--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuieng/EngSrc/CCAMessageHandler.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,841 @@
+/*
+* Copyright (c) 2005 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: Handler class for incoming and outgoing messages
+*
+*/
+
+
+#include "CCAMessageHandler.h"
+#include "MCAChatInterface.h"
+#include "MCAMessagesWriteInterface.h"
+#include "MCAMessageUtils.h"
+#include "MCAImpsImClient.h"
+#include "MCASettings.h"
+#include "MCAMessageErrorObserver.h"
+#include "MCAImpsFactory.h"
+#include "PublicEngineDefinitions.h"
+#include "impsbuilddefinitions.h"
+#include "mcabuffermemoryhandler.h"
+#include "camessageutil.h"
+
+#include <apmstd.h> // KMaxDataTypeLength
+#include <utf.h> // CnvUtfConverter
+
+#include "ChatDebugPrint.h"
+
+#include "ImpsCSPAllErrors.h"
+
+// "test character identity and accents, ignore case"
+const TInt KCollationLevel = 1;
+const TInt KMemorySafeValue = 1024; // One kbyte for safe memory allocation.
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::CCAMessageHandler
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+CCAMessageHandler::CCAMessageHandler( MCAChatInterface& aChatInterface,
+ MCAMessageUtils& aMessageUtils,
+ MCAImpsFactory* aIMPSFactory )
+ : iMessageUtils( aMessageUtils ),
+ iChatInterface( aChatInterface ),
+ iImpsFactory( aIMPSFactory )
+ {
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::~CCAMessageHandler
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+CCAMessageHandler::~CCAMessageHandler()
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::~CCAMessageHandler" );
+ delete iIdle;
+ if ( iSendBuffer )
+ {
+ iSendBuffer->SetObserver( NULL );
+ }
+ iErrorObservers.Close();
+ iHoldingMessages.Close();
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::~CCAMessageHandler" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::NewL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+CCAMessageHandler* CCAMessageHandler::NewL(
+ MCAChatInterface& aChatInterface,
+ MCAMessageUtils& aMessageUtils,
+ MCAImpsFactory* aIMPSFactory )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewL" );
+ CCAMessageHandler* self = CCAMessageHandler::NewLC(
+ aChatInterface,
+ aMessageUtils,
+ aIMPSFactory );
+ CleanupStack::Pop( self );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewL" );
+ return self;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::NewLC
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+CCAMessageHandler* CCAMessageHandler::NewLC(
+ MCAChatInterface& aChatInterface,
+ MCAMessageUtils& aMessageUtils,
+ MCAImpsFactory* aIMPSFactory )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewLC" );
+ CCAMessageHandler* self = new ( ELeave ) CCAMessageHandler(
+ aChatInterface,
+ aMessageUtils,
+ aIMPSFactory );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewLC" );
+ return self;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::ConstructL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::ConstructL()
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::ConstructL" );
+
+ iImpsImClient = iImpsFactory->CreateImClientL();
+
+ iSendBuffer = &iChatInterface.MessageReadInterfaceL( KNullDesC, KNullDesC );
+ iSendBuffer->SetObserver( this );
+ iIdle = CIdle::NewL( CActive::EPriorityIdle );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::ConstructL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleNewTextMessageL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleNewTextMessageL( TInt aOpId,
+ const TDesC& /*aMessageId*/,
+ const TDesC& aSender,
+ const TDesC& aGroupId,
+ const MDesCArray& aRecipients,
+ const MDesCArray& aScreenNames,
+ const TDesC& aText,
+ TImpsCspIdentifier& aCspId )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewTextMessageL" );
+
+ // Don't use memory handling if this is local echo message
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL(
+ aCspId.Sap(),
+ aCspId.UserId(),
+ ( aGroupId == KNullDesC ? aSender : aGroupId ) );
+
+ if ( !( aGroupId != KNullDesC &&
+ iLocalEchoInGroup &&
+ messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) )
+ {
+ if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aText.Size() ) )
+ {
+ NotifyMessageError( KErrNoMemory, NULL );
+ User::Leave( KErrNoMemory );
+ }
+ }
+
+ HBufC* sap = aCspId.Sap().AllocLC();
+ HBufC* userId = aCspId.UserId().AllocLC();
+
+ MCAMessageCreator::SMessageData data =
+ {
+ KMessageDataVersion,
+ aOpId,
+ *sap,
+ *userId,
+ aSender,
+ ( aGroupId == KNullDesC ? aSender : aGroupId ),
+ &aRecipients,
+ &aScreenNames,
+ aText,
+ KNullDesC8,
+ KNullDesC8,
+ MCAMessage::EMessageReceived
+ };
+ HandleNewMessageL( data );
+
+ CleanupStack::PopAndDestroy( 2, sap );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewTextMessageL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleNewContentMessageL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleNewContentMessageL(
+ TInt aOpId,
+ const TDesC& /*aMessageId*/,
+ const TDesC& aSender,
+ const TDesC& aGroupId,
+ const MDesCArray& aRecipients,
+ const MDesCArray& aScreenNames,
+ const TDesC& aContentType,
+ const TDesC8& aContent,
+ TImpsCspIdentifier& aCspId )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewContentMessageL" );
+
+ // Don't use memory handling if this is local echo message
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL(
+ aCspId.Sap(),
+ aCspId.UserId(),
+ ( aGroupId == KNullDesC ? aSender : aGroupId ) );
+
+ if ( !( aGroupId != KNullDesC &&
+ iLocalEchoInGroup &&
+ messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) )
+ {
+ if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aContent.Size() ) )
+ {
+ NotifyMessageError( KErrNoMemory, NULL );
+ User::Leave( KErrNoMemory );
+ }
+ }
+
+ HBufC* sap = aCspId.Sap().AllocLC();
+ HBufC* userId = aCspId.UserId().AllocLC();
+
+ TBuf8< KMaxDataTypeLength > mimeType;
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( mimeType, aContentType );
+
+ MCAMessageCreator::SMessageData data =
+ {
+ KMessageDataVersion,
+ aOpId,
+ *sap,
+ *userId,
+ aSender,
+ ( aGroupId == KNullDesC ? aSender : aGroupId ),
+ &aRecipients,
+ &aScreenNames,
+ KNullDesC,
+ mimeType,
+ aContent,
+ MCAMessage::EMessageReceived
+ };
+ HandleNewMessageL( data );
+
+ CleanupStack::PopAndDestroy( 2, sap );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewContentMessageL" );
+ }
+
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleNewMessageL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleNewMessageL(
+ MCAMessageCreator::SMessageData& aData )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewMessageL" );
+ if ( aData.iTargetId == KNullDesC )
+ {
+ // Invalid message.
+ User::Leave( KErrArgument );
+ }
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL( aData.iSapId,
+ aData.iUserId,
+ aData.iTargetId );
+
+ MCAMessage* message = iMessageUtils.MessageCreator().CreateMessageL( aData );
+
+ if ( iLocalEchoInGroup
+ && ( message->MessageType() == MCAMessage::EMessageGroup )
+ && ( messageContainer.OwnScreenName().CompareC( aData.iSender,
+ KCollationLevel, NULL ) == 0 ) )
+ {
+ // Do not show message because it is already shown with local echo.
+ CHAT_DP( D_CHAT_LIT( "Group message not shown, because local echo." ) );
+ delete message;
+ return;
+ }
+
+ // set iTargetId to ScreenName if current received message type is EMessageWhisper
+ if ( message->MessageType() == MCAMessage::EMessageWhisper || message->MessageType() == MCAMessage::EMessageGroup )
+ {
+ TInt count = aData.iScreenNames->MdcaCount();
+ MCAMessageCreator::SMessageData data2 =
+ {
+ aData.iVersion,
+ aData.iOpId,
+ aData.iSapId,
+ aData.iUserId,
+ aData.iSender,
+ ( count > 0 ) ? aData.iScreenNames->MdcaPoint( 0 ) : aData.iTargetId,
+ aData.iRecipients,
+ aData.iScreenNames,
+ aData.iText,
+ aData.iContentType,
+ aData.iContentData,
+ aData.iMessager
+ };
+
+ MCAMessage* message2 = iMessageUtils.MessageCreator().CreateMessageL( data2 );
+
+ delete message;
+ message = message2;
+ }
+
+ // Message can get different process state during creation. For example
+ // EContentNotSupported
+ if ( message->ContentProcessState() == MCAMessage::EContentNotProcessed )
+ {
+ message->SetProcessState( MCAMessage::EContentReady );
+ }
+
+ // Add message
+ CAMessageUtil::AppendMessageWithDateStampL(
+ *message,
+ messageContainer,
+ iMessageUtils.MessageCreator() );
+
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewMessageL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleSendCompleteL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleSendCompleteL( TInt aOpId,
+ TBool aDeliveryReportOrdered,
+ TImpsCspIdentifier& /*aCspId*/ )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleSendCompleteL" );
+
+ CHAT_DP( D_CHAT_LIT( "Operationcode %d. Delivery ordered %d" ),
+ aOpId, aDeliveryReportOrdered );
+ HandleMessageSentL( KErrNone, aOpId, ETrue );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleSendCompleteL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleDeliveryReportL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleDeliveryReportL( const TDesC& /*aMessageId*/,
+ TInt /*aResult*/,
+ const TDesC* /*aDescription*/,
+ TImpsCspIdentifier& /*aCspId*/ )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleDeliveryReportL" );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleDeliveryReportL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleMessageEvent
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleMessageEvent( TMessageEventType aEvent,
+ TInt /*aIndex*/ )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageEvent" );
+ switch ( aEvent )
+ {
+ case ENewMessage:
+ {
+ if ( !iIdle->IsActive() )
+ {
+ iIdle->Start( TCallBack( SendMessage, this ) );
+ }
+ break;
+ }
+ case EChatDeleted:
+ {
+ // send buffer was deleted
+ iSendBuffer = NULL;
+ break;
+ }
+ default:
+ break;
+ }
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageEvent" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::SendMessage
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+TInt CCAMessageHandler::SendMessage( TAny *aInstance )
+ {
+ CCAMessageHandler* handler = static_cast< CCAMessageHandler* >( aInstance );
+ handler->iSendLaunchLock = ETrue;
+ TInt retVal = handler->DoSendMessage();
+ handler->iSendLaunchLock = EFalse;
+ return retVal;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::DoSendMessage
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+TInt CCAMessageHandler::DoSendMessage()
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::DoSendMessage" );
+
+ if ( !iSendBuffer )
+ {
+ // send buffer was deleted, we're shutting down
+ CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) );
+ return EFalse;
+ }
+
+ // 1. Check if there is message in holding.
+ MCAMessage* holdingMessage = NextHoldingMessage();
+ if ( !holdingMessage && !iSendBuffer->UnreadCount() )
+ {
+ CHAT_DP( D_CHAT_LIT( "There is not ready messages for sending." ) );
+ return EFalse;
+ }
+
+ // 2. Choose new message from sendbuffer or use holding message if exists.
+ MCAMessage& message = ( !holdingMessage ? iSendBuffer->ReadNextUnread()
+ : *holdingMessage );
+
+ // 3. Add message to holding if needed
+ TBool appendedToHolding( EFalse );
+ TRAPD( error, appendedToHolding = AppendedToHoldingL( message ) );
+#ifndef RD_SEND_NOT_SUPPORTED_CONTENT
+ if ( error ) // Corrupted message, inform upstairs
+ {
+ NotifyMessageError(
+ error == KErrOverflow ? error : ECorruptedContent, &message );
+ // Remove sent message from send buffer, because answer will not come.
+ TInt index = iSendBuffer->FindIndex( message );
+ if ( index >= 0 )
+ {
+ iSendBuffer->DeleteMessage( index );
+ }
+ return ETrue;
+ }
+#endif //RD_SEND_NOT_SUPPORTED
+ if ( appendedToHolding )
+ {
+ return ETrue;
+ }
+
+ // 4. Send message
+ TInt opCode( 0 );
+ TRAP( error, opCode = SendMessageToServerL( message ) );
+ CHAT_DP( D_CHAT_LIT( "Send retval ( %d )" ), error );
+
+ if ( error == KErrServerBusy )
+ {
+ TRAPD( err, iHoldingMessages.AppendL( &message ) );
+ if ( err )
+ {
+ CActiveScheduler::Current()->Error( err );
+ }
+ return ETrue;
+ }
+ // 5. Local echo message
+ TRAPD( error2, LocalEchoMessageL( message ) );
+ if ( error2 != KErrNone )
+ {
+ NotifyMessageError( error2, &message );
+ }
+
+ // 6. Handle error
+ if ( error != KErrNone )
+ {
+ TRAP( error2, HandleMessageSentFailedL( message, error ) );
+ if ( error2 )
+ {
+ NotifyMessageError( error2, &message );
+ }
+ // Remove sent message from send buffer, because answer will not come.
+ TInt index = iSendBuffer->FindIndex( message );
+ if ( index >= 0 )
+ {
+ iSendBuffer->DeleteMessage( index );
+ }
+ }
+ else // Send succesfull. -> Local echo
+ {
+ CHAT_DP( D_CHAT_LIT( "Address: %s, UserId: %s, Recipient %s" ),
+ &message.ServerAddress(),
+ &message.UserId(),
+ &message.Recipient() );
+ message.SetOperationCode( opCode );
+ }
+
+ // 7. Check need of
+ TInt unreadCount = iSendBuffer->UnreadCount();
+ TInt holdingMessages( iHoldingMessages.Count() );
+ CHAT_DP( D_CHAT_LIT( "Still %d messages to go. Send buffer has %d messages. \
+ Holding %d messages" ),
+ unreadCount, iSendBuffer->MessageCount(), holdingMessages );
+
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::DoSendMessage" );
+ return Max( unreadCount, holdingMessages );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleMessageSentL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleMessageSentL( TInt aStatus, TInt aOperationCode,
+ TBool aSuccess )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentL" );
+ CHAT_DP( D_CHAT_LIT( "OpCode = %d, Success = %d" ), aOperationCode, aSuccess );
+
+ if ( !iSendBuffer )
+ {
+ // send buffer was deleted, we're shutting down
+ CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) );
+ return;
+ }
+
+ TInt index = User::LeaveIfError( iSendBuffer->FindIndex( aOperationCode ) );
+
+ if ( !aSuccess )
+ {
+ MCAMessage& message = iSendBuffer->Message( index );
+
+ message.SetContainerInfo( NULL );
+
+ MCAMessage* failedMessage =
+ iMessageUtils.MessageCreator().CreateFailedMessageL( &message );
+ CleanupDeletePushL( failedMessage );
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL( message.ServerAddress(),
+ message.UserId(),
+ message.Recipient() );
+ CleanupStack::Pop( failedMessage );
+ messageContainer.AppendL( failedMessage );
+ NotifyMessageError( aStatus, &message );
+ }
+ iSendBuffer->DeleteMessage( index );
+ CHAT_DP( D_CHAT_LIT( "Send buffer has %d messages." ),
+ iSendBuffer->MessageCount() );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::SetLocalEchoInGroup
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::SetLocalEchoInGroup( TBool aLocalEchoInGroup )
+ {
+ iLocalEchoInGroup = aLocalEchoInGroup;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::NotifyMessageError
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::NotifyMessageError( TInt aStatus, MCAMessage* aMessage )
+ {
+ TInt count( iErrorObservers.Count() );
+ for ( TInt a( 0 ); a < count; ++a )
+ {
+ iErrorObservers[ a ]->HandleMessageError( aStatus, aMessage );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::RegisterChatObserver
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::RegisterObserver( MCAMessageErrorObserver* aObserver )
+ {
+ TInt index = iErrorObservers.Find( aObserver );
+ if ( index == KErrNotFound )
+ {
+ iErrorObservers.Append( aObserver );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::RegisterChatObserver
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::UnregisterObserver( MCAMessageErrorObserver* aObserver )
+ {
+ TInt index = iErrorObservers.Find( aObserver );
+ if ( index >= 0 )
+ {
+ iErrorObservers.Remove( index );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleProcessingComplete
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleProcessingComplete(
+ MCAContentProcessor& /*aProcessor*/,
+ MCAMessage& /*aMessage*/,
+ TInt aStatus )
+ {
+ if ( !iIdle->IsActive() && aStatus == KErrNone && !iSendLaunchLock )
+ {
+ iIdle->Start( TCallBack( SendMessage, this ) );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::NextHoldingMessage
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+MCAMessage* CCAMessageHandler::NextHoldingMessage()
+ {
+ TInt holdingMessages = iHoldingMessages.Count();
+ MCAMessage* message = NULL;
+ TInt index( 0 );
+ // Check if holding messages hold one ready message
+ for ( ; index < holdingMessages && !message; ++index )
+ {
+ MCAMessage* msg = iHoldingMessages[ index ];
+ if ( ( msg->ContentProcessState() >= MCAMessage::EContentReady ) ||
+ ( msg->ContentType() == MCAMessage::EContentText ) )
+ {
+ CHAT_DP( D_CHAT_LIT( "Ready holding message found. Index( %d )" ),
+ index );
+ message = msg;
+ iHoldingMessages.Remove( index );
+ }
+ }
+ return message;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::NextHoldingMessage
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+TBool CCAMessageHandler::AppendedToHoldingL( MCAMessage& aMessage )
+ {
+ switch ( aMessage.ContentType() )
+ {
+ case MCAMessage::EContentPicture: // add scaler
+ {
+ if ( aMessage.ContentProcessState() < MCAMessage::EContentReady )
+ {
+ CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \
+ sending. Put to holding." ) );
+ TInt added = User::LeaveIfError( aMessage.AddContentProcessor(
+ iMessageUtils.ImageScaler(), this ) );
+ if ( added )
+ {
+ iHoldingMessages.AppendL( &aMessage );
+ return ETrue;
+ }
+ }
+ break;
+ }
+ default: // Flowthrough other types
+ {
+#ifdef RD_SEND_NOT_SUPPORTED_CONTENT
+ if ( aMessage.ContentProcessState() < MCAMessage::EContentReady )
+ {
+ CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \
+ sending. Put to holding." ) );
+ TInt added = User::LeaveIfError( aMessage.AddContentProcessor(
+ iMessageUtils.ImageScaler(), this ) );
+ if ( added )
+ {
+ iHoldingMessages.AppendL( &aMessage );
+ return ETrue;
+ }
+ }
+#endif //RD_SEND_NOT_SUPPORTED_CONTENT
+ break;
+ }
+ }
+ return EFalse;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::SendMessageToServerL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+TInt CCAMessageHandler::SendMessageToServerL( MCAMessage& aMessage )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::SendMessageToServerL" );
+
+ TInt opCode( 0 );
+ TBuf< KMaxDataTypeLength > mimeType;
+ CnvUtfConverter::ConvertToUnicodeFromUtf8( mimeType, aMessage.MimeType() );
+
+ // granularity of 1 because only one item appended to array
+ CDesCArrayFlat* tempArray = NULL;
+ const MDesCArray* recipients = NULL;
+
+ const TDesC* sender = NULL;
+ const TDesC* groupId = NULL;
+
+ if ( aMessage.ScreenNames() )
+ {
+ groupId = &aMessage.Recipient();
+ if ( aMessage.ScreenNames()->MdcaCount() > 0 )
+ {
+ recipients = aMessage.ScreenNames();
+ }
+ }
+ else
+ {
+ tempArray = new ( ELeave ) CDesCArrayFlat( 1 );
+ CleanupStack::PushL( tempArray );
+ tempArray->AppendL( aMessage.Recipient() );
+ }
+
+ if ( aMessage.ContentType() == MCAMessage::EContentText )
+ {
+ CHAT_DP( D_CHAT_LIT( "Send text message" ) );
+ opCode = iImpsImClient->SendTextMessageL(
+ sender,
+ tempArray,
+ groupId,
+ recipients,
+ aMessage.Text(),
+ EFalse );
+ }
+ else
+ {
+ CHAT_DP( D_CHAT_LIT( "Send content message" ) );
+ TInt size( aMessage.ContentData().Size() );
+ TInt maxSize( iImpsImClient->MaxTransactionContentLengthL() );
+ if ( size > maxSize )
+ {
+ // content too big => can't send
+ CHAT_DP( D_CHAT_LIT( "content too big: %d/%d" ), size, maxSize );
+ User::Leave( KErrOverflow );
+ }
+
+ opCode = iImpsImClient->SendContentMessageL(
+ sender,
+ tempArray,
+ groupId,
+ recipients,
+ mimeType,
+ aMessage.ContentData(),
+ EFalse );
+ }
+
+ if ( tempArray )
+ {
+ CleanupStack::PopAndDestroy( tempArray );
+ }
+
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::SendMessageToServerL" );
+ return opCode;
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::HandleMessageSentFailedL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::HandleMessageSentFailedL( MCAMessage& aMessage,
+ TInt aError )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentFailedL" );
+ MCAMessage* failMessage =
+ iMessageUtils.MessageCreator().CreateFailedMessageL( &aMessage );
+ CleanupDeletePushL( failMessage );
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(),
+ aMessage.UserId(),
+ aMessage.Recipient() );
+ CleanupStack::Pop( failMessage );
+
+ // Notify observers for error.
+ NotifyMessageError( aError, &aMessage );
+ messageContainer.AppendL( failMessage );
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentFailedL" );
+ }
+
+//-----------------------------------------------------------------------------
+// CCAMessageHandler::LocalEchoMessageL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAMessageHandler::LocalEchoMessageL( MCAMessage& aMessage )
+ {
+ CHAT_DP_FUNC_ENTER( "CCAMessageHandler::LocalEchoMessageL" );
+
+ if ( aMessage.MessageType() == MCAMessage::EMessageGroup
+ && !iLocalEchoInGroup )
+ {
+ // Local echo is not allowed in groups.
+ CHAT_DP( D_CHAT_LIT( " Message not shown because local echo is not \
+ allowed." ) );
+ return;
+ }
+
+ MCAMessagesWriteInterface& messageContainer =
+ iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(),
+ aMessage.UserId(),
+ aMessage.Recipient() );
+
+ if ( aMessage.MessageType() == MCAMessage::EMessageWhisper )
+ {
+ // Local echo ones for all recipients
+ const MDesCArray* recipients = aMessage.ScreenNames();
+ TInt count( recipients->MdcaCount() );
+ for ( TInt a( 0 ); a < count; ++a )
+ {
+ MCAMessageCreator::SMessageData data =
+ {
+ KMessageDataVersion,
+ aMessage.OperationCode(),
+ aMessage.ServerAddress(),
+ aMessage.UserId(),
+ aMessage.Sender(),
+ recipients->MdcaPoint( a ),
+ aMessage.Recipients(),
+ recipients,
+ aMessage.Text(),
+ aMessage.MimeType(),
+ aMessage.ContentData(),
+ aMessage.MessagerType()
+ };
+ MCAMessage* message =
+ iMessageUtils.MessageCreator().CreateMessageL( data );
+ message->SetProcessState( MCAMessage::EContentReady );
+
+ // Append message
+ CAMessageUtil::AppendMessageWithDateStampL(
+ *message,
+ messageContainer,
+ iMessageUtils.MessageCreator() );
+ }
+ }
+ else
+ {
+ // Append message
+ CAMessageUtil::AppendMessageWithDateStampL(
+ aMessage,
+ messageContainer,
+ iMessageUtils.MessageCreator(),
+ ETrue );
+ }
+ CHAT_DP_FUNC_DONE( "CCAMessageHandler::LocalEchoMessageL" );
+ }
+
+
+// end of file