|
1 /* |
|
2 * Copyright (c) 2010 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: Implements class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 |
|
22 #include "coutboxsendoperation.h" // header |
|
23 |
|
24 #include <SendUiConsts.h> // MTM Uids |
|
25 #include <msvids.h> // Entry Ids |
|
26 #include <gsmerror.h> // SMS sending failure error codes |
|
27 #include <smutset.h> |
|
28 #include "debugtraces.h" |
|
29 |
|
30 // ================= MEMBER FUNCTIONS ======================= |
|
31 |
|
32 // Two-phased constructor. |
|
33 COutboxSendOperation* COutboxSendOperation::NewL( |
|
34 CMsvSession& aMsvSession, |
|
35 TRequestStatus& aObserverRequestStatus ) |
|
36 { |
|
37 // Create the instance of sending operation |
|
38 COutboxSendOperation* self = |
|
39 new (ELeave) COutboxSendOperation( |
|
40 aMsvSession, aObserverRequestStatus ); |
|
41 |
|
42 // Push self into cleanup stack during construction |
|
43 CleanupStack::PushL(self); |
|
44 self->ConstructL(); |
|
45 CleanupStack::Pop(); |
|
46 |
|
47 // Return the object |
|
48 return self; |
|
49 } |
|
50 |
|
51 // C++ default constructor can NOT contain any code that |
|
52 // might leave. |
|
53 // |
|
54 COutboxSendOperation::COutboxSendOperation( |
|
55 CMsvSession& aMsvSession, |
|
56 TRequestStatus& aObserverRequestStatus ) |
|
57 : |
|
58 CMsvOperation( aMsvSession, CActive::EPriorityStandard, aObserverRequestStatus ), |
|
59 iSelections( 4 ), |
|
60 iServices(), |
|
61 iSupportedMsgs( COutboxSendOperation::ESupportsSmsSending ) |
|
62 { |
|
63 // Start scheduler |
|
64 CActiveScheduler::Add(this); |
|
65 } |
|
66 |
|
67 //destructor |
|
68 COutboxSendOperation::~COutboxSendOperation() |
|
69 { |
|
70 // Cancel sending |
|
71 Cancel(); |
|
72 |
|
73 // Delete sending operation |
|
74 delete iOperation; |
|
75 iOperation = NULL; |
|
76 |
|
77 // Delete entry |
|
78 delete iEntry; |
|
79 iEntry = NULL; |
|
80 |
|
81 // Remove services from queue and destroy message selections |
|
82 iServices.Reset(); |
|
83 iSelections.ResetAndDestroy(); |
|
84 } |
|
85 |
|
86 // ---------------------------------------------------- |
|
87 // COutboxSendOperation::ConstructL |
|
88 // ---------------------------------------------------- |
|
89 // |
|
90 void COutboxSendOperation::ConstructL() |
|
91 { |
|
92 // Get rootindex entry |
|
93 iEntry = iMsvSession.GetEntryL( KMsvRootIndexEntryId ); |
|
94 iEntry->SetSortTypeL( |
|
95 TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ) ); |
|
96 |
|
97 // Set sending flags |
|
98 iSupportedMsgs |= ESendSms; |
|
99 |
|
100 // Start sending |
|
101 StartSendingL(); |
|
102 } |
|
103 |
|
104 // ---------------------------------------------------- |
|
105 // COutboxSendOperation::RunL |
|
106 // ---------------------------------------------------- |
|
107 // |
|
108 void COutboxSendOperation::RunL() |
|
109 { |
|
110 QDEBUG_WRITE("COutboxSendOperation::RunL"); |
|
111 User::LeaveIfError( iStatus.Int() ); |
|
112 |
|
113 // Check and start sending, if needed |
|
114 TUid sendMtm; |
|
115 |
|
116 // Check if messages needs to be sent |
|
117 if( IsSendingNeeded( sendMtm ) ) |
|
118 { |
|
119 StartSendingL(); |
|
120 } |
|
121 // Nothing to send, complete operation |
|
122 else |
|
123 { |
|
124 CompleteObserver( iStatus.Int() ); |
|
125 } |
|
126 } |
|
127 |
|
128 // ---------------------------------------------------- |
|
129 // COutboxSendOperation::RunError |
|
130 // ---------------------------------------------------- |
|
131 // |
|
132 TInt COutboxSendOperation::RunError( TInt aError ) |
|
133 { |
|
134 CompleteObserver( aError ); |
|
135 return aError; |
|
136 } |
|
137 |
|
138 // ---------------------------------------------------- |
|
139 // COutboxSendOperation::DoCancel |
|
140 // ---------------------------------------------------- |
|
141 // |
|
142 void COutboxSendOperation::DoCancel() |
|
143 { |
|
144 // Check if sending operation is running |
|
145 if( iOperation ) |
|
146 { |
|
147 // Cancel it |
|
148 iOperation->Cancel(); |
|
149 } |
|
150 |
|
151 // Complete operation with current status |
|
152 CompleteObserver( iStatus.Int() ); |
|
153 } |
|
154 |
|
155 // ---------------------------------------------------- |
|
156 // COutboxSendOperation::ProgressL |
|
157 // ---------------------------------------------------- |
|
158 // |
|
159 const TDesC8& COutboxSendOperation::ProgressL() |
|
160 { |
|
161 // Check if operation exists |
|
162 if( iOperation ) |
|
163 { |
|
164 // Return the operation |
|
165 return iOperation->ProgressL(); |
|
166 } |
|
167 |
|
168 // If no operation, return blank information |
|
169 return KNullDesC8(); |
|
170 } |
|
171 |
|
172 // --------------------------------------------------------- |
|
173 // COutboxSendOperation::CompleteOperation |
|
174 // --------------------------------------------------------- |
|
175 // |
|
176 void COutboxSendOperation::CompleteObserver( TInt aStatus ) |
|
177 { |
|
178 // Get the observer status |
|
179 TRequestStatus* status = &iObserverRequestStatus; |
|
180 User::RequestComplete( status, aStatus ); |
|
181 } |
|
182 |
|
183 // ---------------------------------------------------- |
|
184 // COutboxSendOperation::StartSendingL |
|
185 // ---------------------------------------------------- |
|
186 // |
|
187 void COutboxSendOperation::StartSendingL() |
|
188 { |
|
189 // Remove any sending operation that currently may be running |
|
190 delete iOperation; |
|
191 iOperation = NULL; |
|
192 |
|
193 |
|
194 // Check if there was errors with creating selection |
|
195 if ( CheckAndCreateSelectionL() ) |
|
196 { |
|
197 // Create new operation and trap any errors |
|
198 SendWaitingSMSMessages(); |
|
199 RemoveSelection(); |
|
200 } |
|
201 else |
|
202 { |
|
203 CompleteSelf( KErrNone ); |
|
204 } |
|
205 } |
|
206 |
|
207 // if error, then complete this pass with the error code |
|
208 void COutboxSendOperation::SendWaitingSMSMessages() |
|
209 { |
|
210 TRAPD( err, SendWaitingSMSMessagesL() ); |
|
211 if ( err != KErrNone ) |
|
212 { |
|
213 ASSERT( !IsActive() ); |
|
214 CompleteSelf( err ); |
|
215 } |
|
216 } |
|
217 |
|
218 // ---------------------------------------------------- |
|
219 // COutboxSendOperation::SendWaitingSMSMessagesL |
|
220 // ---------------------------------------------------- |
|
221 // |
|
222 void COutboxSendOperation::SendWaitingSMSMessagesL() |
|
223 { |
|
224 // Get first selection from queue |
|
225 CMsvEntrySelection& selection = ( *iSelections[0] ); |
|
226 |
|
227 // Get count of messages in queue |
|
228 TInt count = selection.Count(); |
|
229 |
|
230 // Go through all messages |
|
231 while( count-- ) |
|
232 { |
|
233 // Select message |
|
234 iEntry->SetEntryL( selection[count] ); |
|
235 TMsvEntry entry( iEntry->Entry() ); |
|
236 |
|
237 // Check if the message is tried to send when in offline |
|
238 if( ( entry.SendingState() == KMsvSendStateSuspended || |
|
239 entry.SendingState() == KMsvSendStateFailed) && |
|
240 ( entry.iError == KErrGsmOfflineOpNotAllowed || |
|
241 entry.iError == KErrGsmOfflineSimOpNotAllowed) ) |
|
242 { |
|
243 // Set message to wait sending |
|
244 entry.SetSendingState( KMsvSendStateWaiting ); |
|
245 iEntry->ChangeL( entry ); |
|
246 } |
|
247 else |
|
248 { |
|
249 selection.Delete( count ); |
|
250 } |
|
251 } |
|
252 selection.Compress(); |
|
253 |
|
254 // Set entry to outbox |
|
255 iMtm = iEntry->Entry().iMtm; |
|
256 iEntry->SetEntryL( KMsvGlobalOutBoxIndexEntryId ); |
|
257 if ( selection.Count() ) |
|
258 { |
|
259 iOperation = iEntry->CopyL( selection, iServices[0], iStatus ); |
|
260 SetActive(); |
|
261 } |
|
262 else |
|
263 { |
|
264 // Nothing to send, but we must complete the observer via our RunL callback |
|
265 CompleteSelf( KErrNone ); |
|
266 } |
|
267 } |
|
268 |
|
269 |
|
270 // ---------------------------------------------------- |
|
271 // COutboxSendOperation::RemoveSelection |
|
272 // ---------------------------------------------------- |
|
273 // |
|
274 void COutboxSendOperation::RemoveSelection() |
|
275 { |
|
276 // Clear the the current selection. |
|
277 iServices.Delete(0); |
|
278 |
|
279 // Delete selection object and index |
|
280 delete iSelections[0]; |
|
281 iSelections.Delete(0); |
|
282 } |
|
283 |
|
284 // ---------------------------------------------------- |
|
285 // COutboxSendOperation::CreateSelectionL |
|
286 // ---------------------------------------------------- |
|
287 // |
|
288 void COutboxSendOperation::CreateSelectionL( |
|
289 const TUid &aUidForSel, |
|
290 const TMsvId& aServiceId, |
|
291 CMsvEntrySelection*& aSelection ) |
|
292 { |
|
293 // Set entry to outbox and get messages from outbox |
|
294 iEntry->SetEntryL( KMsvGlobalOutBoxIndexEntryId ); |
|
295 aSelection = iEntry->ChildrenWithMtmL( *&aUidForSel ); |
|
296 |
|
297 // Check if there is anything to put into array |
|
298 if( aSelection->Count() ) |
|
299 { |
|
300 // Put selection to queue |
|
301 CleanupStack::PushL( aSelection ); |
|
302 iSelections.AppendL( aSelection ); |
|
303 CleanupStack::Pop( aSelection ); |
|
304 |
|
305 // Put service to queue |
|
306 iServices.AppendL( aServiceId ); |
|
307 } |
|
308 else |
|
309 { |
|
310 // Remove selection |
|
311 delete aSelection; |
|
312 aSelection = NULL; |
|
313 } |
|
314 } |
|
315 |
|
316 // ---------------------------------------------------- |
|
317 // COutboxSendOperation::CheckAndCreateSelectionL |
|
318 // ---------------------------------------------------- |
|
319 // |
|
320 TBool COutboxSendOperation::CheckAndCreateSelectionL() |
|
321 { |
|
322 // Get root index |
|
323 iEntry->SetEntryL( KMsvRootIndexEntryId ); |
|
324 |
|
325 // MTM, for which the selection is collected |
|
326 TUid sendMtm; |
|
327 |
|
328 // Selection of messages for sending |
|
329 CMsvEntrySelection* smsSelection = NULL; |
|
330 |
|
331 // While MTM's available for sending |
|
332 while( smsSelection == NULL && IsSendingNeeded( sendMtm ) ) |
|
333 { |
|
334 // Find default SMS service |
|
335 TMsvId serviceId =0; |
|
336 TSmsUtilities::ServiceIdL(*iEntry, serviceId); |
|
337 QDEBUG_WRITE_FORMAT("COutboxSendOperation::CheckAndCreateSelectionL ",serviceId ); |
|
338 // Check if the service ID is found |
|
339 if( serviceId != KMsvNullIndexEntryId ) |
|
340 { |
|
341 // Create selection of messages of specified MTM |
|
342 CreateSelectionL( sendMtm, serviceId, smsSelection ); |
|
343 } |
|
344 // Selection has been created, remove the flag |
|
345 RemoveSendingFlag( *&sendMtm ); |
|
346 } |
|
347 |
|
348 const TBool selectionAvailable = ( smsSelection != NULL ); |
|
349 return selectionAvailable; |
|
350 } |
|
351 |
|
352 // ---------------------------------------------------- |
|
353 // COutboxSendOperation::RemoveSendingFlag |
|
354 // ---------------------------------------------------- |
|
355 // |
|
356 void COutboxSendOperation::RemoveSendingFlag( const TUid& aMtm ) |
|
357 { |
|
358 // Decide actions by mtm |
|
359 switch( aMtm.iUid ) |
|
360 { |
|
361 // SMS-messages |
|
362 case KSenduiMtmSmsUidValue: |
|
363 iSupportedMsgs &= ~ESendSms; |
|
364 break; |
|
365 default: |
|
366 break; |
|
367 } |
|
368 } |
|
369 |
|
370 // ---------------------------------------------------- |
|
371 // COutboxSendOperation::IsSendingNeeded |
|
372 // ---------------------------------------------------- |
|
373 // |
|
374 TBool COutboxSendOperation::IsSendingNeeded( |
|
375 TUid& aMtm ) const |
|
376 { |
|
377 // Set starting condition |
|
378 TBool needSending = EFalse; |
|
379 |
|
380 // Check if sms-sending is supported and messages need to be sent |
|
381 if( iSupportedMsgs & ESupportsSmsSending && |
|
382 iSupportedMsgs & ESendSms ) |
|
383 { |
|
384 aMtm = KSenduiMtmSmsUid; |
|
385 needSending = ETrue; |
|
386 } |
|
387 // Otherwise nothing needs to be done |
|
388 else |
|
389 { |
|
390 aMtm.iUid = 0; |
|
391 needSending = EFalse; |
|
392 } |
|
393 |
|
394 // Return the result |
|
395 return needSending; |
|
396 } |
|
397 |
|
398 // ---------------------------------------------------- |
|
399 // COutboxSendOperation::CompleteSelf |
|
400 // ---------------------------------------------------- |
|
401 // |
|
402 void COutboxSendOperation::CompleteSelf( TInt aValue ) |
|
403 { |
|
404 TRequestStatus* status = &iStatus; |
|
405 User::RequestComplete( status, aValue ); |
|
406 SetActive(); |
|
407 } |
|
408 |
|
409 // End of file |