|
1 /* |
|
2 * Copyright (c) 2008 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: Message Store Handling for Indications |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "msgstorehandler.h" |
|
19 #include "s60qconversions.h" |
|
20 #include "msgnotifier_p.h" |
|
21 #include <ccsrequesthandler.h> |
|
22 #include <ccsconversationentry.h> |
|
23 #include <ccsclientconversation.h> |
|
24 |
|
25 #include <msvids.h> |
|
26 #include <mmsconst.h> |
|
27 #include <SendUiConsts.h> |
|
28 #include <msvsearchsortquery.h> |
|
29 #include <msvsearchsortoperation.h> |
|
30 |
|
31 // CONSTANTS |
|
32 |
|
33 // ================= MEMBER FUNCTIONS ======================= |
|
34 |
|
35 // --------------------------------------------------------- |
|
36 // Default constructor. |
|
37 // --------------------------------------------------------- |
|
38 // |
|
39 MsgStoreHandler::MsgStoreHandler(MsgNotifierPrivate* notifier, CCSRequestHandler* aCvServer) : |
|
40 iMsvSession(NULL), iNotifier(notifier), iRequestHandler(aCvServer) |
|
41 { |
|
42 TRAP_IGNORE(InitL()); |
|
43 } |
|
44 |
|
45 // --------------------------------------------------------- |
|
46 // Destructor. |
|
47 // --------------------------------------------------------- |
|
48 // |
|
49 MsgStoreHandler::~MsgStoreHandler() |
|
50 { |
|
51 if (iMsvEntry) { |
|
52 delete iMsvEntry; |
|
53 iMsvEntry = NULL; |
|
54 } |
|
55 |
|
56 if (iMsvSession) { |
|
57 delete iMsvSession; |
|
58 iMsvSession = NULL; |
|
59 } |
|
60 |
|
61 if (iFailedMessages) { |
|
62 delete iFailedMessages; |
|
63 iFailedMessages = NULL; |
|
64 } |
|
65 |
|
66 if (iFailedNotes) { |
|
67 delete iFailedNotes; |
|
68 iFailedNotes = NULL; |
|
69 } |
|
70 } |
|
71 |
|
72 // --------------------------------------------------------- |
|
73 // InitL( ) |
|
74 // Initialize the Store handler. |
|
75 // --------------------------------------------------------- |
|
76 void MsgStoreHandler::InitL() |
|
77 { |
|
78 iMsvSession = CMsvSession::OpenSyncL(*this); |
|
79 iMsvEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId); |
|
80 iMsvEntry->AddObserverL(*this); |
|
81 |
|
82 iFailedMessages = new (ELeave) CMsvEntrySelection; |
|
83 iFailedNotes = new (ELeave) CMsvEntrySelection; |
|
84 } |
|
85 |
|
86 // --------------------------------------------------------- |
|
87 // MsgStoreHandler::HandleSessionEventL() |
|
88 // --------------------------------------------------------- |
|
89 // |
|
90 void MsgStoreHandler::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/) |
|
91 { |
|
92 CMsvEntrySelection* selection = NULL; |
|
93 TMsvId parent; |
|
94 |
|
95 //args |
|
96 if (aArg1 == NULL || aArg2 == NULL) { |
|
97 return; |
|
98 } |
|
99 |
|
100 //start, processing the event |
|
101 selection = (CMsvEntrySelection*) aArg1; |
|
102 parent = *(TMsvId*) aArg2; |
|
103 |
|
104 // Return when not (outbox or inbox) and event not EMsvEntriesChanged |
|
105 if (!(parent == KMsvGlobalOutBoxIndexEntryIdValue || parent == KMsvGlobalInBoxIndexEntryIdValue) |
|
106 && aEvent != EMsvEntriesChanged) { |
|
107 return; |
|
108 } |
|
109 |
|
110 //Handling for outbox entries |
|
111 if( parent == KMsvGlobalOutBoxIndexEntryIdValue ) |
|
112 { |
|
113 CMsvEntry* rootEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId); |
|
114 |
|
115 for (TInt i = 0; i < selection->Count(); ++i) { |
|
116 TMsvEntry entry = rootEntry->ChildDataL(selection->At(i)); |
|
117 |
|
118 if ((entry.iMtm == KSenduiMtmSmsUid) || (entry.iMtm == KSenduiMtmMmsUid)) { |
|
119 TUint sendingState = entry.SendingState(); |
|
120 TInt index = iFailedMessages->Find(entry.Id()); |
|
121 |
|
122 if (sendingState == KMsvSendStateFailed && KErrNotFound == index) { |
|
123 iFailedMessages->AppendL(entry.Id()); |
|
124 iFailedNotes->AppendL(entry.Id()); |
|
125 } |
|
126 else if (sendingState != KMsvSendStateFailed && KErrNotFound != index) { |
|
127 iFailedMessages->Delete(index); |
|
128 iFailedMessages->Compress(); |
|
129 } |
|
130 if (iFailedNotes->Count()) { |
|
131 MsgInfo aInfo; |
|
132 ProcessIndicatorDataL(iFailedNotes->At(0), aInfo); |
|
133 iNotifier->displayFailedNote(aInfo); |
|
134 iFailedNotes->Delete(0); |
|
135 iFailedNotes->Compress(); |
|
136 } |
|
137 } |
|
138 }//end for |
|
139 } |
|
140 else |
|
141 { |
|
142 TMsvEntry entry; |
|
143 TMsvId service; |
|
144 TInt error= KErrNone; |
|
145 for (TInt i = 0; i < selection->Count(); ++i) |
|
146 { |
|
147 error = iMsvSession->GetEntry(selection->At(i), service, entry); |
|
148 |
|
149 if (error == KErrNone && entry.iMtm == KUidMsgMMSNotification && MmsNotificationStatus( |
|
150 entry) == EMsgStatusFailed) |
|
151 { |
|
152 MsgInfo aInfo; |
|
153 |
|
154 //Fill aInfo with appropriate data |
|
155 aInfo.mMessageType = ECsMmsNotification; |
|
156 |
|
157 ProcessIndicatorDataL(entry.Id(),aInfo); |
|
158 iNotifier->displayFailedNote(aInfo); |
|
159 } |
|
160 } |
|
161 } |
|
162 } |
|
163 |
|
164 // --------------------------------------------------------- |
|
165 // MsgStoreHandler::HandleEntryEventL() |
|
166 // --------------------------------------------------------- |
|
167 |
|
168 void MsgStoreHandler::HandleEntryEventL(TMsvEntryEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, |
|
169 TAny* /*aArg3*/) |
|
170 { |
|
171 switch (aEvent) { |
|
172 case EMsvChildrenChanged: |
|
173 case EMsvDeletedChildren: |
|
174 { |
|
175 UpdateOutboxIndications(); |
|
176 break; |
|
177 } |
|
178 default: |
|
179 break; |
|
180 |
|
181 } |
|
182 } |
|
183 |
|
184 // --------------------------------------------------------- |
|
185 // UpdateOutboxIndications() |
|
186 // Outgoing Pending message/messages |
|
187 // --------------------------------------------------------- |
|
188 void MsgStoreHandler::UpdateOutboxIndications() |
|
189 { |
|
190 MsgInfo failedIndicatorData; |
|
191 MsgInfo pendingIndicatorData; |
|
192 |
|
193 TInt err = KErrNone; |
|
194 |
|
195 TRAP(err, GetOutboxEntriesL(failedIndicatorData, pendingIndicatorData)); |
|
196 |
|
197 if (err == KErrNone) { |
|
198 iNotifier->displayOutboxIndications(failedIndicatorData); |
|
199 iNotifier->displayOutboxIndications(pendingIndicatorData); |
|
200 } |
|
201 } |
|
202 |
|
203 // --------------------------------------------------------- |
|
204 // GetOutboxEntries() |
|
205 // Outgoing Pending message/messages |
|
206 // --------------------------------------------------------- |
|
207 TInt MsgStoreHandler::GetOutboxEntriesL(MsgInfo& aFailedIndicatorData, |
|
208 MsgInfo& aPendingIndicatorData) |
|
209 { |
|
210 CMsvEntry* rootEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId); |
|
211 CMsvEntrySelection* messages = rootEntry->ChildrenL(); |
|
212 |
|
213 TInt failedMessageCount = 0; |
|
214 TInt pendingMessageCount = 0; |
|
215 |
|
216 for (TInt i = 0; i < messages->Count(); ++i) { |
|
217 TMsvEntry entry = rootEntry->ChildDataL(messages->At(i)); |
|
218 if ((entry.iMtm != KSenduiMtmSmsUid) && (entry.iMtm != KSenduiMtmMmsUid)) { |
|
219 continue; |
|
220 } |
|
221 |
|
222 if (entry.SendingState() == KMsvSendStateFailed) { |
|
223 ++failedMessageCount; |
|
224 } |
|
225 else { |
|
226 ++pendingMessageCount; |
|
227 } |
|
228 |
|
229 if (entry.SendingState() == KMsvSendStateFailed) { |
|
230 ProcessIndicatorDataL(entry.Id(), aFailedIndicatorData); |
|
231 } |
|
232 else { |
|
233 ProcessIndicatorDataL(entry.Id(), aPendingIndicatorData); |
|
234 } |
|
235 |
|
236 } |
|
237 |
|
238 aFailedIndicatorData.mFromSingle = (failedMessageCount > 1) ? false : true; |
|
239 aPendingIndicatorData.mFromSingle = (pendingMessageCount > 1) ? false : true; |
|
240 aFailedIndicatorData.mIndicatorType = FailedIndicatorPlugin; |
|
241 aPendingIndicatorData.mIndicatorType = PendingIndicatorPlugin; |
|
242 aFailedIndicatorData.mMsgCount = failedMessageCount; |
|
243 aPendingIndicatorData.mMsgCount = pendingMessageCount; |
|
244 |
|
245 return KErrNone; |
|
246 } |
|
247 |
|
248 // --------------------------------------------------------- |
|
249 // ProcessIndicatorData() |
|
250 // Process the data in the MsgInfo object. |
|
251 // --------------------------------------------------------- |
|
252 |
|
253 void MsgStoreHandler::ProcessIndicatorDataL(TMsvId msgId, MsgInfo& indicatorData) |
|
254 { |
|
255 CCsClientConversation* conversation = iRequestHandler->GetConversationFromMessageIdL(msgId); |
|
256 if (conversation == NULL) |
|
257 return; |
|
258 |
|
259 indicatorData.mConversationId = conversation->GetConversationEntryId(); |
|
260 CCsConversationEntry* convEntry = conversation->GetConversationEntry(); |
|
261 |
|
262 //check for valid data |
|
263 if ((indicatorData.mConversationId == -1) || (convEntry == NULL)) { |
|
264 delete conversation; |
|
265 return; |
|
266 } |
|
267 |
|
268 //set indicator data |
|
269 HBufC* displayName = conversation->GetDisplayName(); |
|
270 |
|
271 if (displayName) { |
|
272 indicatorData.mDisplayName.append(S60QConversions::s60DescToQString(*displayName)); |
|
273 } |
|
274 else { |
|
275 HBufC* number = convEntry->Contact(); |
|
276 if (number) |
|
277 indicatorData.mDisplayName.append(S60QConversions::s60DescToQString(*number)); |
|
278 } |
|
279 delete conversation; |
|
280 } |
|
281 |
|
282 // --------------------------------------------------------- |
|
283 // GetUnreadMessageCountL() |
|
284 // Get Unread message count. |
|
285 // --------------------------------------------------------- |
|
286 |
|
287 int MsgStoreHandler::GetUnreadMessageCountL() |
|
288 { |
|
289 //Create the query/operation object |
|
290 CMsvSearchSortOperation *operation = CMsvSearchSortOperation::NewL(*iMsvSession); |
|
291 CleanupStack::PushL(operation); |
|
292 CMsvSearchSortQuery *query = CMsvSearchSortQuery::NewL(); |
|
293 CleanupStack::PushL(query); |
|
294 |
|
295 //set the query options |
|
296 query->SetParentId(KMsvGlobalInBoxIndexEntryId); |
|
297 query->SetResultType(EMsvResultAsTMsvEntry); |
|
298 query->AddSearchOptionL(EMsvUnreadMessages, ETrue); |
|
299 CleanupStack::Pop(query); |
|
300 |
|
301 CMsvOperationWait* wait = CMsvOperationWait::NewLC(); |
|
302 //ownership of Query transferred to Operation |
|
303 operation->RequestL(query, EFalse, wait->iStatus); |
|
304 wait->Start(); |
|
305 CActiveScheduler::Start(); |
|
306 |
|
307 //Get No of entries |
|
308 int count = operation->GetResultCountL(); |
|
309 CleanupStack::PopAndDestroy(2, operation); |
|
310 |
|
311 return count; |
|
312 } |
|
313 |
|
314 // --------------------------------------------------------- |
|
315 // MsgStoreHandler::MmsNotificationStatus |
|
316 // --------------------------------------------------------- |
|
317 // |
|
318 TCsMmsNotificationMsgState MsgStoreHandler:: |
|
319 MmsNotificationStatus( TMsvEntry entry ) |
|
320 { |
|
321 TCsMmsNotificationMsgState status = EMsgStatusNull; |
|
322 |
|
323 // operationMask includes operation type. It is not bitmap but ordinal number. |
|
324 // It does not include operation status and result |
|
325 TInt operationMask = (entry.iMtmData2 & KMmsOperationIdentifier) ; |
|
326 |
|
327 // Note! Ongoing operation resets every bit of operation type, operation status |
|
328 // and result. E.g. If message has been forwarded and then fetching starts, |
|
329 // information about forwarding is lost |
|
330 |
|
331 if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd ) |
|
332 { |
|
333 if( operationMask == KMmsOperationFetch |
|
334 && OperationOngoing( entry ) ) |
|
335 { |
|
336 // It's in retrieving state |
|
337 status = EMsgStatusRetrieving; |
|
338 } |
|
339 else if( operationMask == KMmsOperationForward |
|
340 && OperationOngoing( entry ) ) |
|
341 { |
|
342 // It's in forwarding state |
|
343 status = EMsgStatusForwarding; |
|
344 } |
|
345 else if( operationMask == KMmsOperationForward |
|
346 && OperationFinished( entry ) |
|
347 && !( entry.iMtmData2 & KMmsOperationResult ) ) |
|
348 { |
|
349 // It's been forwarded succesfully |
|
350 status = EMsgStatusForwarded; |
|
351 } |
|
352 else if( operationMask == KMmsOperationFetch |
|
353 && OperationFinished( entry ) |
|
354 && ( entry.iMtmData2 & KMmsOperationResult |
|
355 || entry.iError ) ) |
|
356 { |
|
357 // Fetch has been failed |
|
358 status = EMsgStatusFailed; |
|
359 } |
|
360 else if( operationMask == KMmsOperationDelete |
|
361 && OperationFinished( entry ) |
|
362 && !( entry.iMtmData2 & KMmsOperationResult ) ) |
|
363 { |
|
364 // It's been deleted succesfully |
|
365 status = EMsgStatusDeleted; |
|
366 } |
|
367 else |
|
368 { // Normal waiting state |
|
369 status = EMsgStatusReadyForFetching; |
|
370 } |
|
371 } |
|
372 |
|
373 return status; |
|
374 } |
|
375 |
|
376 // --------------------------------------------------------- |
|
377 // MsgStoreHandler::OperationOngoing |
|
378 // --------------------------------------------------------- |
|
379 // |
|
380 TBool MsgStoreHandler::OperationOngoing( const TMsvEntry& aEntry ) const |
|
381 { |
|
382 return ( aEntry.iMtmData2 & KMmsOperationOngoing |
|
383 && !( aEntry.iMtmData2 & KMmsOperationFinished ) ); |
|
384 } |
|
385 |
|
386 // --------------------------------------------------------- |
|
387 // ConversationMsgStoreHandler::OperationFinished |
|
388 // --------------------------------------------------------- |
|
389 // |
|
390 TBool MsgStoreHandler::OperationFinished( |
|
391 const TMsvEntry& aEntry ) const |
|
392 { |
|
393 return ( aEntry.iMtmData2 & KMmsOperationFinished |
|
394 && !( aEntry.iMtmData2 & KMmsOperationOngoing ) ); |
|
395 } |
|
396 |
|
397 // End of file |