|
1 /* |
|
2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Handler class for incoming and outgoing messages |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "CCAMessageHandler.h" |
|
20 #include "MCAChatInterface.h" |
|
21 #include "MCAMessagesWriteInterface.h" |
|
22 #include "MCAMessageUtils.h" |
|
23 #include "MCAImpsImClient.h" |
|
24 #include "MCASettings.h" |
|
25 #include "MCAMessageErrorObserver.h" |
|
26 #include "MCAImpsFactory.h" |
|
27 #include "PublicEngineDefinitions.h" |
|
28 #include "impsbuilddefinitions.h" |
|
29 #include "mcabuffermemoryhandler.h" |
|
30 #include "camessageutil.h" |
|
31 |
|
32 #include <apmstd.h> // KMaxDataTypeLength |
|
33 #include <utf.h> // CnvUtfConverter |
|
34 |
|
35 #include "ChatDebugPrint.h" |
|
36 |
|
37 #include "ImpsCSPAllErrors.h" |
|
38 |
|
39 // "test character identity and accents, ignore case" |
|
40 const TInt KCollationLevel = 1; |
|
41 const TInt KMemorySafeValue = 1024; // One kbyte for safe memory allocation. |
|
42 |
|
43 //----------------------------------------------------------------------------- |
|
44 // CCAMessageHandler::CCAMessageHandler |
|
45 // ( Other items commented in header ) |
|
46 //----------------------------------------------------------------------------- |
|
47 CCAMessageHandler::CCAMessageHandler( MCAChatInterface& aChatInterface, |
|
48 MCAMessageUtils& aMessageUtils, |
|
49 MCAImpsFactory* aIMPSFactory ) |
|
50 : iMessageUtils( aMessageUtils ), |
|
51 iChatInterface( aChatInterface ), |
|
52 iImpsFactory( aIMPSFactory ) |
|
53 { |
|
54 } |
|
55 |
|
56 //----------------------------------------------------------------------------- |
|
57 // CCAMessageHandler::~CCAMessageHandler |
|
58 // ( Other items commented in header ) |
|
59 //----------------------------------------------------------------------------- |
|
60 CCAMessageHandler::~CCAMessageHandler() |
|
61 { |
|
62 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::~CCAMessageHandler" ); |
|
63 delete iIdle; |
|
64 if ( iSendBuffer ) |
|
65 { |
|
66 iSendBuffer->SetObserver( NULL ); |
|
67 } |
|
68 iErrorObservers.Close(); |
|
69 iHoldingMessages.Close(); |
|
70 CHAT_DP_FUNC_DONE( "CCAMessageHandler::~CCAMessageHandler" ); |
|
71 } |
|
72 |
|
73 //----------------------------------------------------------------------------- |
|
74 // CCAMessageHandler::NewL |
|
75 // ( Other items commented in header ) |
|
76 //----------------------------------------------------------------------------- |
|
77 CCAMessageHandler* CCAMessageHandler::NewL( |
|
78 MCAChatInterface& aChatInterface, |
|
79 MCAMessageUtils& aMessageUtils, |
|
80 MCAImpsFactory* aIMPSFactory ) |
|
81 { |
|
82 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewL" ); |
|
83 CCAMessageHandler* self = CCAMessageHandler::NewLC( |
|
84 aChatInterface, |
|
85 aMessageUtils, |
|
86 aIMPSFactory ); |
|
87 CleanupStack::Pop( self ); |
|
88 CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewL" ); |
|
89 return self; |
|
90 } |
|
91 |
|
92 //----------------------------------------------------------------------------- |
|
93 // CCAMessageHandler::NewLC |
|
94 // ( Other items commented in header ) |
|
95 //----------------------------------------------------------------------------- |
|
96 CCAMessageHandler* CCAMessageHandler::NewLC( |
|
97 MCAChatInterface& aChatInterface, |
|
98 MCAMessageUtils& aMessageUtils, |
|
99 MCAImpsFactory* aIMPSFactory ) |
|
100 { |
|
101 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewLC" ); |
|
102 CCAMessageHandler* self = new ( ELeave ) CCAMessageHandler( |
|
103 aChatInterface, |
|
104 aMessageUtils, |
|
105 aIMPSFactory ); |
|
106 CleanupStack::PushL( self ); |
|
107 self->ConstructL(); |
|
108 CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewLC" ); |
|
109 return self; |
|
110 } |
|
111 |
|
112 //----------------------------------------------------------------------------- |
|
113 // CCAMessageHandler::ConstructL |
|
114 // ( Other items commented in header ) |
|
115 //----------------------------------------------------------------------------- |
|
116 void CCAMessageHandler::ConstructL() |
|
117 { |
|
118 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::ConstructL" ); |
|
119 |
|
120 iImpsImClient = iImpsFactory->CreateImClientL(); |
|
121 |
|
122 iSendBuffer = &iChatInterface.MessageReadInterfaceL( KNullDesC, KNullDesC ); |
|
123 iSendBuffer->SetObserver( this ); |
|
124 iIdle = CIdle::NewL( CActive::EPriorityIdle ); |
|
125 CHAT_DP_FUNC_DONE( "CCAMessageHandler::ConstructL" ); |
|
126 } |
|
127 |
|
128 //----------------------------------------------------------------------------- |
|
129 // CCAMessageHandler::HandleNewTextMessageL |
|
130 // ( Other items commented in header ) |
|
131 //----------------------------------------------------------------------------- |
|
132 void CCAMessageHandler::HandleNewTextMessageL( TInt aOpId, |
|
133 const TDesC& /*aMessageId*/, |
|
134 const TDesC& aSender, |
|
135 const TDesC& aGroupId, |
|
136 const MDesCArray& aRecipients, |
|
137 const MDesCArray& aScreenNames, |
|
138 const TDesC& aText, |
|
139 TImpsCspIdentifier& aCspId ) |
|
140 { |
|
141 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewTextMessageL" ); |
|
142 |
|
143 // Don't use memory handling if this is local echo message |
|
144 MCAMessagesWriteInterface& messageContainer = |
|
145 iChatInterface.MessageWriteInterfaceL( |
|
146 aCspId.Sap(), |
|
147 aCspId.UserId(), |
|
148 ( aGroupId == KNullDesC ? aSender : aGroupId ) ); |
|
149 |
|
150 if ( !( aGroupId != KNullDesC && |
|
151 iLocalEchoInGroup && |
|
152 messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) ) |
|
153 { |
|
154 if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aText.Size() ) ) |
|
155 { |
|
156 NotifyMessageError( KErrNoMemory, NULL ); |
|
157 User::Leave( KErrNoMemory ); |
|
158 } |
|
159 } |
|
160 |
|
161 HBufC* sap = aCspId.Sap().AllocLC(); |
|
162 HBufC* userId = aCspId.UserId().AllocLC(); |
|
163 |
|
164 MCAMessageCreator::SMessageData data = |
|
165 { |
|
166 KMessageDataVersion, |
|
167 aOpId, |
|
168 *sap, |
|
169 *userId, |
|
170 aSender, |
|
171 ( aGroupId == KNullDesC ? aSender : aGroupId ), |
|
172 &aRecipients, |
|
173 &aScreenNames, |
|
174 aText, |
|
175 KNullDesC8, |
|
176 KNullDesC8, |
|
177 MCAMessage::EMessageReceived |
|
178 }; |
|
179 HandleNewMessageL( data ); |
|
180 |
|
181 CleanupStack::PopAndDestroy( 2, sap ); |
|
182 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewTextMessageL" ); |
|
183 } |
|
184 |
|
185 //----------------------------------------------------------------------------- |
|
186 // CCAMessageHandler::HandleNewContentMessageL |
|
187 // ( Other items commented in header ) |
|
188 //----------------------------------------------------------------------------- |
|
189 void CCAMessageHandler::HandleNewContentMessageL( |
|
190 TInt aOpId, |
|
191 const TDesC& /*aMessageId*/, |
|
192 const TDesC& aSender, |
|
193 const TDesC& aGroupId, |
|
194 const MDesCArray& aRecipients, |
|
195 const MDesCArray& aScreenNames, |
|
196 const TDesC& aContentType, |
|
197 const TDesC8& aContent, |
|
198 TImpsCspIdentifier& aCspId ) |
|
199 { |
|
200 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewContentMessageL" ); |
|
201 |
|
202 // Don't use memory handling if this is local echo message |
|
203 MCAMessagesWriteInterface& messageContainer = |
|
204 iChatInterface.MessageWriteInterfaceL( |
|
205 aCspId.Sap(), |
|
206 aCspId.UserId(), |
|
207 ( aGroupId == KNullDesC ? aSender : aGroupId ) ); |
|
208 |
|
209 if ( !( aGroupId != KNullDesC && |
|
210 iLocalEchoInGroup && |
|
211 messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) ) |
|
212 { |
|
213 if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aContent.Size() ) ) |
|
214 { |
|
215 NotifyMessageError( KErrNoMemory, NULL ); |
|
216 User::Leave( KErrNoMemory ); |
|
217 } |
|
218 } |
|
219 |
|
220 HBufC* sap = aCspId.Sap().AllocLC(); |
|
221 HBufC* userId = aCspId.UserId().AllocLC(); |
|
222 |
|
223 TBuf8< KMaxDataTypeLength > mimeType; |
|
224 CnvUtfConverter::ConvertFromUnicodeToUtf8( mimeType, aContentType ); |
|
225 |
|
226 MCAMessageCreator::SMessageData data = |
|
227 { |
|
228 KMessageDataVersion, |
|
229 aOpId, |
|
230 *sap, |
|
231 *userId, |
|
232 aSender, |
|
233 ( aGroupId == KNullDesC ? aSender : aGroupId ), |
|
234 &aRecipients, |
|
235 &aScreenNames, |
|
236 KNullDesC, |
|
237 mimeType, |
|
238 aContent, |
|
239 MCAMessage::EMessageReceived |
|
240 }; |
|
241 HandleNewMessageL( data ); |
|
242 |
|
243 CleanupStack::PopAndDestroy( 2, sap ); |
|
244 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewContentMessageL" ); |
|
245 } |
|
246 |
|
247 |
|
248 //----------------------------------------------------------------------------- |
|
249 // CCAMessageHandler::HandleNewMessageL |
|
250 // ( Other items commented in header ) |
|
251 //----------------------------------------------------------------------------- |
|
252 void CCAMessageHandler::HandleNewMessageL( |
|
253 MCAMessageCreator::SMessageData& aData ) |
|
254 { |
|
255 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewMessageL" ); |
|
256 if ( aData.iTargetId == KNullDesC ) |
|
257 { |
|
258 // Invalid message. |
|
259 User::Leave( KErrArgument ); |
|
260 } |
|
261 MCAMessagesWriteInterface& messageContainer = |
|
262 iChatInterface.MessageWriteInterfaceL( aData.iSapId, |
|
263 aData.iUserId, |
|
264 aData.iTargetId ); |
|
265 |
|
266 MCAMessage* message = iMessageUtils.MessageCreator().CreateMessageL( aData ); |
|
267 |
|
268 if ( iLocalEchoInGroup |
|
269 && ( message->MessageType() == MCAMessage::EMessageGroup ) |
|
270 && ( messageContainer.OwnScreenName().CompareC( aData.iSender, |
|
271 KCollationLevel, NULL ) == 0 ) ) |
|
272 { |
|
273 // Do not show message because it is already shown with local echo. |
|
274 CHAT_DP( D_CHAT_LIT( "Group message not shown, because local echo." ) ); |
|
275 delete message; |
|
276 return; |
|
277 } |
|
278 |
|
279 // set iTargetId to ScreenName if current received message type is EMessageWhisper |
|
280 if ( message->MessageType() == MCAMessage::EMessageWhisper || message->MessageType() == MCAMessage::EMessageGroup ) |
|
281 { |
|
282 TInt count = aData.iScreenNames->MdcaCount(); |
|
283 MCAMessageCreator::SMessageData data2 = |
|
284 { |
|
285 aData.iVersion, |
|
286 aData.iOpId, |
|
287 aData.iSapId, |
|
288 aData.iUserId, |
|
289 aData.iSender, |
|
290 ( count > 0 ) ? aData.iScreenNames->MdcaPoint( 0 ) : aData.iTargetId, |
|
291 aData.iRecipients, |
|
292 aData.iScreenNames, |
|
293 aData.iText, |
|
294 aData.iContentType, |
|
295 aData.iContentData, |
|
296 aData.iMessager |
|
297 }; |
|
298 |
|
299 MCAMessage* message2 = iMessageUtils.MessageCreator().CreateMessageL( data2 ); |
|
300 |
|
301 delete message; |
|
302 message = message2; |
|
303 } |
|
304 |
|
305 // Message can get different process state during creation. For example |
|
306 // EContentNotSupported |
|
307 if ( message->ContentProcessState() == MCAMessage::EContentNotProcessed ) |
|
308 { |
|
309 message->SetProcessState( MCAMessage::EContentReady ); |
|
310 } |
|
311 |
|
312 // Add message |
|
313 CAMessageUtil::AppendMessageWithDateStampL( |
|
314 *message, |
|
315 messageContainer, |
|
316 iMessageUtils.MessageCreator() ); |
|
317 |
|
318 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewMessageL" ); |
|
319 } |
|
320 |
|
321 //----------------------------------------------------------------------------- |
|
322 // CCAMessageHandler::HandleSendCompleteL |
|
323 // ( Other items commented in header ) |
|
324 //----------------------------------------------------------------------------- |
|
325 void CCAMessageHandler::HandleSendCompleteL( TInt aOpId, |
|
326 TBool aDeliveryReportOrdered, |
|
327 TImpsCspIdentifier& /*aCspId*/ ) |
|
328 { |
|
329 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleSendCompleteL" ); |
|
330 |
|
331 CHAT_DP( D_CHAT_LIT( "Operationcode %d. Delivery ordered %d" ), |
|
332 aOpId, aDeliveryReportOrdered ); |
|
333 HandleMessageSentL( KErrNone, aOpId, ETrue ); |
|
334 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleSendCompleteL" ); |
|
335 } |
|
336 |
|
337 //----------------------------------------------------------------------------- |
|
338 // CCAMessageHandler::HandleDeliveryReportL |
|
339 // ( Other items commented in header ) |
|
340 //----------------------------------------------------------------------------- |
|
341 void CCAMessageHandler::HandleDeliveryReportL( const TDesC& /*aMessageId*/, |
|
342 TInt /*aResult*/, |
|
343 const TDesC* /*aDescription*/, |
|
344 TImpsCspIdentifier& /*aCspId*/ ) |
|
345 { |
|
346 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleDeliveryReportL" ); |
|
347 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleDeliveryReportL" ); |
|
348 } |
|
349 |
|
350 //----------------------------------------------------------------------------- |
|
351 // CCAMessageHandler::HandleMessageEvent |
|
352 // ( Other items commented in header ) |
|
353 //----------------------------------------------------------------------------- |
|
354 void CCAMessageHandler::HandleMessageEvent( TMessageEventType aEvent, |
|
355 TInt /*aIndex*/ ) |
|
356 { |
|
357 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageEvent" ); |
|
358 switch ( aEvent ) |
|
359 { |
|
360 case ENewMessage: |
|
361 { |
|
362 if ( !iIdle->IsActive() ) |
|
363 { |
|
364 iIdle->Start( TCallBack( SendMessage, this ) ); |
|
365 } |
|
366 break; |
|
367 } |
|
368 case EChatDeleted: |
|
369 { |
|
370 // send buffer was deleted |
|
371 iSendBuffer = NULL; |
|
372 break; |
|
373 } |
|
374 default: |
|
375 break; |
|
376 } |
|
377 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageEvent" ); |
|
378 } |
|
379 |
|
380 //----------------------------------------------------------------------------- |
|
381 // CCAMessageHandler::SendMessage |
|
382 // ( Other items commented in header ) |
|
383 //----------------------------------------------------------------------------- |
|
384 TInt CCAMessageHandler::SendMessage( TAny *aInstance ) |
|
385 { |
|
386 CCAMessageHandler* handler = static_cast< CCAMessageHandler* >( aInstance ); |
|
387 handler->iSendLaunchLock = ETrue; |
|
388 TInt retVal = handler->DoSendMessage(); |
|
389 handler->iSendLaunchLock = EFalse; |
|
390 return retVal; |
|
391 } |
|
392 |
|
393 //----------------------------------------------------------------------------- |
|
394 // CCAMessageHandler::DoSendMessage |
|
395 // ( Other items commented in header ) |
|
396 //----------------------------------------------------------------------------- |
|
397 TInt CCAMessageHandler::DoSendMessage() |
|
398 { |
|
399 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::DoSendMessage" ); |
|
400 |
|
401 if ( !iSendBuffer ) |
|
402 { |
|
403 // send buffer was deleted, we're shutting down |
|
404 CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) ); |
|
405 return EFalse; |
|
406 } |
|
407 |
|
408 // 1. Check if there is message in holding. |
|
409 MCAMessage* holdingMessage = NextHoldingMessage(); |
|
410 if ( !holdingMessage && !iSendBuffer->UnreadCount() ) |
|
411 { |
|
412 CHAT_DP( D_CHAT_LIT( "There is not ready messages for sending." ) ); |
|
413 return EFalse; |
|
414 } |
|
415 |
|
416 // 2. Choose new message from sendbuffer or use holding message if exists. |
|
417 MCAMessage& message = ( !holdingMessage ? iSendBuffer->ReadNextUnread() |
|
418 : *holdingMessage ); |
|
419 |
|
420 // 3. Add message to holding if needed |
|
421 TBool appendedToHolding( EFalse ); |
|
422 TRAPD( error, appendedToHolding = AppendedToHoldingL( message ) ); |
|
423 #ifndef RD_SEND_NOT_SUPPORTED_CONTENT |
|
424 if ( error ) // Corrupted message, inform upstairs |
|
425 { |
|
426 NotifyMessageError( |
|
427 error == KErrOverflow ? error : ECorruptedContent, &message ); |
|
428 // Remove sent message from send buffer, because answer will not come. |
|
429 TInt index = iSendBuffer->FindIndex( message ); |
|
430 if ( index >= 0 ) |
|
431 { |
|
432 iSendBuffer->DeleteMessage( index ); |
|
433 } |
|
434 return ETrue; |
|
435 } |
|
436 #endif //RD_SEND_NOT_SUPPORTED |
|
437 if ( appendedToHolding ) |
|
438 { |
|
439 return ETrue; |
|
440 } |
|
441 |
|
442 // 4. Send message |
|
443 TInt opCode( 0 ); |
|
444 TRAP( error, opCode = SendMessageToServerL( message ) ); |
|
445 CHAT_DP( D_CHAT_LIT( "Send retval ( %d )" ), error ); |
|
446 |
|
447 if ( error == KErrServerBusy ) |
|
448 { |
|
449 TRAPD( err, iHoldingMessages.AppendL( &message ) ); |
|
450 if ( err ) |
|
451 { |
|
452 CActiveScheduler::Current()->Error( err ); |
|
453 } |
|
454 return ETrue; |
|
455 } |
|
456 // 5. Local echo message |
|
457 TRAPD( error2, LocalEchoMessageL( message ) ); |
|
458 if ( error2 != KErrNone ) |
|
459 { |
|
460 NotifyMessageError( error2, &message ); |
|
461 } |
|
462 |
|
463 // 6. Handle error |
|
464 if ( error != KErrNone ) |
|
465 { |
|
466 TRAP( error2, HandleMessageSentFailedL( message, error ) ); |
|
467 if ( error2 ) |
|
468 { |
|
469 NotifyMessageError( error2, &message ); |
|
470 } |
|
471 // Remove sent message from send buffer, because answer will not come. |
|
472 TInt index = iSendBuffer->FindIndex( message ); |
|
473 if ( index >= 0 ) |
|
474 { |
|
475 iSendBuffer->DeleteMessage( index ); |
|
476 } |
|
477 } |
|
478 else // Send succesfull. -> Local echo |
|
479 { |
|
480 CHAT_DP( D_CHAT_LIT( "Address: %s, UserId: %s, Recipient %s" ), |
|
481 &message.ServerAddress(), |
|
482 &message.UserId(), |
|
483 &message.Recipient() ); |
|
484 message.SetOperationCode( opCode ); |
|
485 } |
|
486 |
|
487 // 7. Check need of |
|
488 TInt unreadCount = iSendBuffer->UnreadCount(); |
|
489 TInt holdingMessages( iHoldingMessages.Count() ); |
|
490 CHAT_DP( D_CHAT_LIT( "Still %d messages to go. Send buffer has %d messages. \ |
|
491 Holding %d messages" ), |
|
492 unreadCount, iSendBuffer->MessageCount(), holdingMessages ); |
|
493 |
|
494 CHAT_DP_FUNC_DONE( "CCAMessageHandler::DoSendMessage" ); |
|
495 return Max( unreadCount, holdingMessages ); |
|
496 } |
|
497 |
|
498 //----------------------------------------------------------------------------- |
|
499 // CCAMessageHandler::HandleMessageSentL |
|
500 // ( Other items commented in header ) |
|
501 //----------------------------------------------------------------------------- |
|
502 void CCAMessageHandler::HandleMessageSentL( TInt aStatus, TInt aOperationCode, |
|
503 TBool aSuccess ) |
|
504 { |
|
505 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentL" ); |
|
506 CHAT_DP( D_CHAT_LIT( "OpCode = %d, Success = %d" ), aOperationCode, aSuccess ); |
|
507 |
|
508 if ( !iSendBuffer ) |
|
509 { |
|
510 // send buffer was deleted, we're shutting down |
|
511 CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) ); |
|
512 return; |
|
513 } |
|
514 |
|
515 TInt index = User::LeaveIfError( iSendBuffer->FindIndex( aOperationCode ) ); |
|
516 |
|
517 if ( !aSuccess ) |
|
518 { |
|
519 MCAMessage& message = iSendBuffer->Message( index ); |
|
520 |
|
521 message.SetContainerInfo( NULL ); |
|
522 |
|
523 MCAMessage* failedMessage = |
|
524 iMessageUtils.MessageCreator().CreateFailedMessageL( &message ); |
|
525 CleanupDeletePushL( failedMessage ); |
|
526 MCAMessagesWriteInterface& messageContainer = |
|
527 iChatInterface.MessageWriteInterfaceL( message.ServerAddress(), |
|
528 message.UserId(), |
|
529 message.Recipient() ); |
|
530 CleanupStack::Pop( failedMessage ); |
|
531 messageContainer.AppendL( failedMessage ); |
|
532 NotifyMessageError( aStatus, &message ); |
|
533 } |
|
534 iSendBuffer->DeleteMessage( index ); |
|
535 CHAT_DP( D_CHAT_LIT( "Send buffer has %d messages." ), |
|
536 iSendBuffer->MessageCount() ); |
|
537 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentL" ); |
|
538 } |
|
539 |
|
540 //----------------------------------------------------------------------------- |
|
541 // CCAMessageHandler::SetLocalEchoInGroup |
|
542 // ( Other items commented in header ) |
|
543 //----------------------------------------------------------------------------- |
|
544 void CCAMessageHandler::SetLocalEchoInGroup( TBool aLocalEchoInGroup ) |
|
545 { |
|
546 iLocalEchoInGroup = aLocalEchoInGroup; |
|
547 } |
|
548 |
|
549 //----------------------------------------------------------------------------- |
|
550 // CCAMessageHandler::NotifyMessageError |
|
551 // ( Other items commented in header ) |
|
552 //----------------------------------------------------------------------------- |
|
553 void CCAMessageHandler::NotifyMessageError( TInt aStatus, MCAMessage* aMessage ) |
|
554 { |
|
555 TInt count( iErrorObservers.Count() ); |
|
556 for ( TInt a( 0 ); a < count; ++a ) |
|
557 { |
|
558 iErrorObservers[ a ]->HandleMessageError( aStatus, aMessage ); |
|
559 } |
|
560 } |
|
561 |
|
562 //----------------------------------------------------------------------------- |
|
563 // CCAMessageHandler::RegisterChatObserver |
|
564 // ( Other items commented in header ) |
|
565 //----------------------------------------------------------------------------- |
|
566 void CCAMessageHandler::RegisterObserver( MCAMessageErrorObserver* aObserver ) |
|
567 { |
|
568 TInt index = iErrorObservers.Find( aObserver ); |
|
569 if ( index == KErrNotFound ) |
|
570 { |
|
571 iErrorObservers.Append( aObserver ); |
|
572 } |
|
573 } |
|
574 |
|
575 //----------------------------------------------------------------------------- |
|
576 // CCAMessageHandler::RegisterChatObserver |
|
577 // ( Other items commented in header ) |
|
578 //----------------------------------------------------------------------------- |
|
579 void CCAMessageHandler::UnregisterObserver( MCAMessageErrorObserver* aObserver ) |
|
580 { |
|
581 TInt index = iErrorObservers.Find( aObserver ); |
|
582 if ( index >= 0 ) |
|
583 { |
|
584 iErrorObservers.Remove( index ); |
|
585 } |
|
586 } |
|
587 |
|
588 //----------------------------------------------------------------------------- |
|
589 // CCAMessageHandler::HandleProcessingComplete |
|
590 // ( Other items commented in header ) |
|
591 //----------------------------------------------------------------------------- |
|
592 void CCAMessageHandler::HandleProcessingComplete( |
|
593 MCAContentProcessor& /*aProcessor*/, |
|
594 MCAMessage& /*aMessage*/, |
|
595 TInt aStatus ) |
|
596 { |
|
597 if ( !iIdle->IsActive() && aStatus == KErrNone && !iSendLaunchLock ) |
|
598 { |
|
599 iIdle->Start( TCallBack( SendMessage, this ) ); |
|
600 } |
|
601 } |
|
602 |
|
603 //----------------------------------------------------------------------------- |
|
604 // CCAMessageHandler::NextHoldingMessage |
|
605 // ( Other items commented in header ) |
|
606 //----------------------------------------------------------------------------- |
|
607 MCAMessage* CCAMessageHandler::NextHoldingMessage() |
|
608 { |
|
609 TInt holdingMessages = iHoldingMessages.Count(); |
|
610 MCAMessage* message = NULL; |
|
611 TInt index( 0 ); |
|
612 // Check if holding messages hold one ready message |
|
613 for ( ; index < holdingMessages && !message; ++index ) |
|
614 { |
|
615 MCAMessage* msg = iHoldingMessages[ index ]; |
|
616 if ( ( msg->ContentProcessState() >= MCAMessage::EContentReady ) || |
|
617 ( msg->ContentType() == MCAMessage::EContentText ) ) |
|
618 { |
|
619 CHAT_DP( D_CHAT_LIT( "Ready holding message found. Index( %d )" ), |
|
620 index ); |
|
621 message = msg; |
|
622 iHoldingMessages.Remove( index ); |
|
623 } |
|
624 } |
|
625 return message; |
|
626 } |
|
627 |
|
628 //----------------------------------------------------------------------------- |
|
629 // CCAMessageHandler::NextHoldingMessage |
|
630 // ( Other items commented in header ) |
|
631 //----------------------------------------------------------------------------- |
|
632 TBool CCAMessageHandler::AppendedToHoldingL( MCAMessage& aMessage ) |
|
633 { |
|
634 switch ( aMessage.ContentType() ) |
|
635 { |
|
636 case MCAMessage::EContentPicture: // add scaler |
|
637 { |
|
638 if ( aMessage.ContentProcessState() < MCAMessage::EContentReady ) |
|
639 { |
|
640 CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \ |
|
641 sending. Put to holding." ) ); |
|
642 TInt added = User::LeaveIfError( aMessage.AddContentProcessor( |
|
643 iMessageUtils.ImageScaler(), this ) ); |
|
644 if ( added ) |
|
645 { |
|
646 iHoldingMessages.AppendL( &aMessage ); |
|
647 return ETrue; |
|
648 } |
|
649 } |
|
650 break; |
|
651 } |
|
652 default: // Flowthrough other types |
|
653 { |
|
654 #ifdef RD_SEND_NOT_SUPPORTED_CONTENT |
|
655 if ( aMessage.ContentProcessState() < MCAMessage::EContentReady ) |
|
656 { |
|
657 CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \ |
|
658 sending. Put to holding." ) ); |
|
659 TInt added = User::LeaveIfError( aMessage.AddContentProcessor( |
|
660 iMessageUtils.ImageScaler(), this ) ); |
|
661 if ( added ) |
|
662 { |
|
663 iHoldingMessages.AppendL( &aMessage ); |
|
664 return ETrue; |
|
665 } |
|
666 } |
|
667 #endif //RD_SEND_NOT_SUPPORTED_CONTENT |
|
668 break; |
|
669 } |
|
670 } |
|
671 return EFalse; |
|
672 } |
|
673 |
|
674 //----------------------------------------------------------------------------- |
|
675 // CCAMessageHandler::SendMessageToServerL |
|
676 // ( Other items commented in header ) |
|
677 //----------------------------------------------------------------------------- |
|
678 TInt CCAMessageHandler::SendMessageToServerL( MCAMessage& aMessage ) |
|
679 { |
|
680 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::SendMessageToServerL" ); |
|
681 |
|
682 TInt opCode( 0 ); |
|
683 TBuf< KMaxDataTypeLength > mimeType; |
|
684 CnvUtfConverter::ConvertToUnicodeFromUtf8( mimeType, aMessage.MimeType() ); |
|
685 |
|
686 // granularity of 1 because only one item appended to array |
|
687 CDesCArrayFlat* tempArray = NULL; |
|
688 const MDesCArray* recipients = NULL; |
|
689 |
|
690 const TDesC* sender = NULL; |
|
691 const TDesC* groupId = NULL; |
|
692 |
|
693 if ( aMessage.ScreenNames() ) |
|
694 { |
|
695 groupId = &aMessage.Recipient(); |
|
696 if ( aMessage.ScreenNames()->MdcaCount() > 0 ) |
|
697 { |
|
698 recipients = aMessage.ScreenNames(); |
|
699 } |
|
700 } |
|
701 else |
|
702 { |
|
703 tempArray = new ( ELeave ) CDesCArrayFlat( 1 ); |
|
704 CleanupStack::PushL( tempArray ); |
|
705 tempArray->AppendL( aMessage.Recipient() ); |
|
706 } |
|
707 |
|
708 if ( aMessage.ContentType() == MCAMessage::EContentText ) |
|
709 { |
|
710 CHAT_DP( D_CHAT_LIT( "Send text message" ) ); |
|
711 opCode = iImpsImClient->SendTextMessageL( |
|
712 sender, |
|
713 tempArray, |
|
714 groupId, |
|
715 recipients, |
|
716 aMessage.Text(), |
|
717 EFalse ); |
|
718 } |
|
719 else |
|
720 { |
|
721 CHAT_DP( D_CHAT_LIT( "Send content message" ) ); |
|
722 TInt size( aMessage.ContentData().Size() ); |
|
723 TInt maxSize( iImpsImClient->MaxTransactionContentLengthL() ); |
|
724 if ( size > maxSize ) |
|
725 { |
|
726 // content too big => can't send |
|
727 CHAT_DP( D_CHAT_LIT( "content too big: %d/%d" ), size, maxSize ); |
|
728 User::Leave( KErrOverflow ); |
|
729 } |
|
730 |
|
731 opCode = iImpsImClient->SendContentMessageL( |
|
732 sender, |
|
733 tempArray, |
|
734 groupId, |
|
735 recipients, |
|
736 mimeType, |
|
737 aMessage.ContentData(), |
|
738 EFalse ); |
|
739 } |
|
740 |
|
741 if ( tempArray ) |
|
742 { |
|
743 CleanupStack::PopAndDestroy( tempArray ); |
|
744 } |
|
745 |
|
746 CHAT_DP_FUNC_DONE( "CCAMessageHandler::SendMessageToServerL" ); |
|
747 return opCode; |
|
748 } |
|
749 |
|
750 //----------------------------------------------------------------------------- |
|
751 // CCAMessageHandler::HandleMessageSentFailedL |
|
752 // ( Other items commented in header ) |
|
753 //----------------------------------------------------------------------------- |
|
754 void CCAMessageHandler::HandleMessageSentFailedL( MCAMessage& aMessage, |
|
755 TInt aError ) |
|
756 { |
|
757 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentFailedL" ); |
|
758 MCAMessage* failMessage = |
|
759 iMessageUtils.MessageCreator().CreateFailedMessageL( &aMessage ); |
|
760 CleanupDeletePushL( failMessage ); |
|
761 MCAMessagesWriteInterface& messageContainer = |
|
762 iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(), |
|
763 aMessage.UserId(), |
|
764 aMessage.Recipient() ); |
|
765 CleanupStack::Pop( failMessage ); |
|
766 |
|
767 // Notify observers for error. |
|
768 NotifyMessageError( aError, &aMessage ); |
|
769 messageContainer.AppendL( failMessage ); |
|
770 CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentFailedL" ); |
|
771 } |
|
772 |
|
773 //----------------------------------------------------------------------------- |
|
774 // CCAMessageHandler::LocalEchoMessageL |
|
775 // ( Other items commented in header ) |
|
776 //----------------------------------------------------------------------------- |
|
777 void CCAMessageHandler::LocalEchoMessageL( MCAMessage& aMessage ) |
|
778 { |
|
779 CHAT_DP_FUNC_ENTER( "CCAMessageHandler::LocalEchoMessageL" ); |
|
780 |
|
781 if ( aMessage.MessageType() == MCAMessage::EMessageGroup |
|
782 && !iLocalEchoInGroup ) |
|
783 { |
|
784 // Local echo is not allowed in groups. |
|
785 CHAT_DP( D_CHAT_LIT( " Message not shown because local echo is not \ |
|
786 allowed." ) ); |
|
787 return; |
|
788 } |
|
789 |
|
790 MCAMessagesWriteInterface& messageContainer = |
|
791 iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(), |
|
792 aMessage.UserId(), |
|
793 aMessage.Recipient() ); |
|
794 |
|
795 if ( aMessage.MessageType() == MCAMessage::EMessageWhisper ) |
|
796 { |
|
797 // Local echo ones for all recipients |
|
798 const MDesCArray* recipients = aMessage.ScreenNames(); |
|
799 TInt count( recipients->MdcaCount() ); |
|
800 for ( TInt a( 0 ); a < count; ++a ) |
|
801 { |
|
802 MCAMessageCreator::SMessageData data = |
|
803 { |
|
804 KMessageDataVersion, |
|
805 aMessage.OperationCode(), |
|
806 aMessage.ServerAddress(), |
|
807 aMessage.UserId(), |
|
808 aMessage.Sender(), |
|
809 recipients->MdcaPoint( a ), |
|
810 aMessage.Recipients(), |
|
811 recipients, |
|
812 aMessage.Text(), |
|
813 aMessage.MimeType(), |
|
814 aMessage.ContentData(), |
|
815 aMessage.MessagerType() |
|
816 }; |
|
817 MCAMessage* message = |
|
818 iMessageUtils.MessageCreator().CreateMessageL( data ); |
|
819 message->SetProcessState( MCAMessage::EContentReady ); |
|
820 |
|
821 // Append message |
|
822 CAMessageUtil::AppendMessageWithDateStampL( |
|
823 *message, |
|
824 messageContainer, |
|
825 iMessageUtils.MessageCreator() ); |
|
826 } |
|
827 } |
|
828 else |
|
829 { |
|
830 // Append message |
|
831 CAMessageUtil::AppendMessageWithDateStampL( |
|
832 aMessage, |
|
833 messageContainer, |
|
834 iMessageUtils.MessageCreator(), |
|
835 ETrue ); |
|
836 } |
|
837 CHAT_DP_FUNC_DONE( "CCAMessageHandler::LocalEchoMessageL" ); |
|
838 } |
|
839 |
|
840 |
|
841 // end of file |