|
1 /* |
|
2 * Copyright (c) 2006 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 CNcdDownloadOperationProxy |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <s32strm.h> |
|
20 #include "ncddownloadoperationproxy.h" |
|
21 #include "ncddownloadoperationobserver.h" |
|
22 #include "catalogsdebug.h" |
|
23 #include "ncddownloadoperationstates.h" |
|
24 #include "ncdoperationproxyremovehandler.h" |
|
25 #include "catalogsclientserver.h" |
|
26 #include "ncdnodeproxy.h" |
|
27 #include "ncdnodemanagerproxy.h" |
|
28 #include "catalogsutils.h" |
|
29 |
|
30 // ======== MEMBER FUNCTIONS ======== |
|
31 |
|
32 // --------------------------------------------------------------------------- |
|
33 // |
|
34 // --------------------------------------------------------------------------- |
|
35 // |
|
36 CNcdDownloadOperationProxy* CNcdDownloadOperationProxy::NewL( |
|
37 MCatalogsClientServer& aSession, |
|
38 TNcdDownloadDataType aDownloadType, |
|
39 TInt aHandle, |
|
40 MNcdOperationProxyRemoveHandler* aRemoveHandler, |
|
41 CNcdNodeProxy* aNode, |
|
42 MNcdDownloadOperationObserver* aObserver, |
|
43 CNcdNodeManagerProxy* aNodeManager, |
|
44 TInt aDownloadIndex, |
|
45 TBool aIsRunning ) |
|
46 { |
|
47 CNcdDownloadOperationProxy* self = CNcdDownloadOperationProxy::NewLC( |
|
48 aSession, |
|
49 aDownloadType, |
|
50 aHandle, |
|
51 aRemoveHandler, |
|
52 aNode, |
|
53 aObserver, |
|
54 aNodeManager, |
|
55 aDownloadIndex, |
|
56 aIsRunning ); |
|
57 CleanupStack::Pop( self ); |
|
58 return self; |
|
59 } |
|
60 |
|
61 |
|
62 // --------------------------------------------------------------------------- |
|
63 // |
|
64 // --------------------------------------------------------------------------- |
|
65 // |
|
66 CNcdDownloadOperationProxy* CNcdDownloadOperationProxy::NewLC( |
|
67 MCatalogsClientServer& aSession, |
|
68 TNcdDownloadDataType aDownloadType, |
|
69 TInt aHandle, |
|
70 MNcdOperationProxyRemoveHandler* aRemoveHandler, |
|
71 CNcdNodeProxy* aNode, |
|
72 MNcdDownloadOperationObserver* aObserver, |
|
73 CNcdNodeManagerProxy* aNodeManager, |
|
74 TInt aDownloadIndex, |
|
75 TBool aIsRunning ) |
|
76 { |
|
77 CNcdDownloadOperationProxy* self = |
|
78 new( ELeave ) CNcdDownloadOperationProxy( aDownloadType, |
|
79 aDownloadIndex ); |
|
80 |
|
81 self->AddRef(); |
|
82 CleanupReleasePushL( *self ); |
|
83 self->ConstructL( aSession, aHandle, aRemoveHandler, aNode, |
|
84 aObserver, aNodeManager, aIsRunning ); |
|
85 return self; |
|
86 } |
|
87 |
|
88 |
|
89 // --------------------------------------------------------------------------- |
|
90 // From MNcdDownloadOperation |
|
91 // |
|
92 // --------------------------------------------------------------------------- |
|
93 // |
|
94 TInt CNcdDownloadOperationProxy::FileCount() |
|
95 { |
|
96 return iFileCount; |
|
97 } |
|
98 |
|
99 |
|
100 // --------------------------------------------------------------------------- |
|
101 // From MNcdDownloadOperation |
|
102 // |
|
103 // --------------------------------------------------------------------------- |
|
104 // |
|
105 TInt CNcdDownloadOperationProxy::CurrentFile() |
|
106 { |
|
107 return iCurrentFile; |
|
108 } |
|
109 |
|
110 |
|
111 // --------------------------------------------------------------------------- |
|
112 // From MNcdDownloadOperation |
|
113 // |
|
114 // --------------------------------------------------------------------------- |
|
115 // |
|
116 void CNcdDownloadOperationProxy::PauseL() |
|
117 { |
|
118 DLTRACEIN( ( "" ) ); |
|
119 HBufC8* data = NULL; |
|
120 |
|
121 TState state = OperationStateL(); |
|
122 // Check that the operation is in a resumable state |
|
123 if ( state == EStateCancelled ) |
|
124 { |
|
125 DLERROR(("Cannot resume! Operation has been cancelled. Leaving")); |
|
126 User::Leave( KErrCancel ); |
|
127 } |
|
128 |
|
129 // Operation must be running for pause to work |
|
130 if ( state != EStateRunning || iIsPaused ) |
|
131 { |
|
132 DLTRACEOUT(("Operation complete or other unresumable state")); |
|
133 return; |
|
134 } |
|
135 |
|
136 ClientServerSession().SendSyncAlloc( ENCDOperationFunctionPause, |
|
137 KNullDesC8(), |
|
138 data, |
|
139 Handle(), |
|
140 0 ); |
|
141 |
|
142 if ( data ) |
|
143 { |
|
144 DLTRACE(("Received progress information")); |
|
145 |
|
146 RDesReadStream stream( *data ); |
|
147 CleanupStack::PushL( data ); |
|
148 CleanupClosePushL( stream ); |
|
149 |
|
150 // Just read completionId from the stream |
|
151 stream.ReadInt32L(); |
|
152 |
|
153 TNcdSendableProgress progress; |
|
154 // Read progress info |
|
155 progress.InternalizeL( stream ); |
|
156 |
|
157 // Update paused state |
|
158 iIsPaused = ( progress.iState == ENcdDownloadPaused ); |
|
159 |
|
160 CleanupStack::PopAndDestroy( 2, data ); // stream, data |
|
161 } |
|
162 |
|
163 SetState( EStateRunning ); |
|
164 DLTRACEOUT( ( "IsPaused: %d", iIsPaused ) ); |
|
165 } |
|
166 |
|
167 |
|
168 // --------------------------------------------------------------------------- |
|
169 // From MNcdDownloadOperation |
|
170 // |
|
171 // --------------------------------------------------------------------------- |
|
172 // |
|
173 void CNcdDownloadOperationProxy::ResumeL() |
|
174 { |
|
175 DLTRACEIN(( "" )); |
|
176 HBufC8* data = NULL; |
|
177 TState state = OperationStateL(); |
|
178 |
|
179 // Check that the operation is in a resumable state |
|
180 if ( state == EStateCancelled ) |
|
181 { |
|
182 DLERROR(("Cannot resume! Operation has been cancelled. Leaving")); |
|
183 User::Leave( KErrCancel ); |
|
184 } |
|
185 |
|
186 if ( ( state != EStateStopped && state != EStateRunning ) || !iIsPaused ) |
|
187 { |
|
188 DLTRACEOUT(("Operation complete or other unresumable state")); |
|
189 return; |
|
190 } |
|
191 |
|
192 ClientServerSession().SendSyncAlloc( ENCDOperationFunctionResume, |
|
193 KNullDesC8(), |
|
194 data, |
|
195 Handle(), |
|
196 0 ); |
|
197 |
|
198 if ( data ) |
|
199 { |
|
200 DLTRACE(("Received progress information")); |
|
201 RDesReadStream stream( *data ); |
|
202 CleanupStack::PushL( data ); |
|
203 CleanupClosePushL( stream ); |
|
204 |
|
205 // Just read the completionId from the stream |
|
206 stream.ReadInt32L(); |
|
207 |
|
208 TNcdSendableProgress progress; |
|
209 // Read progress info |
|
210 |
|
211 progress.InternalizeL( stream ); |
|
212 // Update paused-state |
|
213 iIsPaused = ( progress.iState == ENcdDownloadPaused ); |
|
214 |
|
215 DLTRACE(("Sending continue message")); |
|
216 if ( progress.iState == KNcdDownloadContinueMessageRequired ) |
|
217 { |
|
218 SendContinueMessageL(); |
|
219 } |
|
220 else if ( progress.iState == KNcdDownloadStartMessageRequired ) |
|
221 { |
|
222 DLTRACE(("Start the operation")); |
|
223 SetState( EStateStopped ); |
|
224 DoStartOperationL(); |
|
225 } |
|
226 |
|
227 CleanupStack::PopAndDestroy( 2, data ); // stream, data |
|
228 } |
|
229 |
|
230 SetState( EStateRunning ); |
|
231 DLTRACEOUT(( "" )); |
|
232 } |
|
233 |
|
234 |
|
235 // --------------------------------------------------------------------------- |
|
236 // From MNcdDownloadOperation |
|
237 // |
|
238 // --------------------------------------------------------------------------- |
|
239 // |
|
240 TBool CNcdDownloadOperationProxy::IsPaused() |
|
241 { |
|
242 return iIsPaused; |
|
243 } |
|
244 |
|
245 |
|
246 // --------------------------------------------------------------------------- |
|
247 // |
|
248 // --------------------------------------------------------------------------- |
|
249 // |
|
250 TBool CNcdDownloadOperationProxy::IsPausableL() |
|
251 { |
|
252 DLTRACEIN(("")); |
|
253 TInt data = KErrNone; |
|
254 User::LeaveIfError( ClientServerSession().SendSync( |
|
255 ENCDOperationFunctionGetData, |
|
256 KNullDesC8(), |
|
257 data, |
|
258 Handle() ) ); |
|
259 |
|
260 DLTRACEOUT(("pausable: %d", data == KNcdDownloadIsPausable )); |
|
261 return data == KNcdDownloadIsPausable; |
|
262 } |
|
263 |
|
264 |
|
265 |
|
266 // --------------------------------------------------------------------------- |
|
267 // From MNcdDownloadOperation |
|
268 // Observer adder |
|
269 // --------------------------------------------------------------------------- |
|
270 // |
|
271 void CNcdDownloadOperationProxy::AddObserverL( |
|
272 MNcdDownloadOperationObserver& aObserver ) |
|
273 { |
|
274 DLTRACEIN( ( "this: %X, aObserver: %X", this, &aObserver ) ); |
|
275 TInt err = iObservers.InsertInAddressOrder( &aObserver ); |
|
276 if ( err != KErrNone && err != KErrAlreadyExists ) |
|
277 { |
|
278 User::Leave( err ); |
|
279 } |
|
280 } |
|
281 |
|
282 |
|
283 // --------------------------------------------------------------------------- |
|
284 // From MNcdDownloadOperation |
|
285 // Observer remover |
|
286 // --------------------------------------------------------------------------- |
|
287 // |
|
288 TBool CNcdDownloadOperationProxy::RemoveObserver( |
|
289 MNcdDownloadOperationObserver& aObserver ) |
|
290 { |
|
291 DLTRACEIN( ( "this: %X, aObserver: %X", this, &aObserver ) ); |
|
292 // observer must exist |
|
293 |
|
294 TInt index = iObservers.FindInAddressOrder( &aObserver ); |
|
295 if ( index != KErrNotFound ) |
|
296 { |
|
297 DLTRACE(("Removing observer")); |
|
298 iObservers.Remove( index ); |
|
299 return ETrue; |
|
300 } |
|
301 DLTRACE(("Observer didn't exist")) |
|
302 return EFalse; |
|
303 } |
|
304 |
|
305 // --------------------------------------------------------------------------- |
|
306 // From MNcdOperation |
|
307 // Operation type getter |
|
308 // --------------------------------------------------------------------------- |
|
309 // |
|
310 TNcdInterfaceId CNcdDownloadOperationProxy::OperationType() const |
|
311 { |
|
312 return static_cast<TNcdInterfaceId>(MNcdDownloadOperation::KInterfaceUid); |
|
313 } |
|
314 |
|
315 |
|
316 // --------------------------------------------------------------------------- |
|
317 // Download type getter |
|
318 // --------------------------------------------------------------------------- |
|
319 // |
|
320 TNcdDownloadDataType CNcdDownloadOperationProxy::DownloadDataType() const |
|
321 { |
|
322 return iDownloadType; |
|
323 } |
|
324 |
|
325 |
|
326 // --------------------------------------------------------------------------- |
|
327 // Constructor |
|
328 // --------------------------------------------------------------------------- |
|
329 // |
|
330 CNcdDownloadOperationProxy::CNcdDownloadOperationProxy( |
|
331 TNcdDownloadDataType aDownloadType, |
|
332 TInt aDownloadIndex ) |
|
333 : CNcdOperation< MNcdDownloadOperation >( NULL ), iDownloadType( aDownloadType ), |
|
334 iFileCount( 1 ), iCurrentFile( aDownloadIndex + 1 ), iIsPaused( EFalse ) |
|
335 { |
|
336 } |
|
337 |
|
338 |
|
339 |
|
340 // --------------------------------------------------------------------------- |
|
341 // Destructor |
|
342 // --------------------------------------------------------------------------- |
|
343 // |
|
344 CNcdDownloadOperationProxy::~CNcdDownloadOperationProxy() |
|
345 { |
|
346 DLTRACEIN(( "this: %X", this )); |
|
347 iObservers.Close(); |
|
348 DASSERT( iRemoveHandler ); |
|
349 DLTRACE(("Removing proxy from remove handler")); |
|
350 if ( iRemoveHandler ) |
|
351 iRemoveHandler->RemoveOperationProxy( *this ); |
|
352 |
|
353 DLTRACEOUT(( "" )); |
|
354 } |
|
355 |
|
356 |
|
357 // --------------------------------------------------------------------------- |
|
358 // ConstructL |
|
359 // --------------------------------------------------------------------------- |
|
360 // |
|
361 void CNcdDownloadOperationProxy::ConstructL( MCatalogsClientServer& aSession, |
|
362 TInt aHandle, |
|
363 MNcdOperationProxyRemoveHandler* aRemoveHandler, |
|
364 CNcdNodeProxy* aNode, |
|
365 MNcdDownloadOperationObserver* aObserver, |
|
366 CNcdNodeManagerProxy* aNodeManager, |
|
367 TBool aIsRunning ) |
|
368 { |
|
369 DLTRACEIN( ( "this: %X", this ) ); |
|
370 CNcdBaseOperationProxy::ConstructL( aSession, aHandle, aRemoveHandler, |
|
371 aNode, aNodeManager ); |
|
372 |
|
373 if ( aObserver ) |
|
374 { |
|
375 AddObserverL( *aObserver ); |
|
376 } |
|
377 |
|
378 TNcdSendableProgress& sendableProgress( SendableProgress() ); |
|
379 sendableProgress.iMaxProgress = 1; |
|
380 |
|
381 // Initialize the operation |
|
382 InitializeOperationL(); |
|
383 if ( aIsRunning ) |
|
384 { |
|
385 DLTRACE(("Setting state as EStateRunning")); |
|
386 SetState( EStateRunning ); |
|
387 iIsPaused = ETrue; |
|
388 } |
|
389 |
|
390 DLTRACEOUT( ( "" ) ); |
|
391 } |
|
392 |
|
393 |
|
394 // --------------------------------------------------------------------------- |
|
395 // Handle progress callback |
|
396 // --------------------------------------------------------------------------- |
|
397 // |
|
398 void CNcdDownloadOperationProxy::ProgressCallback() |
|
399 { |
|
400 DLTRACEIN( ( "this: %X", this ) ); |
|
401 TNcdSendableProgress& sendableProgress( SendableProgress() ); |
|
402 TNcdProgress progress( sendableProgress.iProgress, |
|
403 sendableProgress.iMaxProgress ); |
|
404 |
|
405 iCurrentFile = sendableProgress.iState; |
|
406 iFileCount = sendableProgress.iOperationId; |
|
407 |
|
408 DLTRACE(("Progress: %d/%d", sendableProgress.iProgress, |
|
409 sendableProgress.iMaxProgress )); |
|
410 |
|
411 AddRef(); |
|
412 // Iterate backwards in case observers want to remove themselves |
|
413 // from observers during callback |
|
414 for ( TInt i = iObservers.Count() - 1; i >= 0; --i ) |
|
415 { |
|
416 DLTRACE(("Calling observer")); |
|
417 iObservers[i]->DownloadProgress( *this, progress ); |
|
418 } |
|
419 Release(); |
|
420 DLTRACEOUT( ( "" ) ); |
|
421 } |
|
422 |
|
423 |
|
424 // --------------------------------------------------------------------------- |
|
425 // Handle query received callback |
|
426 // --------------------------------------------------------------------------- |
|
427 // |
|
428 void CNcdDownloadOperationProxy::QueryReceivedCallback( CNcdQuery* /*aQuery*/ ) |
|
429 { |
|
430 DLTRACEIN( ( "" ) ); |
|
431 } |
|
432 |
|
433 |
|
434 // --------------------------------------------------------------------------- |
|
435 // Handle operation complete |
|
436 // --------------------------------------------------------------------------- |
|
437 // |
|
438 void CNcdDownloadOperationProxy::CompleteCallback( TInt aError ) |
|
439 { |
|
440 DLTRACEIN( ( "Error: %d, this: %X", aError, this ) ); |
|
441 AddRef(); |
|
442 iIsPaused = EFalse; |
|
443 |
|
444 if ( aError == KErrNone ) |
|
445 { |
|
446 iCurrentFile = iFileCount; |
|
447 } |
|
448 |
|
449 if ( DownloadDataType() == ENcdContentDownload ) |
|
450 { |
|
451 // The download operation for the purchased content has completed. |
|
452 // Update the error code and operation time into the purchase history. |
|
453 DLINFO(("Update purchase history")); |
|
454 TRAP_IGNORE( UpdateOperationInfoToPurchaseHistoryL( aError ) ); |
|
455 |
|
456 // If no errors occurred during operation, then internalize the node. |
|
457 if ( aError == KErrNone ) |
|
458 { |
|
459 DLTRACE(("Updating related nodes")); |
|
460 TRAP_IGNORE( NodeManager()->InternalizeRelatedNodesL( *NodeProxy() ) ); |
|
461 DLTRACE(("Node updated")); |
|
462 } |
|
463 } |
|
464 |
|
465 DLTRACE(("Calling observers, count: %d", iObservers.Count() )); |
|
466 // Iterate backwards in case observers want to remove themselves |
|
467 // from observers during callback |
|
468 for ( TInt i = iObservers.Count() - 1; i >= 0; --i ) |
|
469 { |
|
470 iObservers[i]->OperationComplete( *this, aError ); |
|
471 } |
|
472 DLTRACE(("Observers handled, this: %X", this)); |
|
473 Release(); |
|
474 DLTRACEOUT( ( "" ) ); |
|
475 } |
|
476 |
|
477 |
|
478 // --------------------------------------------------------------------------- |
|
479 // Create initialization data sent to the server-side |
|
480 // --------------------------------------------------------------------------- |
|
481 // |
|
482 HBufC8* CNcdDownloadOperationProxy::CreateInitializationBufferL() |
|
483 { |
|
484 DLTRACEIN(("")); |
|
485 return KNullDesC8().AllocL(); |
|
486 } |
|
487 |
|
488 |
|
489 // --------------------------------------------------------------------------- |
|
490 // Handle initialization callback |
|
491 // --------------------------------------------------------------------------- |
|
492 // |
|
493 void CNcdDownloadOperationProxy::InitializationCallback( |
|
494 RReadStream& aReadStream, TInt /*aDataLength*/ ) |
|
495 { |
|
496 DLTRACEIN( ( "" ) ); |
|
497 TRAP_IGNORE( |
|
498 { |
|
499 iCurrentFile = 1; |
|
500 // Read file count from the stream |
|
501 iFileCount = aReadStream.ReadInt32L(); |
|
502 iIsPaused = aReadStream.ReadInt32L(); |
|
503 }); |
|
504 DLTRACEOUT(( "%d files, paused: %d", iFileCount, iIsPaused )); |
|
505 } |
|
506 |
|
507 |
|
508 void CNcdDownloadOperationProxy::DoCancel() |
|
509 { |
|
510 DLTRACEIN( ( "" ) ); |
|
511 // Let's internalize the node in cases of content download. |
|
512 // This is needed for example in the following case: |
|
513 // Cancel occurs when download notification is being sent to |
|
514 // server. The content info has already been saved to purchase |
|
515 // history. To enable retry of get after this cancellation |
|
516 // the node information has to be transported from the |
|
517 // server side to proxy side. This is done with internalize. |
|
518 // Redownload from the actual server is not possible as it |
|
519 // may have already received the installation confirmation. |
|
520 if ( DownloadDataType() == ENcdContentDownload ) |
|
521 { |
|
522 DLINFO(("Internalizing node in content download cancellation.")); |
|
523 // NOTICE: It is chosen that if the internalization fails then |
|
524 // no error message is shown to user. This is because the |
|
525 // cancellation can still be successfull and then it would be a |
|
526 // bit misleading to show that the cancellation has failed. One |
|
527 // possibility could be that in case of error the cancellation |
|
528 // could be aborted, but it is probably more important to |
|
529 // try the cancel than abort and show correct message. |
|
530 // If the error message should still be shown, then this |
|
531 // internalization should probably be done elsewhere. |
|
532 // If this fails, then the outcome can be that the user |
|
533 // cannot use option Get before the node is reinternalized. |
|
534 // (This seems to happen with current implementation for example |
|
535 // by pressing Back and re-entering the same folder) |
|
536 |
|
537 // The download operation for the purchased content has completed. |
|
538 // Update the error code and operation time into the purchase history. |
|
539 DLINFO(("Update purchase history with cancel")); |
|
540 TRAP_IGNORE( UpdateOperationInfoToPurchaseHistoryL( KErrCancel ) ); |
|
541 |
|
542 DLINFO(("Updating related nodes")); |
|
543 TRAP_IGNORE( NodeManager()->InternalizeRelatedNodesL( *NodeProxy() ) ); |
|
544 |
|
545 DLINFO(("Node updated")); |
|
546 } |
|
547 |
|
548 CNcdBaseOperationProxy::DoCancel(); |
|
549 } |