|
1 /* |
|
2 * Copyright (c) 2006-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: Implements CNcdNodeUpgrade class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "ncdnodeupgradeimpl.h" |
|
20 |
|
21 #include "ncdnodemetadataimpl.h" |
|
22 #include "ncddownloadinfo.h" |
|
23 #include "catalogssession.h" |
|
24 #include "catalogsbasemessage.h" |
|
25 #include "ncdnodefunctionids.h" |
|
26 #include "ncdnodeclassids.h" |
|
27 #include "catalogsconstants.h" |
|
28 #include "ncd_pp_dataentity.h" |
|
29 #include "ncd_pp_dataentitycontent.h" |
|
30 #include "ncd_pp_entitydependency.h" |
|
31 #include "ncd_cp_query.h" |
|
32 #include "ncdnodeidentifier.h" |
|
33 #include "ncddependencyinfo.h" |
|
34 #include "catalogsutils.h" |
|
35 #include "ncderrors.h" |
|
36 #include "ncdproviderutils.h" |
|
37 #include "ncdattributes.h" |
|
38 |
|
39 #include "catalogsdebug.h" |
|
40 |
|
41 |
|
42 CNcdNodeUpgrade::CNcdNodeUpgrade( CNcdNodeMetaData& aParentMetaData, |
|
43 NcdNodeClassIds::TNcdNodeClassId aClassId ) |
|
44 : CNcdCommunicable(), |
|
45 iParentMetaData( aParentMetaData ), |
|
46 iClassId( aClassId ) |
|
47 { |
|
48 } |
|
49 |
|
50 void CNcdNodeUpgrade::ConstructL() |
|
51 { |
|
52 // These values have to be set. |
|
53 iUpgradeData = CNcdAttributes::NewL( EUpgradeDataInternal ); |
|
54 } |
|
55 |
|
56 |
|
57 CNcdNodeUpgrade* CNcdNodeUpgrade::NewL( CNcdNodeMetaData& aParentMetaData ) |
|
58 { |
|
59 CNcdNodeUpgrade* self = |
|
60 CNcdNodeUpgrade::NewLC( aParentMetaData ); |
|
61 CleanupStack::Pop( self ); |
|
62 return self; |
|
63 } |
|
64 |
|
65 CNcdNodeUpgrade* CNcdNodeUpgrade::NewLC( CNcdNodeMetaData& aParentMetaData ) |
|
66 { |
|
67 CNcdNodeUpgrade* self = |
|
68 new( ELeave ) CNcdNodeUpgrade( |
|
69 aParentMetaData, |
|
70 NcdNodeClassIds::ENcdNodeUpgradeClassId ); |
|
71 CleanupClosePushL( *self ); |
|
72 self->ConstructL(); |
|
73 return self; |
|
74 } |
|
75 |
|
76 |
|
77 CNcdNodeUpgrade::~CNcdNodeUpgrade() |
|
78 { |
|
79 DLTRACEIN(("")); |
|
80 |
|
81 // Delete member variables here |
|
82 iUpgradeNodeTargets.ResetAndDestroy(); |
|
83 iUpgradeContentTargets.ResetAndDestroy(); |
|
84 delete iUpgradeData; |
|
85 // Do not delete parent metadata because it is not owned here. |
|
86 |
|
87 DLTRACEOUT(("")); |
|
88 } |
|
89 |
|
90 |
|
91 NcdNodeClassIds::TNcdNodeClassId CNcdNodeUpgrade::ClassId() const |
|
92 { |
|
93 return iClassId; |
|
94 } |
|
95 |
|
96 |
|
97 const RPointerArray<CNcdDownloadInfo>& CNcdNodeUpgrade::ContentTargets() const |
|
98 { |
|
99 return iUpgradeContentTargets; |
|
100 } |
|
101 |
|
102 |
|
103 const RPointerArray<CNcdDependencyInfo>& CNcdNodeUpgrade::NodeTargets() const |
|
104 { |
|
105 return iUpgradeNodeTargets; |
|
106 } |
|
107 |
|
108 |
|
109 // Internalization from the protocol |
|
110 |
|
111 void CNcdNodeUpgrade::InternalizeL( |
|
112 MNcdPreminetProtocolDataEntity& aData, |
|
113 const TDesC& aVersion ) |
|
114 { |
|
115 DLTRACEIN(("")); |
|
116 |
|
117 // First create the new values |
|
118 |
|
119 // Notice that ownerships are not transferred from the parser objects. |
|
120 const MNcdPreminetProtocolDataEntityContent* downloadableContent = |
|
121 aData.DownloadableContent(); |
|
122 if ( downloadableContent == NULL ) |
|
123 { |
|
124 DLINFO(("No data present")); |
|
125 // Content data not present. |
|
126 User::Leave( KErrNotFound ); |
|
127 } |
|
128 |
|
129 // Reset the array here. |
|
130 // If something here fails after this. Then, the owner of this class object |
|
131 // should remove this class object from the metadata anyway. |
|
132 iUpgradeNodeTargets.ResetAndDestroy(); |
|
133 |
|
134 const MNcdPreminetProtocolEntityDependency* dependency( NULL ); |
|
135 CNcdNodeIdentifier* identifier( NULL ); |
|
136 CNcdDependencyInfo* upgradeInfo( NULL ); |
|
137 for ( TInt i = 0; i < downloadableContent->EntityDependencyCount(); ++i ) |
|
138 { |
|
139 // Check what nodes depend on this node. |
|
140 dependency = &downloadableContent->EntityDependencyL( i ); |
|
141 if ( dependency->Type() == EUpgradeDependency ) |
|
142 { |
|
143 // Check if the upgrade should be loaded as a node when |
|
144 // the download responsibility is transferred to the proxy side |
|
145 // or should we just download the content directly in server side. |
|
146 if ( dependency->EntityId() != KNullDesC ) |
|
147 { |
|
148 DLINFO((_L("Upgrade entity id: %S"), &dependency->EntityId())); |
|
149 // The dependecy information contains the |
|
150 // entity id of the target node. |
|
151 identifier = |
|
152 CNcdNodeIdentifier::NewL( iParentMetaData.Identifier().NodeNameSpace(), |
|
153 dependency->EntityId(), |
|
154 iParentMetaData.Identifier().ServerUri(), |
|
155 iParentMetaData.Identifier().ClientUid() ); |
|
156 // Note, that identifier ownership is transferred here. |
|
157 upgradeInfo = |
|
158 CNcdDependencyInfo::NewLC( dependency->Name(), |
|
159 aVersion, |
|
160 dependency->ContentId(), |
|
161 identifier ); |
|
162 iUpgradeNodeTargets.AppendL( upgradeInfo ); |
|
163 CleanupStack::Pop( upgradeInfo ); |
|
164 |
|
165 } |
|
166 else |
|
167 { |
|
168 // Ownership is not transferred here. |
|
169 const MNcdPreminetProtocolDownload* downloadDetails( |
|
170 dependency->DownloadDetails() ); |
|
171 if ( downloadDetails != NULL ) |
|
172 { |
|
173 DLINFO(("Download the content directly. New node will not be created.")); |
|
174 // Copy the content object and insert it into the content array. |
|
175 // The purchase operation may use the array content when checking |
|
176 // if upgrades should be downloaded and installed. |
|
177 CNcdDownloadInfo* content( |
|
178 CNcdDownloadInfo::NewLC( *dependency ) ); |
|
179 iUpgradeContentTargets.AppendL( content ); |
|
180 content->SetContentUsage( MNcdPurchaseDownloadInfo::EUpgrade ); |
|
181 // Array took ownership. So, do not delete. |
|
182 CleanupStack::Pop( content ); |
|
183 } |
|
184 } |
|
185 } |
|
186 } |
|
187 |
|
188 if ( iUpgradeNodeTargets.Count() == 0 |
|
189 && iUpgradeContentTargets.Count() == 0 ) |
|
190 { |
|
191 // No upgrade data was found. |
|
192 // So, inform about that to the owner of this class object. |
|
193 DLINFO(("No content")); |
|
194 User::Leave( KErrNotFound ); |
|
195 } |
|
196 |
|
197 DLTRACEOUT(("")); |
|
198 } |
|
199 |
|
200 |
|
201 |
|
202 TBool CNcdNodeUpgrade::AllUpgradesInstalledL() const |
|
203 { |
|
204 DLTRACEIN(("Checking %d upgrades", |
|
205 iUpgradeContentTargets.Count() )); |
|
206 |
|
207 // Check if the upgrades have already been installed |
|
208 // Note that missing app is also considered as installed because |
|
209 // we can't upgrade "nothing" :) |
|
210 for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i ) |
|
211 { |
|
212 if ( CNcdProviderUtils::IsApplicationInstalledL( |
|
213 iUpgradeContentTargets[i]->ContentId(), |
|
214 iUpgradeContentTargets[i]->ContentVersion() ) |
|
215 == ENcdApplicationOlderVersionInstalled ) |
|
216 { |
|
217 DLTRACEOUT(("All upgrades have not been installed yet")); |
|
218 return EFalse; |
|
219 } |
|
220 } |
|
221 |
|
222 // Check if the upgrades have already been installed |
|
223 for ( TInt i = 0; i < iUpgradeNodeTargets.Count(); ++i ) |
|
224 { |
|
225 if ( CNcdProviderUtils::IsApplicationInstalledL( |
|
226 iUpgradeNodeTargets[i]->Uid(), |
|
227 iUpgradeNodeTargets[i]->Version() ) |
|
228 == ENcdApplicationOlderVersionInstalled ) |
|
229 { |
|
230 DLTRACEOUT(("All upgrade node contents have not been installed yet")); |
|
231 return EFalse; |
|
232 } |
|
233 } |
|
234 |
|
235 DLTRACEOUT(("All upgrades have been installed")); |
|
236 return ETrue; |
|
237 } |
|
238 |
|
239 |
|
240 void CNcdNodeUpgrade::SetContentUpgradesL( |
|
241 TBool aContentUpgrades, |
|
242 const TUid& aUid, |
|
243 const TDesC& aVersion ) |
|
244 { |
|
245 DLTRACEIN(("aContentUpgrades = %d", aContentUpgrades )); |
|
246 iContentUpgrades = aContentUpgrades; |
|
247 |
|
248 iUpgradeData->SetAttributeL( EUpgradeDataVersion, aVersion ); |
|
249 iUpgradeData->SetAttributeL( EUpgradeDataUid, aUid.iUid ); |
|
250 |
|
251 } |
|
252 |
|
253 TBool CNcdNodeUpgrade::ContentUpgrades() const |
|
254 { |
|
255 DLTRACEIN(("ContentUpgrades: %d", iContentUpgrades)); |
|
256 return iContentUpgrades; |
|
257 } |
|
258 |
|
259 |
|
260 // Internalization from and externalization to the database |
|
261 |
|
262 void CNcdNodeUpgrade::ExternalizeL( RWriteStream& aStream ) |
|
263 { |
|
264 DLTRACEIN(("")); |
|
265 |
|
266 // The upgrade may be provided even if arrays are empty if |
|
267 // the content upgrade flag is set. |
|
268 if ( iUpgradeNodeTargets.Count() == 0 |
|
269 && iUpgradeContentTargets.Count() == 0 |
|
270 && !ContentUpgrades() ) |
|
271 { |
|
272 DLERROR(("No content")); |
|
273 DASSERT( EFalse ); |
|
274 User::Leave( KErrNotFound ); |
|
275 } |
|
276 |
|
277 // First insert data that the creator of this class object will use to |
|
278 // create this class object. Class id informs what class object |
|
279 // will be created. |
|
280 |
|
281 aStream.WriteInt32L( iClassId ); |
|
282 |
|
283 ExternalizeNodeUpgradeArrayL( aStream ); |
|
284 ExternalizeContentUpgradeArrayL( aStream ); |
|
285 aStream.WriteInt32L( iContentUpgrades ); |
|
286 } |
|
287 |
|
288 void CNcdNodeUpgrade::InternalizeL( RReadStream& aStream ) |
|
289 { |
|
290 DLTRACEIN(("")); |
|
291 |
|
292 // Read the class id first because it is set to the stream in internalize |
|
293 // function and it is not read from the stream anywhere else. |
|
294 TInt classId( aStream.ReadInt32L() ); |
|
295 if ( classId != ClassId() ) |
|
296 { |
|
297 DLTRACE(("Wrong class id")); |
|
298 DASSERT( EFalse ); |
|
299 // Leave because the stream does not match this class object |
|
300 User::Leave( KErrCorrupt ); |
|
301 } |
|
302 |
|
303 InternalizeNodeUpgradeArrayL( aStream ); |
|
304 InternalizeContentUpgradeArrayL( aStream ); |
|
305 |
|
306 iContentUpgrades = aStream.ReadInt32L(); |
|
307 DLTRACEOUT(("")); |
|
308 } |
|
309 |
|
310 |
|
311 void CNcdNodeUpgrade::ReceiveMessage( MCatalogsBaseMessage* aMessage, |
|
312 TInt aFunctionNumber ) |
|
313 { |
|
314 DLTRACEIN(("")); |
|
315 |
|
316 DASSERT( aMessage ); |
|
317 |
|
318 // Now, we can be sure that rest of the time iMessage exists. |
|
319 // This member variable is set for the CounterPartLost function. |
|
320 iMessage = aMessage; |
|
321 |
|
322 TInt trapError( KErrNone ); |
|
323 |
|
324 // Check which function is called by the proxy side object. |
|
325 // Function number are located in ncdnodefunctinoids.h file. |
|
326 switch( aFunctionNumber ) |
|
327 { |
|
328 case NcdNodeFunctionIds::ENcdInternalize: |
|
329 // Internalize the proxy side according to the data |
|
330 // of this object. |
|
331 TRAP( trapError, InternalizeRequestL( *aMessage ) ); |
|
332 break; |
|
333 |
|
334 case NcdNodeFunctionIds::ENcdRelease: |
|
335 // The proxy does not want to use this object anymore. |
|
336 // So, release the handle from the session. |
|
337 ReleaseRequest( *aMessage ); |
|
338 break; |
|
339 |
|
340 default: |
|
341 DLERROR(("Unidentified function request")); |
|
342 DASSERT( EFalse ); |
|
343 break; |
|
344 } |
|
345 |
|
346 if ( trapError != KErrNone ) |
|
347 { |
|
348 // Because something went wrong, the complete has not been |
|
349 // yet called for the message. |
|
350 // So, inform the client about the error if the |
|
351 // message is still available. |
|
352 aMessage->CompleteAndRelease( trapError ); |
|
353 } |
|
354 |
|
355 // Because the message should not be used after this, set it NULL. |
|
356 // So, CounterPartLost function will know that no messages are |
|
357 // waiting the response at the moment. |
|
358 iMessage = NULL; |
|
359 |
|
360 DLTRACEOUT(("")); |
|
361 } |
|
362 |
|
363 void CNcdNodeUpgrade::CounterPartLost( const MCatalogsSession& aSession ) |
|
364 { |
|
365 // This function may be called whenever -- when the message is waiting |
|
366 // response or when the message does not exist. |
|
367 // iMessage may be NULL here, because in the end of the |
|
368 // ReceiveMessage it is set to NULL. The life time of the message |
|
369 // ends shortly after CompleteAndRelease is called. |
|
370 if ( iMessage != NULL ) |
|
371 { |
|
372 iMessage->CounterPartLost( aSession ); |
|
373 } |
|
374 } |
|
375 |
|
376 |
|
377 void CNcdNodeUpgrade::InternalizeRequestL( MCatalogsBaseMessage& aMessage ) |
|
378 { |
|
379 DLTRACEIN(("")); |
|
380 |
|
381 CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); |
|
382 CleanupStack::PushL( buf ); |
|
383 |
|
384 RBufWriteStream stream( *buf ); |
|
385 CleanupClosePushL( stream ); |
|
386 |
|
387 |
|
388 // Include all the necessary node data to the stream |
|
389 ExternalizeDataForRequestL( stream ); |
|
390 |
|
391 |
|
392 // Commits data to the stream when closing. |
|
393 CleanupStack::PopAndDestroy( &stream ); |
|
394 |
|
395 |
|
396 // If this leaves, ReceiveMessage will complete the message. |
|
397 // NOTE: that here we expect that the buffer contains at least |
|
398 // some data. So, make sure that ExternalizeDataForRequestL inserts |
|
399 // something to the buffer. |
|
400 aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone ); |
|
401 |
|
402 |
|
403 DLTRACE(("Deleting the buf")); |
|
404 CleanupStack::PopAndDestroy( buf ); |
|
405 |
|
406 DLTRACEOUT(("")); |
|
407 } |
|
408 |
|
409 |
|
410 void CNcdNodeUpgrade::ExternalizeDataForRequestL( RWriteStream& aStream ) |
|
411 { |
|
412 DLTRACEIN(("")); |
|
413 |
|
414 // Also, check if the interface should be shown even if there is nothing to be |
|
415 // installed. |
|
416 if ( AllUpgradesInstalledL() |
|
417 && !ContentUpgrades() ) |
|
418 { |
|
419 DLINFO(("No installable node targets. Leave with KErrNotFound.")); |
|
420 User::Leave( KErrNotFound ); |
|
421 } |
|
422 |
|
423 if ( IsObsolete() ) |
|
424 { |
|
425 DLINFO(("Set as obsolete. This means that server has removed the object.")); |
|
426 User::Leave( KNcdErrorObsolete ); |
|
427 } |
|
428 |
|
429 // First insert data that the creator of this class object will use to |
|
430 // create this class object. Class id informs what class object |
|
431 // will be created. |
|
432 |
|
433 aStream.WriteInt32L( iClassId ); |
|
434 |
|
435 ExternalizeNodeUpgradeArrayL( aStream ); |
|
436 |
|
437 // Also externalize some information about the possible content dependencies for the |
|
438 // proxy |
|
439 ExternalizeContentUpgradeArrayForRequestL( aStream ); |
|
440 |
|
441 DASSERT( iUpgradeData ); |
|
442 if ( ContentUpgrades() ) |
|
443 { |
|
444 aStream.WriteInt8L( 1 ); |
|
445 iUpgradeData->ExternalizeL( aStream ); |
|
446 } |
|
447 else |
|
448 { |
|
449 aStream.WriteInt8L( 0 ); |
|
450 } |
|
451 |
|
452 DLTRACEOUT(("")); |
|
453 } |
|
454 |
|
455 |
|
456 void CNcdNodeUpgrade::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const |
|
457 { |
|
458 DLTRACEIN(("")); |
|
459 |
|
460 // Decrease the reference count for this object. |
|
461 // When the reference count reaches zero, this object will be destroyed |
|
462 // and removed from the session. |
|
463 MCatalogsSession& requestSession( aMessage.Session() ); |
|
464 TInt handle( aMessage.Handle() ); |
|
465 |
|
466 // Send complete information back to proxy. |
|
467 aMessage.CompleteAndRelease( KErrNone ); |
|
468 |
|
469 // Remove this object from the session. |
|
470 requestSession.RemoveObject( handle ); |
|
471 |
|
472 DLTRACEOUT(("")); |
|
473 } |
|
474 |
|
475 |
|
476 void CNcdNodeUpgrade::ExternalizeNodeUpgradeArrayL( RWriteStream& aStream ) |
|
477 { |
|
478 DLTRACEIN(("")); |
|
479 |
|
480 aStream.WriteInt32L( iUpgradeNodeTargets.Count() ); |
|
481 for ( TInt i = 0; i < iUpgradeNodeTargets.Count(); ++i ) |
|
482 { |
|
483 iUpgradeNodeTargets[ i ]->ExternalizeL( aStream ); |
|
484 } |
|
485 |
|
486 DLTRACEOUT(("")); |
|
487 } |
|
488 |
|
489 void CNcdNodeUpgrade::InternalizeNodeUpgradeArrayL( RReadStream& aStream ) |
|
490 { |
|
491 DLTRACEIN(("")); |
|
492 |
|
493 CNcdDependencyInfo* upgradeInfo( NULL ); |
|
494 TInt count( aStream.ReadInt32L() ); |
|
495 |
|
496 iUpgradeNodeTargets.ResetAndDestroy(); |
|
497 for( TInt i = 0; i < count; ++i ) |
|
498 { |
|
499 upgradeInfo = CNcdDependencyInfo::NewLC( aStream ); |
|
500 iUpgradeNodeTargets.AppendL( upgradeInfo ); |
|
501 CleanupStack::Pop( upgradeInfo ); |
|
502 } |
|
503 |
|
504 DLTRACEOUT(("")); |
|
505 } |
|
506 |
|
507 |
|
508 void CNcdNodeUpgrade::ExternalizeContentUpgradeArrayForRequestL( RWriteStream& aStream ) |
|
509 { |
|
510 DLTRACEIN(("")); |
|
511 |
|
512 aStream.WriteInt32L( iUpgradeContentTargets.Count() ); |
|
513 CNcdDownloadInfo* downloadInfo( NULL ); |
|
514 CNcdDependencyInfo* upgradeInfo( NULL ); |
|
515 // Notice that here we will give dependency info objects to the proxy side. |
|
516 for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i ) |
|
517 { |
|
518 downloadInfo = iUpgradeContentTargets[ i ]; |
|
519 upgradeInfo = CNcdDependencyInfo::NewLC( downloadInfo->ContentName(), |
|
520 downloadInfo->ContentVersion(), |
|
521 downloadInfo->ContentId(), |
|
522 NULL ); |
|
523 upgradeInfo->ExternalizeL( aStream ); |
|
524 CleanupStack::PopAndDestroy( upgradeInfo ); |
|
525 upgradeInfo = NULL; |
|
526 } |
|
527 |
|
528 DLTRACEOUT(("")); |
|
529 } |
|
530 |
|
531 void CNcdNodeUpgrade::ExternalizeContentUpgradeArrayL( RWriteStream& aStream ) |
|
532 { |
|
533 DLTRACEIN(("")); |
|
534 |
|
535 aStream.WriteInt32L( iUpgradeContentTargets.Count() ); |
|
536 for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i ) |
|
537 { |
|
538 iUpgradeContentTargets[ i ]->ExternalizeL( aStream ); |
|
539 } |
|
540 |
|
541 DLTRACEOUT(("")); |
|
542 } |
|
543 |
|
544 void CNcdNodeUpgrade::InternalizeContentUpgradeArrayL( RReadStream& aStream ) |
|
545 { |
|
546 DLTRACEIN(("")); |
|
547 |
|
548 CNcdDownloadInfo* content( NULL ); |
|
549 TInt count( aStream.ReadInt32L() ); |
|
550 |
|
551 iUpgradeContentTargets.ResetAndDestroy(); |
|
552 for( TInt i = 0; i < count; ++i ) |
|
553 { |
|
554 content = CNcdDownloadInfo::NewLC(); |
|
555 content->InternalizeL( aStream ); |
|
556 iUpgradeContentTargets.AppendL( content ); |
|
557 CleanupStack::Pop( content ); |
|
558 } |
|
559 |
|
560 DLTRACEOUT(("")); |
|
561 } |
|
562 |
|
563 |