|
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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32base.h> |
|
20 |
|
21 #include "ncdnodepurchaseproxy.h" |
|
22 |
|
23 #include "ncdpurchaseoptionproxy.h" |
|
24 #include "ncdpurchaseoperationproxy.h" |
|
25 #include "ncdsubscriptionmanagerproxy.h" |
|
26 #include "ncdclientpartofsubscription.h" |
|
27 #include "ncdclientsubscribablecontent.h" |
|
28 #include "ncdnodemanagerproxy.h" |
|
29 |
|
30 #include "ncdnodeproxy.h" |
|
31 #include "ncdnodemetadataproxy.h" |
|
32 #include "ncdoperationmanagerproxy.h" |
|
33 #include "ncdoperationimpl.h" |
|
34 #include "catalogsclientserver.h" |
|
35 #include "ncdnodeidentifier.h" |
|
36 #include "ncdnodefunctionids.h" |
|
37 #include "ncdnodeclassids.h" |
|
38 #include "catalogsinterfaceidentifier.h" |
|
39 #include "catalogsutils.h" |
|
40 #include "catalogsdebug.h" |
|
41 #include "catalogsconstants.h" |
|
42 #include "ncderrors.h" |
|
43 |
|
44 |
|
45 // ======== MEMBER FUNCTIONS ======== |
|
46 |
|
47 |
|
48 CNcdNodePurchaseProxy::CNcdNodePurchaseProxy( |
|
49 MCatalogsClientServer& aSession, |
|
50 TInt aHandle, |
|
51 CNcdNodeMetadataProxy& aMetadata ) |
|
52 : CNcdInterfaceBaseProxy( aSession, aHandle, &aMetadata ), |
|
53 iMetadata( aMetadata ) |
|
54 { |
|
55 // This would be faster in the construct list but because |
|
56 // resetting is needed also elsewhere it is better to keep |
|
57 // the reset values only in one place. |
|
58 ResetHistoryData(); |
|
59 } |
|
60 |
|
61 void CNcdNodePurchaseProxy::ConstructL() |
|
62 { |
|
63 DLTRACEIN(("")); |
|
64 |
|
65 // Register the interface |
|
66 MNcdNodePurchase* purchase( this ); |
|
67 AddInterfaceL( CCatalogsInterfaceIdentifier::NewL( |
|
68 purchase, |
|
69 this, |
|
70 MNcdNodePurchase::KInterfaceUid ) ); |
|
71 // Try to internalize already here. And if it fails, |
|
72 // then let it leave. |
|
73 InternalizeL(); |
|
74 |
|
75 DLTRACEOUT(("Success. Options: %d", iPurchaseOptions.Count())); |
|
76 } |
|
77 |
|
78 |
|
79 CNcdNodePurchaseProxy* CNcdNodePurchaseProxy::NewL( |
|
80 MCatalogsClientServer& aSession, |
|
81 TInt aHandle, |
|
82 CNcdNodeMetadataProxy& aMetadata ) |
|
83 { |
|
84 CNcdNodePurchaseProxy* self = |
|
85 CNcdNodePurchaseProxy::NewLC( aSession, |
|
86 aHandle, |
|
87 aMetadata ); |
|
88 CleanupStack::Pop( self ); |
|
89 return self; |
|
90 } |
|
91 |
|
92 |
|
93 CNcdNodePurchaseProxy* CNcdNodePurchaseProxy::NewLC( |
|
94 MCatalogsClientServer& aSession, |
|
95 TInt aHandle, |
|
96 CNcdNodeMetadataProxy& aMetadata ) |
|
97 { |
|
98 CNcdNodePurchaseProxy* self = |
|
99 new( ELeave ) CNcdNodePurchaseProxy( aSession, |
|
100 aHandle, |
|
101 aMetadata ); |
|
102 // Using PushL because the object does not have any references yet |
|
103 CleanupStack::PushL( self ); |
|
104 self->ConstructL(); |
|
105 return self; |
|
106 } |
|
107 |
|
108 |
|
109 CNcdNodePurchaseProxy::~CNcdNodePurchaseProxy() |
|
110 { |
|
111 DLTRACEIN(("")); |
|
112 // Remove interfaces implemented by this class from the interface list. |
|
113 // So, the interface list is up to date when this class object is deleted. |
|
114 RemoveInterface( MNcdNodePurchase::KInterfaceUid ); |
|
115 |
|
116 delete iSubscribableContent; |
|
117 iSubscribableContent = NULL; |
|
118 |
|
119 // When purchase is destroyed, also purchaseoptions go |
|
120 // with it if no references are left to them. |
|
121 DeletePurchaseOptions(); |
|
122 |
|
123 ResetHistoryData(); |
|
124 |
|
125 DLTRACEOUT(("")); |
|
126 } |
|
127 |
|
128 void CNcdNodePurchaseProxy::InternalizeL() |
|
129 { |
|
130 DLTRACEIN(("")); |
|
131 |
|
132 TRAPD( error, |
|
133 { |
|
134 InternalizeMeansL(); |
|
135 InternalizeHistoryL(); |
|
136 } ); |
|
137 if ( error != KErrNone ) |
|
138 { |
|
139 DLERROR(("Purchase internalize error")); |
|
140 // Because we can't fully construct the purchase info, |
|
141 // we don't give even parts of info to the user because it could |
|
142 // be misleading. |
|
143 DeletePurchaseOptions(); |
|
144 ResetHistoryData(); |
|
145 User::Leave( error ); |
|
146 } |
|
147 DLTRACEOUT(("")); |
|
148 } |
|
149 |
|
150 |
|
151 void CNcdNodePurchaseProxy::InternalizeMeansL() |
|
152 { |
|
153 DLTRACEIN(("")); |
|
154 |
|
155 // Request the purchase option ids from server side |
|
156 CDesCArray* poIds = RequestPurchaseOptionIdsL(); |
|
157 CleanupStack::PushL( poIds ); |
|
158 |
|
159 // Delete purchase options that don't exist in server side. |
|
160 ReleaseMissingPurchaseOptions( *poIds ); |
|
161 |
|
162 // Reinternalize purchase options that existed already. |
|
163 InternalizeExistingPurchaseOptionsL(); |
|
164 |
|
165 // Create purchase options that exists in the server side but not |
|
166 // in proxy side. |
|
167 CDesCArray* newPurchaseOptions = new( ELeave ) CDesCArrayFlat( 5 ); |
|
168 CleanupStack::PushL( newPurchaseOptions ); |
|
169 |
|
170 // Find the purchase options that don't exist in the proxy side. |
|
171 for ( TInt i = 0; i < poIds->Count(); i++ ) |
|
172 { |
|
173 TPtrC id = (*poIds)[i]; |
|
174 if ( !HasPurchaseOption( id ) ) |
|
175 { |
|
176 newPurchaseOptions->AppendL( id ); |
|
177 } |
|
178 } |
|
179 |
|
180 InternalizeMeansL( *newPurchaseOptions ); |
|
181 CleanupStack::PopAndDestroy( newPurchaseOptions ); |
|
182 newPurchaseOptions = NULL; |
|
183 CleanupStack::PopAndDestroy( poIds ); |
|
184 poIds = NULL; |
|
185 |
|
186 DLTRACEOUT(("")); |
|
187 } |
|
188 |
|
189 |
|
190 void CNcdNodePurchaseProxy::InternalizeHistoryL() |
|
191 { |
|
192 DLTRACEIN(("")); |
|
193 |
|
194 HBufC8* data( NULL ); |
|
195 |
|
196 // Because we do not know the exact size of the data id, use |
|
197 // the alloc method, which creates the buffer of the right size |
|
198 // and sets the pointer to point to the created buffer. |
|
199 User::LeaveIfError( |
|
200 ClientServerSession(). |
|
201 SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalizePurchaseHistory, |
|
202 KNullDesC8, |
|
203 data, |
|
204 Metadata().Handle(), |
|
205 0 ) ); |
|
206 |
|
207 if ( data == NULL ) |
|
208 { |
|
209 User::Leave( KErrNotFound ); |
|
210 } |
|
211 |
|
212 CleanupStack::PushL( data ); |
|
213 |
|
214 |
|
215 // Read the data from the stream |
|
216 RDesReadStream stream( *data ); |
|
217 CleanupClosePushL( stream ); |
|
218 |
|
219 TRAPD( error, InternalizeHistoryDataL( stream ) ); |
|
220 if ( error != KErrNone ) |
|
221 { |
|
222 User::Leave( error ); |
|
223 } |
|
224 |
|
225 // Closes the stream |
|
226 CleanupStack::PopAndDestroy( &stream ); |
|
227 CleanupStack::PopAndDestroy( data ); |
|
228 |
|
229 DLTRACEOUT(("")); |
|
230 } |
|
231 |
|
232 CNcdNodeMetadataProxy& CNcdNodePurchaseProxy::Metadata() const |
|
233 { |
|
234 return iMetadata; |
|
235 } |
|
236 |
|
237 const CNcdClientSubscribableContent* |
|
238 CNcdNodePurchaseProxy::SubscribableContent() const |
|
239 { |
|
240 DLTRACEIN(("")); |
|
241 DLTRACEOUT(("")); |
|
242 return iSubscribableContent; |
|
243 } |
|
244 |
|
245 |
|
246 |
|
247 // --------------------------------------------------------------------------- |
|
248 // From class MNcdNodePurchase. |
|
249 // In this function we return purchaseoptions to ui that are available for |
|
250 // the client at the moment. |
|
251 // --------------------------------------------------------------------------- |
|
252 // |
|
253 RCatalogsArray<MNcdPurchaseOption> |
|
254 CNcdNodePurchaseProxy::PurchaseOptionsL() const |
|
255 { |
|
256 DLTRACEIN(( "" )); |
|
257 |
|
258 RCatalogsArray<MNcdPurchaseOption> options; |
|
259 |
|
260 // in case of leave, destroy its contents (release) |
|
261 CleanupResetAndDestroyPushL( options ); |
|
262 |
|
263 |
|
264 TInt optionsCount( iPurchaseOptions.Count() ); |
|
265 TInt optionsIndexer( 0 ); |
|
266 while ( optionsIndexer < optionsCount ) |
|
267 { |
|
268 DASSERT( iPurchaseOptions[optionsIndexer] ); |
|
269 |
|
270 // Purchaseoption that we handle at the moment |
|
271 CNcdPurchaseOptionProxy* purchaseOption = |
|
272 iPurchaseOptions[optionsIndexer]; |
|
273 |
|
274 // Type of the purchaseoption |
|
275 MNcdPurchaseOption::TType purchaseoptionType = |
|
276 purchaseOption->PurchaseOptionType(); |
|
277 |
|
278 // dataentity to whome the purchaseoption belongs to |
|
279 CNcdNodeMetadataProxy& meta = |
|
280 purchaseOption->ParentNodePurchase()->Metadata(); |
|
281 |
|
282 |
|
283 |
|
284 // NOTICE: At the moment this function does not take into count |
|
285 // situations where purchaseoption could be of several |
|
286 // types like ESubscription and ESubscriptionPurchase |
|
287 |
|
288 |
|
289 // Can purchase of the item be done if it is already |
|
290 // purchased? |
|
291 |
|
292 |
|
293 if ( purchaseoptionType == MNcdPurchaseOption::EPurchase ) |
|
294 { |
|
295 |
|
296 // Should check if parentfolder has separately purchaseable |
|
297 // false and if it has then do not show normal purchase |
|
298 // purchaseoptions to ui |
|
299 |
|
300 options.AppendL( purchaseOption ); |
|
301 TInt ref = purchaseOption->AddRef(); |
|
302 DLTRACE(("Purchase option ref count after addref: %d", ref)); |
|
303 } |
|
304 else if ( purchaseoptionType == |
|
305 MNcdPurchaseOption::ESubscriptionPurchase ) |
|
306 { |
|
307 // Part of subscription -type purchaseoptions are |
|
308 // always shown to ui |
|
309 options.AppendL( purchaseOption ); |
|
310 purchaseOption->AddRef(); |
|
311 } |
|
312 else if ( purchaseoptionType == |
|
313 MNcdPurchaseOption::ESubscription ) |
|
314 { |
|
315 // If this subscription is already bought, we can't show |
|
316 // it to ui. |
|
317 |
|
318 TBool isBought = |
|
319 Metadata().Node().NodeManager(). |
|
320 SubscriptionManager(). |
|
321 ActiveSubscriptionExists( meta.Id(), |
|
322 meta.Namespace(), |
|
323 purchaseOption->Id() ); |
|
324 |
|
325 if ( !isBought ) |
|
326 { |
|
327 options.AppendL( purchaseOption ); |
|
328 purchaseOption->AddRef(); |
|
329 } |
|
330 } |
|
331 else if ( purchaseoptionType == |
|
332 MNcdPurchaseOption::ESubscriptionUpgrade ) |
|
333 { |
|
334 // If target of the purchaseoption is not bought, upgrade |
|
335 // cannot be used |
|
336 if ( purchaseOption->IsUsableL() ) |
|
337 { |
|
338 options.AppendL( purchaseOption ); |
|
339 purchaseOption->AddRef(); |
|
340 } |
|
341 } |
|
342 else |
|
343 { |
|
344 // Not supported |
|
345 DASSERT( false ); |
|
346 } |
|
347 |
|
348 ++optionsIndexer; |
|
349 } |
|
350 |
|
351 |
|
352 CleanupStack::Pop( &options ); |
|
353 |
|
354 DLTRACEOUT(( "" )); |
|
355 return options; |
|
356 } |
|
357 |
|
358 // --------------------------------------------------------------------------- |
|
359 // From class MNcdNodePurchase. |
|
360 // ?implementation_description |
|
361 // --------------------------------------------------------------------------- |
|
362 // |
|
363 MNcdPurchaseOption* CNcdNodePurchaseProxy::PurchaseOptionL( |
|
364 const TDesC& aPurchaseOptionId ) const |
|
365 { |
|
366 DLTRACEIN(("")); |
|
367 TInt optionsCount( iPurchaseOptions.Count() ); |
|
368 TInt optionsIndexer( 0 ); |
|
369 while ( optionsIndexer < optionsCount ) |
|
370 { |
|
371 DASSERT( iPurchaseOptions[optionsIndexer] ); |
|
372 |
|
373 if ( iPurchaseOptions[optionsIndexer]->Id() == aPurchaseOptionId ) |
|
374 { |
|
375 iPurchaseOptions[optionsIndexer]->AddRef(); |
|
376 |
|
377 DLTRACEOUT(( "" )); |
|
378 return iPurchaseOptions[optionsIndexer]; |
|
379 } |
|
380 |
|
381 ++optionsIndexer; |
|
382 } |
|
383 |
|
384 DLTRACEOUT(( "" )); |
|
385 return NULL; |
|
386 } |
|
387 |
|
388 |
|
389 // --------------------------------------------------------------------------- |
|
390 // From class MNcdNodePurchase. |
|
391 // Notice that this function accepts purchase options also from other nodes |
|
392 // than into which this interface belongs to. Could be changed to accept |
|
393 // only purchase options from this interface, but at the moment UI |
|
394 // does not permit this in case of subscription. |
|
395 // --------------------------------------------------------------------------- |
|
396 // |
|
397 MNcdPurchaseOperation* CNcdNodePurchaseProxy::PurchaseL( |
|
398 MNcdPurchaseOption& aPurchaseOption, |
|
399 MNcdPurchaseOperationObserver& aObserver ) |
|
400 { |
|
401 DLTRACEIN(("")); |
|
402 |
|
403 |
|
404 CNcdPurchaseOperationProxy* operation( NULL ); |
|
405 |
|
406 CNcdPurchaseOptionProxy& option = |
|
407 *static_cast<CNcdPurchaseOptionProxy*>( &aPurchaseOption ); |
|
408 |
|
409 |
|
410 // Given purchaseoption is old and should not be used anymore |
|
411 if ( option.IsObsolete() ) |
|
412 { |
|
413 User::Leave( KNcdErrorObsolete ); |
|
414 } |
|
415 |
|
416 |
|
417 // Now if validuntil for subscription has passed, we should not allow it |
|
418 // to be bought anymore |
|
419 if ( option.PurchaseOptionType() == MNcdPurchaseOption::ESubscription ) |
|
420 { |
|
421 TTime now; |
|
422 now.HomeTime(); |
|
423 |
|
424 // The time until the node is subscribable is stored in the |
|
425 // subscribable content of the NodePurchase interface where to |
|
426 // the GIVEN PURCHASEOPTION belongs to. |
|
427 const CNcdClientSubscribableContent* subscribableContent = |
|
428 option.ParentNodePurchase()->SubscribableContent(); |
|
429 |
|
430 DASSERT( subscribableContent ); |
|
431 if ( subscribableContent && |
|
432 subscribableContent->ValidUntilSet() && |
|
433 now > subscribableContent->ValidUntil() ) |
|
434 { |
|
435 User::Leave( KNcdErrorSubscriptionNotSubscribableAnymore ); |
|
436 } |
|
437 |
|
438 } |
|
439 |
|
440 |
|
441 DLTRACE(( _L("Purchase started with option whose name is: %S"), |
|
442 &option.Name() )); |
|
443 |
|
444 |
|
445 // NOTICE: In the case of subscription or upgrade the purchaseoption |
|
446 // can be from another node. That is why we give |
|
447 // node-reference from the purchaseoption. |
|
448 operation = |
|
449 Metadata().Node().OperationManager(). |
|
450 CreatePurchaseOperationL( option.ParentNodePurchase()->Metadata().Node(), |
|
451 option, |
|
452 &aObserver ); |
|
453 |
|
454 // It is enough that the observer is informed |
|
455 // when the file operation is ready. So, no need to add |
|
456 // node or this class object to be observers. |
|
457 |
|
458 // No need to increase the operation ref count here because |
|
459 // it should be initially one. |
|
460 |
|
461 DLTRACEOUT(("")); |
|
462 |
|
463 return operation; |
|
464 } |
|
465 |
|
466 // --------------------------------------------------------------------------- |
|
467 // From class MNcdNodePurchase. |
|
468 // ?implementation_description |
|
469 // --------------------------------------------------------------------------- |
|
470 // |
|
471 TBool CNcdNodePurchaseProxy::IsPurchased() const |
|
472 { |
|
473 return iIsPurchased; |
|
474 } |
|
475 |
|
476 |
|
477 // --------------------------------------------------------------------------- |
|
478 // From class MNcdNodePurchase. |
|
479 // ?implementation_description |
|
480 // --------------------------------------------------------------------------- |
|
481 // |
|
482 MNcdPurchaseOption* CNcdNodePurchaseProxy::PurchasedOptionL() const |
|
483 { |
|
484 if ( !IsPurchased() ) |
|
485 { |
|
486 return NULL; |
|
487 } |
|
488 |
|
489 return PurchaseOptionL( *iPurchasedOptionId ); |
|
490 } |
|
491 |
|
492 // --------------------------------------------------------------------------- |
|
493 // From class MNcdNodePurchase. |
|
494 // ?implementation_description |
|
495 // --------------------------------------------------------------------------- |
|
496 // |
|
497 TTime CNcdNodePurchaseProxy::TimeOfPurchaseL() const |
|
498 { |
|
499 if ( !IsPurchased() ) |
|
500 { |
|
501 User::Leave( KErrNotFound ); |
|
502 } |
|
503 |
|
504 return iTimeOfPurchase; |
|
505 } |
|
506 |
|
507 // --------------------------------------------------------------------------- |
|
508 // From class MNcdNodePurchase. |
|
509 // ?implementation_description |
|
510 // --------------------------------------------------------------------------- |
|
511 // |
|
512 const TDesC& CNcdNodePurchaseProxy::PurchasedPriceL() const |
|
513 { |
|
514 if ( !IsPurchased() ) |
|
515 { |
|
516 User::Leave( KErrNotFound ); |
|
517 } |
|
518 |
|
519 return *iPurchasedPrice; |
|
520 } |
|
521 |
|
522 |
|
523 void CNcdNodePurchaseProxy::InternalizeMeansDataL( RReadStream& aStream ) |
|
524 { |
|
525 DLTRACEIN(("")); |
|
526 |
|
527 // Subscribable content is read into its own class |
|
528 TBool subscribableContentFound( aStream.ReadInt32L() ); |
|
529 if ( subscribableContentFound ) |
|
530 { |
|
531 if ( iSubscribableContent == NULL ) |
|
532 { |
|
533 iSubscribableContent = CNcdClientSubscribableContent::NewL(); |
|
534 } |
|
535 iSubscribableContent->InternalizeL( aStream ); |
|
536 } |
|
537 |
|
538 |
|
539 TInt handleCount = aStream.ReadInt32L(); |
|
540 DLINFO((( "handle count: %d" ), handleCount )); |
|
541 |
|
542 for ( TInt i = 0; i < handleCount; i++ ) |
|
543 { |
|
544 TInt tmpProxyHandle = aStream.ReadInt32L(); |
|
545 CNcdPurchaseOptionProxy* tmpPurchaseOption = |
|
546 CNcdPurchaseOptionProxy::NewLC( |
|
547 ClientServerSession(), |
|
548 tmpProxyHandle, |
|
549 *this ); |
|
550 |
|
551 TRAPD( addError, iPurchaseOptions.AppendL( tmpPurchaseOption ) ); |
|
552 if ( addError != KErrNone ) |
|
553 { |
|
554 CleanupStack::PopAndDestroy( tmpPurchaseOption ); |
|
555 User::Leave( addError ); |
|
556 } |
|
557 |
|
558 CleanupStack::Pop( tmpPurchaseOption ); |
|
559 tmpPurchaseOption->InternalizeL(); |
|
560 } |
|
561 |
|
562 DLTRACEOUT(("")); |
|
563 } |
|
564 |
|
565 |
|
566 void CNcdNodePurchaseProxy::InternalizeHistoryDataL( RReadStream& aStream ) |
|
567 { |
|
568 DLTRACEIN(("")); |
|
569 |
|
570 // Reset values so that if we receive message that for some reason |
|
571 // does not contain purchase history info, we don't keep the old |
|
572 // purchase history info in memory. |
|
573 ResetHistoryData(); |
|
574 |
|
575 // Node class id. Not actually needed. |
|
576 aStream.ReadInt32L(); |
|
577 |
|
578 |
|
579 iIsPurchased = aStream.ReadInt32L(); |
|
580 if ( iIsPurchased == EFalse ) |
|
581 { |
|
582 return; |
|
583 } |
|
584 |
|
585 InternalizeDesL( iPurchasedOptionId, aStream ); |
|
586 |
|
587 TInt64 integerTimeOfPurchase( 0 ); |
|
588 // Store framework provides the necessary implementation for |
|
589 // the operator>> to internalise the 64-bit integer |
|
590 aStream >> integerTimeOfPurchase; |
|
591 iTimeOfPurchase = TTime( integerTimeOfPurchase ); |
|
592 |
|
593 InternalizeDesL( iPurchasedPrice, aStream ); |
|
594 |
|
595 |
|
596 DLTRACEOUT(("")); |
|
597 } |
|
598 |
|
599 |
|
600 void CNcdNodePurchaseProxy::DeletePurchaseOptions() |
|
601 { |
|
602 DLTRACEIN(("Handling %d purchase options", iPurchaseOptions.Count() )); |
|
603 for ( TInt i = iPurchaseOptions.Count() - 1; i >= 0; --i ) |
|
604 { |
|
605 CNcdPurchaseOptionProxy* tmpOption = iPurchaseOptions[i]; |
|
606 |
|
607 if ( tmpOption->MyTotalRefCount() > 0 ) |
|
608 { |
|
609 // to prevent loops remove purchaseoption first |
|
610 // so it won't become deleted |
|
611 iPurchaseOptions.Remove( i ); |
|
612 |
|
613 tmpOption->SetObsolete(); |
|
614 // Remove the purchase option from the interface parent. |
|
615 // This will update the parent reference count. |
|
616 // Because purchase option does not provide any interfaces for |
|
617 // the parent, it is safe to use this function. |
|
618 tmpOption->RemoveFromParent(); |
|
619 if ( tmpOption->TotalRefCount() == 0 ) |
|
620 { |
|
621 DLINFO(("Purchase option can be deleted here.")); |
|
622 delete tmpOption; |
|
623 } |
|
624 } |
|
625 } |
|
626 DLTRACE(("Deleting %d purchase options", iPurchaseOptions.Count() )); |
|
627 iPurchaseOptions.ResetAndDestroy(); |
|
628 } |
|
629 |
|
630 void CNcdNodePurchaseProxy::ResetHistoryData() |
|
631 { |
|
632 iIsPurchased = EFalse; |
|
633 delete iPurchasedOptionId; |
|
634 iPurchasedOptionId = NULL; |
|
635 iTimeOfPurchase = TTime( 0 ); |
|
636 delete iPurchasedPrice; |
|
637 iPurchasedPrice = NULL; |
|
638 } |
|
639 |
|
640 CDesCArray* CNcdNodePurchaseProxy::RequestPurchaseOptionIdsL() |
|
641 { |
|
642 DLTRACEIN(("")); |
|
643 |
|
644 HBufC8* data( NULL ); |
|
645 |
|
646 // Because we do not know the exact size of the data, use |
|
647 // the alloc method, which creates the buffer of the right size |
|
648 // and sets the pointer to point to the created buffer. |
|
649 User::LeaveIfError( |
|
650 ClientServerSession(). |
|
651 SendSyncAlloc( NcdNodeFunctionIds::ENcdPurchaseOptionIds, |
|
652 KNullDesC8, |
|
653 data, |
|
654 Handle(), |
|
655 0 ) ); |
|
656 |
|
657 if ( data == NULL ) |
|
658 { |
|
659 User::Leave( KErrNotFound ); |
|
660 } |
|
661 |
|
662 CleanupStack::PushL( data ); |
|
663 |
|
664 // Read the data from the stream |
|
665 RDesReadStream stream( *data ); |
|
666 CleanupClosePushL( stream ); |
|
667 |
|
668 TInt purchaseOptionCount = stream.ReadInt32L(); |
|
669 CDesCArray* array = new( ELeave ) CDesCArrayFlat( 5 ); |
|
670 CleanupStack::PushL( array ); |
|
671 for ( TInt i = 0; i < purchaseOptionCount; i++ ) |
|
672 { |
|
673 HBufC* des( NULL ); |
|
674 InternalizeDesL( des, stream ); |
|
675 CleanupStack::PushL( des ); |
|
676 array->AppendL( *des ); |
|
677 CleanupStack::PopAndDestroy( des ); |
|
678 } |
|
679 |
|
680 CleanupStack::Pop( array ); |
|
681 CleanupStack::PopAndDestroy( &stream ); |
|
682 CleanupStack::PopAndDestroy( data ); |
|
683 |
|
684 return array; |
|
685 } |
|
686 |
|
687 void CNcdNodePurchaseProxy::ReleaseMissingPurchaseOptions( |
|
688 const CDesCArray& aPurchaseOptionIds ) |
|
689 { |
|
690 DLTRACEIN(("")); |
|
691 |
|
692 for ( TInt i = iPurchaseOptions.Count() - 1; i >= 0; i-- ) |
|
693 { |
|
694 TInt index; |
|
695 if ( aPurchaseOptionIds.Find( iPurchaseOptions[i]->Id(), index ) != 0 ) |
|
696 { |
|
697 iPurchaseOptions[i]->SetObsolete(); |
|
698 // Remove the purchase option from the interface parent. |
|
699 // This will update the parent reference count. |
|
700 // Because purchase option does not provide any interfaces for |
|
701 // the parent, it is safe to use this function. |
|
702 iPurchaseOptions[i]->RemoveFromParent(); |
|
703 if ( iPurchaseOptions[ i ]->TotalRefCount() == 0 ) |
|
704 { |
|
705 DLINFO(("Purchase option can be deleted.")); |
|
706 delete iPurchaseOptions[ i ]; |
|
707 } |
|
708 iPurchaseOptions.Remove( i ); |
|
709 } |
|
710 } |
|
711 } |
|
712 |
|
713 void CNcdNodePurchaseProxy::InternalizeExistingPurchaseOptionsL() |
|
714 { |
|
715 DLTRACEIN(("")); |
|
716 |
|
717 for ( TInt i = 0; i < iPurchaseOptions.Count(); i++ ) |
|
718 { |
|
719 iPurchaseOptions[i]->InternalizeL(); |
|
720 } |
|
721 } |
|
722 |
|
723 void CNcdNodePurchaseProxy::InternalizeMeansL( |
|
724 const CDesCArray& aPurchaseOptionIds ) |
|
725 { |
|
726 DLTRACEIN(("")); |
|
727 |
|
728 CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); |
|
729 CleanupStack::PushL( buf ); |
|
730 |
|
731 RBufWriteStream writeStream( *buf ); |
|
732 CleanupClosePushL( writeStream ); |
|
733 writeStream.WriteInt32L( aPurchaseOptionIds.Count() ); |
|
734 for ( TInt i = 0; i < aPurchaseOptionIds.Count(); i++ ) |
|
735 { |
|
736 ExternalizeDesL( aPurchaseOptionIds[i], writeStream ); |
|
737 } |
|
738 |
|
739 CleanupStack::PopAndDestroy( &writeStream ); |
|
740 HBufC8* messageToSend = HBufC8::NewL( buf->Size() ); |
|
741 messageToSend->Des().Copy( buf->Ptr( 0 ) ); |
|
742 |
|
743 CleanupStack::PopAndDestroy( buf ); |
|
744 CleanupStack::PushL( messageToSend ); |
|
745 |
|
746 // Request handles to the new purchase options. |
|
747 HBufC8* data( NULL ); |
|
748 |
|
749 // Because we do not know the exact size of the data, use |
|
750 // the alloc method, which creates the buffer of the right size |
|
751 // and sets the pointer to point to the created buffer. |
|
752 User::LeaveIfError( |
|
753 ClientServerSession(). |
|
754 SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalizePurchaseMeans, |
|
755 *messageToSend, |
|
756 data, |
|
757 Handle(), |
|
758 0 ) ); |
|
759 |
|
760 CleanupStack::PopAndDestroy( messageToSend ); |
|
761 messageToSend = NULL; |
|
762 |
|
763 if ( data == NULL ) |
|
764 { |
|
765 User::Leave( KErrNotFound ); |
|
766 } |
|
767 |
|
768 CleanupStack::PushL( data ); |
|
769 |
|
770 // Read the data from the stream |
|
771 RDesReadStream stream( *data ); |
|
772 CleanupClosePushL( stream ); |
|
773 |
|
774 InternalizeMeansDataL( stream ); |
|
775 |
|
776 CleanupStack::PopAndDestroy( &stream ); |
|
777 CleanupStack::PopAndDestroy( data ); |
|
778 } |
|
779 |
|
780 TBool CNcdNodePurchaseProxy::HasPurchaseOption( const TDesC& aId ) const |
|
781 { |
|
782 DLTRACEIN(("")); |
|
783 for ( TInt i = 0; i < iPurchaseOptions.Count(); i++ ) |
|
784 { |
|
785 if ( iPurchaseOptions[i]->Id() == aId ) |
|
786 { |
|
787 return ETrue; |
|
788 } |
|
789 } |
|
790 |
|
791 return EFalse; |
|
792 } |