messagingfw/sendas/server/src/csendassender.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
child 36 e7635922c074
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // csendassender.cpp
       
    15 //
       
    16 
       
    17 #include "csendassender.h"
       
    18 
       
    19 #include <msvids.h>
       
    20 #include <mtclbase.h>
       
    21 #include <tmsvpackednotifierrequest.h>
       
    22 #include <s32mem.h>
       
    23 
       
    24 #include "msendassenderobserver.h"
       
    25 #include "tsendasserverpanic.h"
       
    26 
       
    27 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    28 #include "msvconsts.h"
       
    29 #endif
       
    30 
       
    31 // Buffer for IPC messages to notifier
       
    32 const TInt KNotifierBufferLength 	= 60;
       
    33 const TInt KNotifierBufferIncrement = 20;
       
    34 
       
    35 CSendAsSender* CSendAsSender::NewL(MSendAsSenderObserver& aObserver)
       
    36 	{
       
    37 	CSendAsSender* self = new (ELeave) CSendAsSender(aObserver);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop(self);
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 CSendAsSender::~CSendAsSender()
       
    45 	{
       
    46 	// do not notify observer during deletion.
       
    47 	iObserver = NULL;
       
    48 	Cancel();
       
    49 
       
    50 	iNotifier.Close();
       
    51 	delete iClientMtm;
       
    52 	delete iOperation;
       
    53 	delete iBuffer;
       
    54 	delete iSelection;
       
    55 	// Close UPS session
       
    56 #if (defined SYMBIAN_USER_PROMPT_SERVICE)	
       
    57     iUpsSubsession.Close();
       
    58 	iUpsSession.Close();
       
    59 #endif	
       
    60 	}
       
    61 
       
    62 CSendAsSender::CSendAsSender(MSendAsSenderObserver& aObserver)
       
    63 : CActive(CActive::EPriorityStandard), iObserver(&aObserver)
       
    64 	{
       
    65 	CActiveScheduler::Add(this);
       
    66 	}
       
    67 	
       
    68 void CSendAsSender::ConstructL()
       
    69 	{
       
    70 	iBuffer = HBufC8::NewL(KNotifierBufferLength);
       
    71 	User::LeaveIfError(iNotifier.Connect());		
       
    72 	iSelection = new (ELeave) CMsvEntrySelection();
       
    73 	}
       
    74 	
       
    75 /**
       
    76 Sets the client MTM to use for move and send operations.
       
    77  
       
    78 @param	aClientMtm
       
    79 The client MTM.
       
    80 */
       
    81 void CSendAsSender::SetClientMtm(CBaseMtm& aClientMtm)
       
    82 	{
       
    83 	__ASSERT_ALWAYS( iState == ESenderIdle, User::Invariant() );
       
    84 	__ASSERT_ALWAYS( iClientMtm == NULL, User::Invariant() );
       
    85 	__ASSERT_ALWAYS( iSelection != NULL, User::Invariant() );
       
    86 	
       
    87 	iClientMtm = &aClientMtm;
       
    88 	}
       
    89 
       
    90 /**
       
    91 Populates the entry selection from the client MTM's entry.
       
    92 */
       
    93 void CSendAsSender::SetEntrySelectionL()
       
    94 	{
       
    95 	iSelection->Reset();
       
    96 	iSelection->AppendL(iClientMtm->Entry().EntryId());
       
    97 	}
       
    98 
       
    99 /**
       
   100 Initiates an confirmed / unconfirmed message send operation.
       
   101 */
       
   102 #if (defined SYMBIAN_USER_PROMPT_SERVICE)
       
   103 void CSendAsSender::SendMessageL(const RMessage2 aMessage, TBool aHasCapability)
       
   104 	{
       
   105 	__ASSERT_ALWAYS( iState == ESenderIdle, User::Invariant() );
       
   106 	__ASSERT_ALWAYS( iClientMtm != NULL, User::Invariant() );
       
   107 	
       
   108 	iState = ESenderAuthoriseSend;
       
   109 	// Serialise the recipient list
       
   110 	const CMsvRecipientList& rcptList = iClientMtm->AddresseeList();
       
   111 	const MDesC16Array& recipient = rcptList.RecipientList();
       
   112 	
       
   113 	TInt rcptCount = recipient.MdcaCount();
       
   114 	TInt size = 0;
       
   115 	for(TInt i=0;i<rcptCount; ++i)
       
   116 		{
       
   117 		size += recipient.MdcaPoint(i).Length();
       
   118 		}		
       
   119 	
       
   120  	_LIT16(KComma, ",");
       
   121  		
       
   122  	RBuf16 buffer;
       
   123  	buffer.Create(size+ rcptCount);
       
   124  	CleanupClosePushL(buffer);
       
   125  	if(rcptCount > 0)
       
   126  		{
       
   127  		buffer.Append(recipient.MdcaPoint(0));	
       
   128  		}
       
   129  		
       
   130  	for(TInt i=1;i<rcptCount; ++i)
       
   131  		{
       
   132  		buffer.Append(KComma);
       
   133  		buffer.Append(recipient.MdcaPoint(i));
       
   134  		}
       
   135    	
       
   136    	RThread clientThread;
       
   137    	aMessage.Client(clientThread);
       
   138    	
       
   139    	// Connect to UPS service.....
       
   140    	User::LeaveIfError(iUpsSession.Connect());
       
   141  	
       
   142  	User::LeaveIfError(iUpsSubsession.Initialise(iUpsSession, clientThread));
       
   143    	
       
   144    	iDecision = EUpsDecNo;
       
   145  	iUpsSubsession.Authorise(aHasCapability, KUidSendAs2Service, buffer, iDecision, iStatus);
       
   146    	SetActive();
       
   147  	CleanupStack::PopAndDestroy(&buffer);
       
   148 	}
       
   149 #endif	
       
   150 
       
   151 /**
       
   152 Initiates an unconfirmed message send operation.
       
   153 */
       
   154 void CSendAsSender::SendMessage()
       
   155 	{
       
   156 	__ASSERT_ALWAYS( iState == ESenderIdle, User::Invariant() );
       
   157 	__ASSERT_ALWAYS( iClientMtm != NULL, User::Invariant() );
       
   158 	
       
   159 	// update state and auto-complete - send process started by RunL()
       
   160 	iState = ESenderStartingUnconfirmedSend;
       
   161 	TRequestStatus* status=&iStatus;
       
   162 	User::RequestComplete(status, KErrNone);
       
   163 	SetActive();
       
   164 	}
       
   165 	
       
   166 /**
       
   167 Initiates a confirmed message send operation.
       
   168  
       
   169 @param	aSecurityInfo
       
   170 The security info associated with the message.
       
   171 
       
   172 @param  aNotifierUid
       
   173 The UID of the notifier plugin.
       
   174 */
       
   175 void CSendAsSender::SendMessage(const TSecurityInfo& aSecurityInfo, const TUid& aNotifierUid)
       
   176 	{
       
   177 	__ASSERT_ALWAYS( iState == ESenderIdle, User::Invariant() );
       
   178 	__ASSERT_ALWAYS( iClientMtm != NULL, User::Invariant() );
       
   179 	
       
   180 	// confirmed send - use notifier to prompt the user for confirmation.
       
   181 	iSecurityInfo = aSecurityInfo;
       
   182 	iNotifierUid  = aNotifierUid;
       
   183 
       
   184 	// update state and auto-complete
       
   185 	iState = ESenderStartingConfirmedSend;
       
   186 	TRequestStatus* status=&iStatus;
       
   187 	User::RequestComplete(status, KErrNone);
       
   188 	SetActive();
       
   189 	}
       
   190 	
       
   191 /**
       
   192 Provides progress information for the send operation.
       
   193  
       
   194 @param	aProgress
       
   195 The operation progerss object.
       
   196 */
       
   197 void CSendAsSender::ProgressL(TMsvSendOperationProgress& aProgress)
       
   198 	{
       
   199 	switch( iState )
       
   200 		{
       
   201 	case ESenderStartingUnconfirmedSend:
       
   202 	case ESenderStartingConfirmedSend:
       
   203 	case ESenderIdle:
       
   204 	case ESenderConfirming:
       
   205 	case ESenderMoving:
       
   206 	case ESenderAuthoriseSend:
       
   207 		{
       
   208 		aProgress().iState = CMsvSendOperation::ESendStateWaitingToSend;
       
   209 		} break;
       
   210 	case ESenderSending:
       
   211 		{
       
   212 		// when sending, operation returns a CMsvSendOperation which returns the
       
   213 		// correct progress.
       
   214 		const TDesC8& opProgress = iOperation->ProgressL();
       
   215 		__ASSERT_ALWAYS(opProgress.Size() == sizeof(CMsvSendOperation::TSendOperationProgress), 
       
   216 						TSendAsServerPanic::Panic(TSendAsServerPanic::ESendAsBadDescriptor));
       
   217 		TMsvSendOperationProgress& progress = (TMsvSendOperationProgress&) opProgress;
       
   218 		aProgress = progress;
       
   219 		} break;
       
   220 	case ESenderDone:
       
   221 		{
       
   222 		FinalProgress(aProgress);
       
   223 		} break;
       
   224 	default:
       
   225 		User::Invariant();
       
   226 		break;
       
   227 		}
       
   228 	}
       
   229 	
       
   230 void CSendAsSender::FinalProgress(TMsvSendOperationProgress& aProgress)
       
   231 	{
       
   232 	__ASSERT_ALWAYS( iState == ESenderDone, User::Invariant() );
       
   233 	
       
   234 	aProgress = iFinalProgress;
       
   235 	}
       
   236 
       
   237 /**
       
   238 Deletes the current operation
       
   239 */
       
   240 void CSendAsSender::DeleteOperation()
       
   241 	{
       
   242 	delete iOperation;
       
   243 	iOperation = NULL;
       
   244 	}
       
   245 
       
   246 /**
       
   247 Invokes an asynchronous move operation.
       
   248 Moves the message from current location (drafts folder) to the outbox.
       
   249 */
       
   250 void CSendAsSender::InvokeMoveOperationL()
       
   251 	{
       
   252 	iEntry = iClientMtm->Entry().Entry();
       
   253 	iClientMtm->Entry().SetEntryL(iEntry.Parent());
       
   254 
       
   255 	DeleteOperation();
       
   256 	iOperation = iClientMtm->Entry().MoveL(iEntry.Id(), KMsvGlobalOutBoxIndexEntryId, iStatus);
       
   257 	SetActive();
       
   258 
       
   259 	iState = ESenderMoving;
       
   260 	}
       
   261 
       
   262 /**
       
   263 Invokes an asychronous send operation.
       
   264 */
       
   265 void CSendAsSender::InvokeSendOperationL()
       
   266 	{
       
   267 	// Buffer required for call to InvokeAsyncFunction, unused.
       
   268 	TBuf8<1> buf;
       
   269 	iClientMtm->Entry().SetEntryL(iEntry.Id());
       
   270 	DeleteOperation();
       
   271 	// Note: This operation must be a CMsvSendOperation as TMsvSendOperationProgress is needed
       
   272 	iOperation = iClientMtm->InvokeAsyncFunctionL(KMTMStandardFunctionsSendMessage, *iSelection, buf, iStatus);
       
   273 	SetActive();
       
   274 	
       
   275 	iState = ESenderSending;	
       
   276 	}
       
   277 
       
   278 /**
       
   279 Invokes an asynchronous notification request.
       
   280 */
       
   281 void CSendAsSender::InvokeConfirmOperationL()
       
   282 	{
       
   283 	// Use plugin notifier to get the send confirmation.
       
   284 	TMsvPackedNotifierRequest packedInfo(iBuffer);
       
   285 	while(packedInfo.Pack(*iSelection, iSecurityInfo) != KErrNone)
       
   286 		{
       
   287 		// increase the size of the buffer and try again
       
   288 		iBuffer->Des().Zero(); // to avoid copying contents
       
   289 		iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KNotifierBufferIncrement);
       
   290 		}
       
   291 
       
   292 	iNotifier.StartNotifierAndGetResponse(iStatus, iNotifierUid, *iBuffer, iNotifierResult);
       
   293 	SetActive();
       
   294 	
       
   295 	iState = ESenderConfirming;
       
   296 	}
       
   297 
       
   298 /**
       
   299 Notifies the observer that the operation has completed.
       
   300 @param  aError 	The error code.
       
   301 */
       
   302 void CSendAsSender::Complete(TInt aError)
       
   303 	{
       
   304 	iState = ESenderDone; // This must be set before notifying observer
       
   305 	if( iObserver != NULL )
       
   306 		{
       
   307 		// notify observer that the send has completed.
       
   308 		iObserver->SenderComplete(aError);
       
   309 		}
       
   310 	}
       
   311 	
       
   312 /**
       
   313 Methods from CActive
       
   314 Handles a request completion event.
       
   315 Implements the CSendAsSender state machine.
       
   316 
       
   317 @see CActive::RunL()
       
   318 */
       
   319 void CSendAsSender::RunL()
       
   320 	{
       
   321 	User::LeaveIfError(iStatus.Int());
       
   322 	
       
   323 	switch( iState )
       
   324 		{
       
   325 	case ESenderStartingConfirmedSend:
       
   326 		{
       
   327 		SetEntrySelectionL();
       
   328 		InvokeConfirmOperationL();
       
   329 		}break;
       
   330 	case ESenderStartingUnconfirmedSend:
       
   331 		{
       
   332 		SetEntrySelectionL();
       
   333 		} // fall through
       
   334 	case ESenderConfirming:
       
   335 		{
       
   336 		InvokeMoveOperationL();			
       
   337 		} break;
       
   338 #if (defined SYMBIAN_USER_PROMPT_SERVICE)		
       
   339 	case ESenderAuthoriseSend:
       
   340 		{
       
   341 		if(iDecision != EUpsDecYes)
       
   342 			{
       
   343 			Complete(KErrPermissionDenied);
       
   344 			}
       
   345 		else
       
   346 			{
       
   347 			SetEntrySelectionL();
       
   348 			InvokeMoveOperationL();	
       
   349 			}	
       
   350 						
       
   351 		}break;
       
   352 #endif		
       
   353 	case ESenderMoving:
       
   354 		{
       
   355 		InvokeSendOperationL();			
       
   356 		} break;
       
   357 	case ESenderSending:
       
   358 		{
       
   359 		TMsvSendOperationProgress& progress = (TMsvSendOperationProgress&)iOperation->FinalProgress();
       
   360 		iFinalProgress = progress;
       
   361 		Complete(KErrNone);
       
   362 		} break;
       
   363 	case ESenderIdle:
       
   364 	case ESenderDone:
       
   365 	default:
       
   366 		User::Invariant();
       
   367 		}
       
   368 	}
       
   369 	
       
   370 /** 
       
   371 Implements cancellation of an outstanding request.
       
   372 @see CActive::DoCancel()
       
   373 */
       
   374 void CSendAsSender::DoCancel()
       
   375 	{
       
   376 	switch( iState )
       
   377 		{
       
   378 		case ESenderConfirming:
       
   379 			{
       
   380 			iNotifier.NotifyCancel();
       
   381 			}break;
       
   382 		case ESenderMoving:
       
   383 		case ESenderSending:
       
   384 			{
       
   385 			__ASSERT_ALWAYS( iOperation != NULL, User::Invariant() );
       
   386 			iOperation->Cancel();
       
   387 			} break;
       
   388 #if (defined SYMBIAN_USER_PROMPT_SERVICE)
       
   389 		case ESenderAuthoriseSend:
       
   390 			{
       
   391 			iUpsSubsession.Close();
       
   392 			}break;
       
   393 #endif
       
   394 		case ESenderStartingConfirmedSend:
       
   395 		case ESenderStartingUnconfirmedSend:	
       
   396 		case ESenderIdle:	
       
   397 		case ESenderDone:
       
   398 		default:
       
   399 			// do nothing...
       
   400 			break;
       
   401 			}
       
   402 	Complete(KErrCancel);
       
   403 	}
       
   404 	
       
   405 /** 
       
   406 Handles leaves from the RunL method.
       
   407 @see CActive::RunL()
       
   408 */
       
   409 TInt CSendAsSender::RunError(TInt aError)
       
   410 	{
       
   411 	Complete(aError);
       
   412 	return KErrNone;
       
   413 	}