|
1 /* |
|
2 * Copyright (c) 2007-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: CNcdReportManager implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "ncdreportmanager.h" |
|
20 |
|
21 #include "ncdoperationobserver.h" |
|
22 |
|
23 // Supported reports |
|
24 #include "ncdreportdownload.h" |
|
25 #include "ncdreportomadownload.h" |
|
26 #include "ncdreportinstall.h" |
|
27 |
|
28 #include "ncdproviderdefines.h" |
|
29 #include "ncdproviderutils.h" |
|
30 #include "ncdpanics.h" |
|
31 #include "ncdnodeidentifier.h" |
|
32 #include "ncdconfigurationmanager.h" |
|
33 #include "ncdserverdetails.h" |
|
34 #include "ncdgeneralmanager.h" |
|
35 |
|
36 // Protocol |
|
37 #include "ncdprotocol.h" |
|
38 #include "ncdrequestgenerator.h" |
|
39 #include "ncdrequestinstallation.h" |
|
40 #include "ncdcapabilities.h" |
|
41 #include "ncdprotocol.h" |
|
42 |
|
43 // Storage |
|
44 #include "ncdstorage.h" |
|
45 #include "ncddatabasestorage.h" |
|
46 #include "ncdstoragemanager.h" |
|
47 #include "ncdstorageitem.h" |
|
48 #include "ncdstoragedataitem.h" |
|
49 |
|
50 #include "catalogscontext.h" |
|
51 #include "catalogsutils.h" |
|
52 |
|
53 // HTTP |
|
54 #include "catalogshttpincludes.h" |
|
55 #include "catalogshttptransaction.h" |
|
56 #include "catalogshttpsessionmanagerimpl.h" |
|
57 #include "catalogsnetworkmanager.h" |
|
58 #include "catalogshttpconnectionmanager.h" |
|
59 |
|
60 #include "catalogsdebug.h" |
|
61 |
|
62 |
|
63 void CNcdReportManager::ReportIdToDescriptor( |
|
64 const TNcdReportId& aId, TDes& aTarget ) |
|
65 { |
|
66 aTarget.Num( aId ); |
|
67 } |
|
68 |
|
69 |
|
70 // --------------------------------------------------------------------------- |
|
71 // NewL |
|
72 // --------------------------------------------------------------------------- |
|
73 CNcdReportManager* CNcdReportManager::NewL( |
|
74 const MCatalogsContext& aContext, |
|
75 CNcdGeneralManager& aGeneralManager, |
|
76 MCatalogsHttpSession& aHttpSession, |
|
77 TBool aClientCrashed ) |
|
78 { |
|
79 CNcdReportManager* self = new(ELeave) CNcdReportManager( |
|
80 aContext, |
|
81 aGeneralManager, |
|
82 aHttpSession, |
|
83 aClientCrashed ); |
|
84 |
|
85 CleanupStack::PushL( self ); |
|
86 self->ConstructL(); |
|
87 CleanupStack::Pop( self ); |
|
88 return self; |
|
89 } |
|
90 |
|
91 |
|
92 // --------------------------------------------------------------------------- |
|
93 // Destructor |
|
94 // --------------------------------------------------------------------------- |
|
95 CNcdReportManager::~CNcdReportManager() |
|
96 { |
|
97 DLTRACEIN(("")); |
|
98 CancelReportSending(); |
|
99 Cancel(); |
|
100 |
|
101 iReports.ResetAndDestroy(); |
|
102 if ( iNetworkManager ) |
|
103 { |
|
104 iNetworkManager->RemoveObserver( *this ); |
|
105 } |
|
106 } |
|
107 |
|
108 |
|
109 // --------------------------------------------------------------------------- |
|
110 // |
|
111 // --------------------------------------------------------------------------- |
|
112 // |
|
113 void CNcdReportManager::SetReportingMethod( const MNcdServerReportManager::TReportingMethod& aMethod ) |
|
114 { |
|
115 DLTRACEIN(("")); |
|
116 // Here we create a copy of the member variable for later comparison. Notice, that |
|
117 // we crete a copy instead of a reference because if reference was used then the value of the |
|
118 // variable would change when iReporting is changed. |
|
119 MNcdServerReportManager::TReportingMethod tmpMethod( iReportingMethod ); |
|
120 iReportingMethod = aMethod; |
|
121 |
|
122 if ( tmpMethod != iReportingMethod |
|
123 && iReportingMethod == MNcdServerReportManager::EReportingBackground |
|
124 && iManagerState == ENcdReportManagerIdle |
|
125 && iTransactions.Count() == 0 ) |
|
126 { |
|
127 // If reporting method was changed to background method, |
|
128 // then try one loop to send the reports now, instead of waiting for the next report setting. |
|
129 // Also, transactions are checked to be sure that no pending transactions exist and |
|
130 // to check if all HTTP operations are completed yet. |
|
131 // Probably there is not anything to send, but just in case. |
|
132 // This setting will also start the RunL loop for the sending. |
|
133 TRAP_IGNORE( SetManagerStateL( ENcdReportManagerPreparing ) ); |
|
134 } |
|
135 } |
|
136 |
|
137 |
|
138 // --------------------------------------------------------------------------- |
|
139 // |
|
140 // --------------------------------------------------------------------------- |
|
141 // |
|
142 const MNcdServerReportManager::TReportingMethod& CNcdReportManager::ReportingMethod() const |
|
143 { |
|
144 DLTRACEIN(("")); |
|
145 return iReportingMethod; |
|
146 } |
|
147 |
|
148 |
|
149 // --------------------------------------------------------------------------- |
|
150 // |
|
151 // --------------------------------------------------------------------------- |
|
152 // |
|
153 void CNcdReportManager::SetReportingStyle( const MNcdServerReportManager::TReportingStyle& aStyle ) |
|
154 { |
|
155 DLTRACEIN(("")); |
|
156 iReportingStyle = aStyle; |
|
157 } |
|
158 |
|
159 |
|
160 // --------------------------------------------------------------------------- |
|
161 // |
|
162 // --------------------------------------------------------------------------- |
|
163 // |
|
164 const MNcdServerReportManager::TReportingStyle& CNcdReportManager::ReportingStyle() const |
|
165 { |
|
166 DLTRACEIN(("")); |
|
167 return iReportingStyle; |
|
168 } |
|
169 |
|
170 |
|
171 // --------------------------------------------------------------------------- |
|
172 // |
|
173 // --------------------------------------------------------------------------- |
|
174 // |
|
175 void CNcdReportManager::StartSendReportsL( MNcdOperationObserver& aObserver ) |
|
176 { |
|
177 DLTRACEIN(("")); |
|
178 |
|
179 if ( iObserver != NULL ) |
|
180 { |
|
181 // Operation is already going on and observer is set. |
|
182 User::Leave( KErrInUse ); |
|
183 } |
|
184 else if ( iReportingMethod != MNcdServerReportManager::EReportingManaged ) |
|
185 { |
|
186 // This function should be called only for managed reports. |
|
187 User::Leave( KErrArgument ); |
|
188 } |
|
189 else if ( iManagerState != ENcdReportManagerIdle |
|
190 || iTransactions.Count() > 0 ) |
|
191 { |
|
192 // This case may occur if the reporting method has just been changed and |
|
193 // there was still an automated operation pending when sending was asked |
|
194 // by the manager. |
|
195 // Because observer was not set, then set it here. |
|
196 // Observers are set only when reporting is managed. |
|
197 // For automated reporting observers are not used. |
|
198 // Also, transactions are checked to be sure that no pending transactions exist and |
|
199 // to check if all HTTP operations are completed yet. |
|
200 // Notice, that ownership is not transferred here. |
|
201 iObserver = &aObserver; |
|
202 return; |
|
203 } |
|
204 else |
|
205 { |
|
206 // We are having a managed report and operation is in idle state. |
|
207 // So, start the action. |
|
208 SetManagerStateL( ENcdReportManagerPreparing ); |
|
209 // Notice, that ownership is not transferred here. |
|
210 iObserver = &aObserver; |
|
211 } |
|
212 } |
|
213 |
|
214 |
|
215 // --------------------------------------------------------------------------- |
|
216 // |
|
217 // --------------------------------------------------------------------------- |
|
218 TNcdReportId CNcdReportManager::RegisterDownloadL( |
|
219 const TDesC& aUri, |
|
220 const CNcdNodeIdentifier& aMetadataId, |
|
221 const TNcdReportStatusInfo& aStatus, |
|
222 const TDesC& aReportUri, |
|
223 const TDesC& aReportNamespace ) |
|
224 { |
|
225 DLTRACEIN(( _L("aUri: %S, aStatus: %d"), &aUri, aStatus.iStatus )); |
|
226 |
|
227 // Check if the download has already been registered |
|
228 CNcdReport* report = FindReport( |
|
229 aUri, |
|
230 aMetadataId, |
|
231 aReportUri, |
|
232 ENcdReportDownload, |
|
233 iReports ); |
|
234 |
|
235 // Use old report only if it can still be updated with a new |
|
236 // status before sending. We don't want to overwrite any pending |
|
237 // cancellation/failure/success reports |
|
238 if ( report && !report->StatusIsFinal() ) |
|
239 { |
|
240 DLTRACEOUT(("Download has already been registered")); |
|
241 report->Attributes().SetAttributeL( |
|
242 ENcdReportAttributeIsUsed, ETrue ); |
|
243 |
|
244 return report->ReportId(); |
|
245 } |
|
246 |
|
247 report = NULL; |
|
248 |
|
249 TBool serverSupports = ServerSupportsReports( |
|
250 ENcdReportDownload, |
|
251 aReportUri, |
|
252 aReportNamespace ); |
|
253 |
|
254 if ( serverSupports ) |
|
255 { |
|
256 DLTRACE(("Server supports download reports")); |
|
257 report = CNcdReportDownload::NewLC( |
|
258 *this, |
|
259 aUri, |
|
260 aMetadataId, |
|
261 aStatus, |
|
262 aReportUri, |
|
263 aReportNamespace ); |
|
264 |
|
265 iReports.InsertInOrderAllowRepeatsL( |
|
266 report, |
|
267 TLinearOrder<CNcdReport>( CNcdReport::Compare ) ); |
|
268 |
|
269 CleanupStack::Pop( report ); |
|
270 report->SetReportId( GenerateReportId() ); |
|
271 report->Attributes().SetAttributeL( |
|
272 ENcdReportAttributeIsUsed, ETrue ); |
|
273 |
|
274 DLTRACEOUT(("Report added")); |
|
275 return report->ReportId(); |
|
276 } |
|
277 |
|
278 return KNcdReportNotSupported; |
|
279 } |
|
280 |
|
281 |
|
282 // --------------------------------------------------------------------------- |
|
283 // |
|
284 // --------------------------------------------------------------------------- |
|
285 TNcdReportId CNcdReportManager::RegisterOmaDownloadL( |
|
286 const TDesC& aUri, |
|
287 const CNcdNodeIdentifier& aMetadataId, |
|
288 const TNcdReportStatusInfo& aStatus, |
|
289 const TDesC& aReportUri ) |
|
290 { |
|
291 DLTRACEIN(( _L("aUri: %S, aStatus: %d"), &aUri, aStatus.iStatus )); |
|
292 |
|
293 // Check if the download has already been registered |
|
294 CNcdReport* report = FindReport( |
|
295 aUri, |
|
296 aMetadataId, |
|
297 aReportUri, |
|
298 ENcdReportOmaDownload, |
|
299 iReports ); |
|
300 |
|
301 // Use old report only if it can still be updated with a new |
|
302 // status before sending |
|
303 if ( report && !report->StatusIsFinal() ) |
|
304 { |
|
305 |
|
306 DLTRACEOUT(("Download has already been registered")); |
|
307 report->Attributes().SetAttributeL( |
|
308 ENcdReportAttributeIsUsed, ETrue ); |
|
309 |
|
310 return report->ReportId(); |
|
311 } |
|
312 |
|
313 report = NULL; |
|
314 |
|
315 DLTRACE(("Server supports download reports")); |
|
316 report = CNcdReportOmaDownload::NewLC( |
|
317 *this, |
|
318 aUri, |
|
319 aMetadataId, |
|
320 aStatus, |
|
321 aReportUri ); |
|
322 |
|
323 iReports.InsertInOrderAllowRepeatsL( |
|
324 report, |
|
325 TLinearOrder<CNcdReport>( CNcdReport::Compare ) ); |
|
326 |
|
327 CleanupStack::Pop( report ); |
|
328 report->SetReportId( GenerateReportId() ); |
|
329 report->Attributes().SetAttributeL( |
|
330 ENcdReportAttributeIsUsed, ETrue ); |
|
331 |
|
332 DLTRACEOUT(("Report added")); |
|
333 return report->ReportId(); |
|
334 } |
|
335 |
|
336 |
|
337 // --------------------------------------------------------------------------- |
|
338 // |
|
339 // --------------------------------------------------------------------------- |
|
340 TInt CNcdReportManager::SetDownloadReportAccessPoint( |
|
341 const TNcdReportId& aReportId, |
|
342 const TCatalogsConnectionMethod& aAccessPoint ) |
|
343 { |
|
344 DLTRACEIN(("aAccessPoint: %d", aAccessPoint.iId )); |
|
345 |
|
346 CNcdReport* report = FindReport( |
|
347 aReportId, |
|
348 iReports ); |
|
349 |
|
350 if ( !report ) |
|
351 { |
|
352 DLERROR(("Download has not been been registered")); |
|
353 return KErrNotFound; |
|
354 } |
|
355 |
|
356 report->SetAccessPoint( aAccessPoint ); |
|
357 |
|
358 DLTRACEOUT(("Access point set successfully")); |
|
359 return KErrNone; |
|
360 } |
|
361 |
|
362 |
|
363 // --------------------------------------------------------------------------- |
|
364 // |
|
365 // --------------------------------------------------------------------------- |
|
366 void CNcdReportManager::ReportDownloadStatusL( |
|
367 const TNcdReportId& aReportId, |
|
368 const TNcdReportStatusInfo& aStatus, |
|
369 TBool aSendable ) |
|
370 { |
|
371 DLTRACEIN(("aStatus: %d", aStatus.iStatus )); |
|
372 |
|
373 CNcdReport* report = FindReport( |
|
374 aReportId, |
|
375 iReports ); |
|
376 |
|
377 if ( !report ) |
|
378 { |
|
379 DLERROR(("Report not found")); |
|
380 return; |
|
381 } |
|
382 |
|
383 SetReportStatusL( *report, aStatus, aSendable ); |
|
384 } |
|
385 |
|
386 |
|
387 // --------------------------------------------------------------------------- |
|
388 // |
|
389 // --------------------------------------------------------------------------- |
|
390 TNcdReportId CNcdReportManager::RegisterInstallL( |
|
391 const TDesC& aContentIdentifier, |
|
392 const CNcdNodeIdentifier& aMetadataId, |
|
393 const TNcdReportStatusInfo& aStatus, |
|
394 const TDesC& aReportUri, |
|
395 const TDesC& aReportNamespace ) |
|
396 { |
|
397 DLTRACEIN(( _L("aReportUri: %S, aStatus: %d"), &aReportUri, aStatus.iStatus )); |
|
398 |
|
399 // Check if the install has already been registered. |
|
400 CNcdReport* report = FindReport( |
|
401 aContentIdentifier, |
|
402 aMetadataId, |
|
403 aReportUri, |
|
404 ENcdReportInstall, |
|
405 iReports ); |
|
406 |
|
407 if ( report && !report->StatusIsFinal() ) |
|
408 { |
|
409 DLTRACEOUT(("Install has already been registered")); |
|
410 report->Attributes().SetAttributeL( |
|
411 ENcdReportAttributeIsUsed, ETrue ); |
|
412 |
|
413 return report->ReportId(); |
|
414 } |
|
415 |
|
416 TBool serverSupports = ServerSupportsReports( |
|
417 ENcdReportInstall, |
|
418 aReportUri, |
|
419 aReportNamespace ); |
|
420 |
|
421 if ( serverSupports ) |
|
422 { |
|
423 DLTRACE(("Server supports install reports")); |
|
424 report = CNcdReportInstall::NewLC( |
|
425 *this, |
|
426 aContentIdentifier, |
|
427 aMetadataId, |
|
428 aStatus, |
|
429 aReportUri, |
|
430 aReportNamespace ); |
|
431 |
|
432 iReports.InsertInOrderAllowRepeatsL( |
|
433 report, |
|
434 TLinearOrder<CNcdReport>( CNcdReport::Compare ) ); |
|
435 |
|
436 CleanupStack::Pop( report ); |
|
437 report->SetReportId( GenerateReportId() ); |
|
438 report->Attributes().SetAttributeL( |
|
439 ENcdReportAttributeIsUsed, ETrue ); |
|
440 |
|
441 DLTRACEOUT(("Report added")); |
|
442 return report->ReportId(); |
|
443 } |
|
444 |
|
445 return KNcdReportNotSupported; |
|
446 } |
|
447 |
|
448 |
|
449 // --------------------------------------------------------------------------- |
|
450 // |
|
451 // --------------------------------------------------------------------------- |
|
452 TInt CNcdReportManager::SetInstallReportAccessPoint( |
|
453 const TNcdReportId& aReportId, |
|
454 const TCatalogsConnectionMethod& aAccessPoint ) |
|
455 { |
|
456 DLTRACEIN(("aAccessPoint: %d", aAccessPoint.iId )); |
|
457 |
|
458 // Same implementation with download and install. |
|
459 TInt error( SetDownloadReportAccessPoint( aReportId, aAccessPoint ) ); |
|
460 |
|
461 DLTRACEOUT(("Access point set successfully")); |
|
462 return error; |
|
463 } |
|
464 |
|
465 |
|
466 // --------------------------------------------------------------------------- |
|
467 // |
|
468 // --------------------------------------------------------------------------- |
|
469 void CNcdReportManager::ReportInstallStatusL( |
|
470 const TNcdReportId& aReportId, |
|
471 const TNcdReportStatusInfo& aStatus ) |
|
472 { |
|
473 DLTRACEIN(("aStatus: %d", aStatus.iStatus)); |
|
474 |
|
475 // Same implementation with download and install |
|
476 TBool sendable( EFalse ); |
|
477 if ( aStatus.iStatus == ENcdReportSuccess |
|
478 || aStatus.iStatus == ENcdReportCancel |
|
479 || aStatus.iStatus == ENcdReportFail ) |
|
480 { |
|
481 sendable = ETrue; |
|
482 } |
|
483 ReportDownloadStatusL( aReportId, aStatus, sendable ); |
|
484 } |
|
485 |
|
486 |
|
487 // --------------------------------------------------------------------------- |
|
488 // |
|
489 // --------------------------------------------------------------------------- |
|
490 void CNcdReportManager::SetReportsAsUsedL( |
|
491 const CNcdNodeIdentifier& aMetadataId ) |
|
492 { |
|
493 DLTRACEIN(("")); |
|
494 for ( TInt i = 0; i < iReports.Count(); ++i ) |
|
495 { |
|
496 if ( iReports[i]->MetadataId().Equals( aMetadataId ) ) |
|
497 { |
|
498 DLINFO(("Setting report as used")); |
|
499 iReports[i]->Attributes().SetAttributeL( |
|
500 ENcdReportAttributeIsUsed, ETrue ); |
|
501 // No break since there may be other reports with |
|
502 // the same metadata id |
|
503 } |
|
504 } |
|
505 } |
|
506 |
|
507 |
|
508 // --------------------------------------------------------------------------- |
|
509 // |
|
510 // --------------------------------------------------------------------------- |
|
511 void CNcdReportManager::RemoveUnusedReportsL() |
|
512 { |
|
513 DLTRACEIN(("")); |
|
514 for ( TInt i = 0; i < iReports.Count(); ++i ) |
|
515 { |
|
516 if ( !iReports[i]->Attributes().AttributeInt32( |
|
517 ENcdReportAttributeIsUsed ) ) |
|
518 { |
|
519 TNcdReportStatusInfo info( ENcdReportCancel, KErrCancel ); |
|
520 SetReportStatusL( *iReports[i], info, ETrue ); |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 |
|
526 // --------------------------------------------------------------------------- |
|
527 // |
|
528 // --------------------------------------------------------------------------- |
|
529 void CNcdReportManager::OpenStorageL() |
|
530 { |
|
531 DLTRACEIN(("")); |
|
532 iDb = NULL; |
|
533 |
|
534 HBufC* clientUid = iContext.FamilyId().Name().AllocLC(); |
|
535 |
|
536 // Recreate necessary storage objects. Nothing is created if not necessary |
|
537 MNcdStorage& storage = iStorageManager.CreateOrGetStorageL( |
|
538 *clientUid, NcdProviderDefines::KDownloadNamespace ); |
|
539 |
|
540 CleanupStack::PopAndDestroy( clientUid ); |
|
541 |
|
542 iDb = &storage.DatabaseStorageL( |
|
543 NcdProviderDefines::KReportDatabaseUid ); |
|
544 DLTRACEOUT(("Storage opened, iDb: %x", iDb)); |
|
545 } |
|
546 |
|
547 |
|
548 // --------------------------------------------------------------------------- |
|
549 // |
|
550 // --------------------------------------------------------------------------- |
|
551 void CNcdReportManager::CloseStorage() |
|
552 { |
|
553 DLTRACEIN(("")); |
|
554 |
|
555 iDb = NULL; |
|
556 } |
|
557 |
|
558 |
|
559 // --------------------------------------------------------------------------- |
|
560 // Loads unfinished reports |
|
561 // --------------------------------------------------------------------------- |
|
562 void CNcdReportManager::LoadReportsL() |
|
563 { |
|
564 DLTRACEIN(("")); |
|
565 |
|
566 OpenStorageL(); |
|
567 |
|
568 DASSERT( iDb ); |
|
569 |
|
570 // Get all items from the db |
|
571 RPointerArray<MNcdStorageItem> items; |
|
572 iDb->StorageItemsL( items ); |
|
573 CleanupClosePushL( items ); |
|
574 |
|
575 for ( TInt i = 0; i < items.Count(); ++i ) |
|
576 { |
|
577 items[i]->SetDataItem( this ); |
|
578 |
|
579 // This will cause a call to report manager's InternalizeL |
|
580 items[i]->ReadDataL(); |
|
581 } |
|
582 |
|
583 CleanupStack::PopAndDestroy( &items ); |
|
584 |
|
585 DLTRACEOUT(("Reports loaded")); |
|
586 } |
|
587 |
|
588 |
|
589 // --------------------------------------------------------------------------- |
|
590 // Saves an individual report to disk |
|
591 // --------------------------------------------------------------------------- |
|
592 void CNcdReportManager::SaveReportL( CNcdReport& aReport ) |
|
593 { |
|
594 DLTRACEIN(("")); |
|
595 |
|
596 MNcdStorageItem& item( StorageItemForReportL( aReport.ReportId() ) ); |
|
597 |
|
598 // Save new item to database |
|
599 item.SetDataItem( &aReport ); |
|
600 item.OpenL(); |
|
601 |
|
602 // Calls ExternalizeL for the item |
|
603 item.WriteDataL(); |
|
604 |
|
605 // Save the item to the database. |
|
606 item.SaveL(); |
|
607 |
|
608 DLTRACEOUT(("")); |
|
609 } |
|
610 |
|
611 |
|
612 // --------------------------------------------------------------------------- |
|
613 // Remove report from db |
|
614 // --------------------------------------------------------------------------- |
|
615 void CNcdReportManager::RemoveReportL( const TNcdReportId& aId ) |
|
616 { |
|
617 DLTRACEIN(("")); |
|
618 |
|
619 MNcdStorageItem& item( StorageItemForReportL( aId ) ); |
|
620 item.RemoveFromStorageL(); |
|
621 } |
|
622 |
|
623 |
|
624 // --------------------------------------------------------------------------- |
|
625 // Get a storage item that matches the report id |
|
626 // --------------------------------------------------------------------------- |
|
627 MNcdStorageItem& CNcdReportManager::StorageItemForReportL( |
|
628 const TNcdReportId& aId ) |
|
629 { |
|
630 DLTRACEIN(("")); |
|
631 OpenStorageL(); |
|
632 |
|
633 DASSERT( iDb ); |
|
634 |
|
635 TBuf<KNcdReportIdLength16Bit> id; |
|
636 ReportIdToDescriptor( aId, id ); |
|
637 DLTRACE(( _L("Id: %S"), &id )); |
|
638 DLTRACE(("Getting storage item, iDb: %x", iDb )); |
|
639 // Get/create the storage item where the data is saved |
|
640 // Note: database has the ownership of the item |
|
641 MNcdStorageItem* item = iDb->StorageItemL( id, KNcdReportDataType ); |
|
642 return *item; |
|
643 } |
|
644 |
|
645 |
|
646 // --------------------------------------------------------------------------- |
|
647 // MCatalogsAccessPointObserver |
|
648 // --------------------------------------------------------------------------- |
|
649 |
|
650 // --------------------------------------------------------------------------- |
|
651 // |
|
652 // --------------------------------------------------------------------------- |
|
653 void CNcdReportManager::HandleAccessPointEventL( |
|
654 const TCatalogsConnectionMethod& aAp, |
|
655 const TCatalogsAccessPointEvent& aEvent ) |
|
656 { |
|
657 DLTRACEIN(("")); |
|
658 (void) aAp; // suppress warning |
|
659 |
|
660 // Just try to send reports when an AP is opened. |
|
661 if ( aEvent == ECatalogsAccessPointOpened && |
|
662 iManagerState == ENcdReportManagerIdle && |
|
663 iReportingMethod == MNcdServerReportManager::EReportingBackground ) |
|
664 { |
|
665 DLTRACE(("Ap: %d opened", aAp.iId )); |
|
666 // Notice, that the manager state is set to ENcdReportManagerPreparing |
|
667 // only if the reporting method should work in the background. |
|
668 // This setting will also start the RunL loop for the sending. |
|
669 SetManagerStateL( ENcdReportManagerPreparing ); |
|
670 } |
|
671 } |
|
672 |
|
673 |
|
674 // --------------------------------------------------------------------------- |
|
675 // |
|
676 // --------------------------------------------------------------------------- |
|
677 void CNcdReportManager::HandleHttpEventL( |
|
678 MCatalogsHttpOperation& aOperation, |
|
679 TCatalogsHttpEvent aEvent ) |
|
680 { |
|
681 DLTRACEIN(("")); |
|
682 |
|
683 switch( aEvent.iOperationState ) |
|
684 { |
|
685 // Handle completed operation |
|
686 case ECatalogsHttpOpCompleted: |
|
687 { |
|
688 DLTRACE(("Operation complete")); |
|
689 // Finish report releases the transaction |
|
690 FinishReportL( aOperation, KErrNone ); |
|
691 break; |
|
692 } |
|
693 |
|
694 // Handle operation in progress |
|
695 case ECatalogsHttpOpInProgress: |
|
696 { |
|
697 if ( aEvent.iProgressState == |
|
698 ECatalogsHttpResponseBodyReceived ) |
|
699 { |
|
700 DLINFO(("response body=%S", &aOperation.Body() )); |
|
701 // send received data to parser |
|
702 } |
|
703 break; |
|
704 } |
|
705 |
|
706 default: |
|
707 { |
|
708 break; |
|
709 } |
|
710 } |
|
711 |
|
712 DLTRACEOUT(("")); |
|
713 |
|
714 } |
|
715 |
|
716 |
|
717 // --------------------------------------------------------------------------- |
|
718 // |
|
719 // --------------------------------------------------------------------------- |
|
720 TBool CNcdReportManager::HandleHttpError( |
|
721 MCatalogsHttpOperation& aOperation, |
|
722 TCatalogsHttpError aError ) |
|
723 { |
|
724 DLTRACEIN(("Error type: %d, code: %d", aError.iType, aError.iError )); |
|
725 |
|
726 // Can't do anything for the error anyway |
|
727 // Finish report releases the transaction |
|
728 TRAP_IGNORE( FinishReportL( aOperation, aError.iError ) ); |
|
729 DLTRACEOUT(("")); |
|
730 return ETrue; |
|
731 |
|
732 } |
|
733 |
|
734 |
|
735 // --------------------------------------------------------------------------- |
|
736 // Context getter |
|
737 // --------------------------------------------------------------------------- |
|
738 const MCatalogsContext& CNcdReportManager::Context() const |
|
739 { |
|
740 return iContext; |
|
741 } |
|
742 |
|
743 |
|
744 // --------------------------------------------------------------------------- |
|
745 // Cancel ongoing report transactions |
|
746 // --------------------------------------------------------------------------- |
|
747 void CNcdReportManager::CancelReportSending() |
|
748 { |
|
749 DLTRACEIN(("")); |
|
750 |
|
751 for ( TInt i = 0; i < iTransactions.Count(); ++i ) |
|
752 { |
|
753 iTransactions[i]->Cancel(); |
|
754 } |
|
755 iTransactions.Reset(); |
|
756 |
|
757 for ( TInt i = 0; i < iReports.Count(); ++i ) |
|
758 { |
|
759 iReports[i]->SetReportTransaction( NULL ); |
|
760 } |
|
761 |
|
762 if ( iObserver != NULL ) |
|
763 { |
|
764 // Inform the observer about the cancellation. |
|
765 iObserver->OperationComplete( NULL, KErrCancel ); |
|
766 iObserver = NULL; |
|
767 } |
|
768 } |
|
769 |
|
770 |
|
771 // --------------------------------------------------------------------------- |
|
772 // |
|
773 // --------------------------------------------------------------------------- |
|
774 TCatalogsConnectionMethod CNcdReportManager::DefaultConnectionMethod() |
|
775 { |
|
776 DLTRACEIN(("")); |
|
777 // APN ID of the current/last opened default accesspoint |
|
778 TUint32 apn = iHttpSession.ConnectionManager().CurrentAccessPoint(); |
|
779 |
|
780 // This ensures that reports use the latest connected default accesspoint |
|
781 // or the AP that is set to them. |
|
782 // Issue: DLEB-140 |
|
783 TCatalogsConnectionMethod method( |
|
784 apn, |
|
785 ECatalogsConnectionMethodTypeAccessPoint ); |
|
786 method.iApnId = apn; |
|
787 |
|
788 return method; |
|
789 } |
|
790 |
|
791 |
|
792 // --------------------------------------------------------------------------- |
|
793 // |
|
794 // --------------------------------------------------------------------------- |
|
795 CNcdGeneralManager& CNcdReportManager::GeneralManager() const |
|
796 { |
|
797 return iGeneralManager; |
|
798 } |
|
799 |
|
800 |
|
801 // --------------------------------------------------------------------------- |
|
802 // From MNcdStorageDataItem |
|
803 // --------------------------------------------------------------------------- |
|
804 |
|
805 // --------------------------------------------------------------------------- |
|
806 // |
|
807 // --------------------------------------------------------------------------- |
|
808 void CNcdReportManager::ExternalizeL( RWriteStream& /*aStream*/ ) |
|
809 { |
|
810 DLTRACEIN(("")); |
|
811 // nothing to do |
|
812 } |
|
813 |
|
814 |
|
815 // --------------------------------------------------------------------------- |
|
816 // |
|
817 // --------------------------------------------------------------------------- |
|
818 void CNcdReportManager::InternalizeL( RReadStream& aStream ) |
|
819 { |
|
820 DLTRACEIN(("")); |
|
821 |
|
822 TNcdReportType type; |
|
823 InternalizeEnumL( type, aStream ); |
|
824 |
|
825 CNcdReport* report( NULL ); |
|
826 |
|
827 switch( type ) |
|
828 { |
|
829 case ENcdReportDownload: |
|
830 { |
|
831 report = CNcdReportDownload::NewLC( *this, aStream ); |
|
832 break; |
|
833 } |
|
834 |
|
835 case ENcdReportOmaDownload: |
|
836 { |
|
837 report = CNcdReportOmaDownload::NewLC( *this, aStream ); |
|
838 break; |
|
839 } |
|
840 |
|
841 case ENcdReportInstall: |
|
842 { |
|
843 report = CNcdReportInstall::NewLC( *this, aStream ); |
|
844 break; |
|
845 } |
|
846 |
|
847 default: |
|
848 { |
|
849 NCD_ASSERT_ALWAYS( 0, ENcdPanicIndexOutOfRange ); |
|
850 } |
|
851 } |
|
852 |
|
853 CNcdAttributes& att( report->Attributes() ); |
|
854 |
|
855 if ( !iClientCrashed ) |
|
856 { |
|
857 |
|
858 // Set as unused, flag is set to used if a download registers |
|
859 // to this report |
|
860 att.SetAttributeL( |
|
861 ENcdReportAttributeIsUsed, EFalse ); |
|
862 |
|
863 // Check if the report sending was canceled and |
|
864 // set as sendable if it was |
|
865 if ( att.AttributeInt32( |
|
866 ENcdReportAttributeReportBeingSent ) != ENcdReportNone && |
|
867 att.AttributeInt32( |
|
868 ENcdReportAttributeLatestSentReport ) == ENcdReportNone ) |
|
869 { |
|
870 DLTRACE(("Set as sendable because previous attempt was canceled")); |
|
871 att.SetAttributeL( ENcdReportAttributeSendable, ETrue ); |
|
872 } |
|
873 } |
|
874 else |
|
875 { |
|
876 DLTRACE(("Set report as failed because engine crashed")); |
|
877 TNcdReportStatusInfo info( ENcdReportFail, KErrUnknown ); |
|
878 report->SetStatus( info ); |
|
879 att.SetAttributeL( |
|
880 ENcdReportAttributeIsUsed, EFalse ); |
|
881 |
|
882 // Check if the report sending was canceled and |
|
883 // set as sendable if it was |
|
884 att.SetAttributeL( ENcdReportAttributeSendable, ETrue ); |
|
885 |
|
886 } |
|
887 |
|
888 iReports.InsertInOrderAllowRepeatsL( |
|
889 report, |
|
890 TLinearOrder<CNcdReport>( CNcdReport::Compare ) ); |
|
891 |
|
892 CleanupStack::Pop( report ); // report, |
|
893 |
|
894 // ensure that iNewReportId is higher than any current report id |
|
895 if ( report->ReportId() >= iNewReportId ) |
|
896 { |
|
897 iNewReportId = report->ReportId() + 1; |
|
898 } |
|
899 |
|
900 DLTRACEOUT(("Report internalized")); |
|
901 } |
|
902 |
|
903 |
|
904 |
|
905 // --------------------------------------------------------------------------- |
|
906 // From CActive |
|
907 // --------------------------------------------------------------------------- |
|
908 |
|
909 |
|
910 // --------------------------------------------------------------------------- |
|
911 // |
|
912 // --------------------------------------------------------------------------- |
|
913 void CNcdReportManager::RunL() |
|
914 { |
|
915 DLTRACEIN(("")); |
|
916 if ( iStatus.Int() == KErrNone ) |
|
917 { |
|
918 switch ( iManagerState ) |
|
919 { |
|
920 case ENcdReportManagerPreparing: |
|
921 { |
|
922 SendReportsL(); |
|
923 break; |
|
924 }; |
|
925 |
|
926 default: |
|
927 { |
|
928 DLTRACE(("Default")); |
|
929 break; |
|
930 } |
|
931 } |
|
932 } |
|
933 } |
|
934 |
|
935 |
|
936 // --------------------------------------------------------------------------- |
|
937 // |
|
938 // --------------------------------------------------------------------------- |
|
939 void CNcdReportManager::DoCancel() |
|
940 { |
|
941 DLTRACEIN(("")); |
|
942 |
|
943 // No requests to cancel |
|
944 } |
|
945 |
|
946 |
|
947 // --------------------------------------------------------------------------- |
|
948 // |
|
949 // --------------------------------------------------------------------------- |
|
950 TInt CNcdReportManager::RunError( TInt aError ) |
|
951 { |
|
952 DLTRACEIN(("aError: %d", aError)); |
|
953 |
|
954 if ( iObserver != NULL ) |
|
955 { |
|
956 iObserver->OperationComplete( NULL, aError ); |
|
957 iObserver = NULL; |
|
958 } |
|
959 |
|
960 // Return KErrNone so that CActiveScheduler doesn't panic |
|
961 // with E32USER-CBase 47. Would call an observer if there was any. |
|
962 |
|
963 return KErrNone; |
|
964 } |
|
965 |
|
966 |
|
967 // --------------------------------------------------------------------------- |
|
968 // |
|
969 // --------------------------------------------------------------------------- |
|
970 void CNcdReportManager::FinishReportL( MCatalogsHttpOperation& aOperation, TInt aErrorCode ) |
|
971 { |
|
972 DLTRACEIN(("")); |
|
973 |
|
974 // This function will insert the information into the reports after the |
|
975 // report sending operation has been finished. So, all the reports that have |
|
976 // been handled by the operation are removed from the list. |
|
977 |
|
978 MCatalogsHttpOperation* operationPtr = &aOperation; |
|
979 |
|
980 // Remove the transaction before any leaving code so that if a leave |
|
981 // occurs, we don't have any hanging transactions in the array |
|
982 TInt index = iTransactions.FindInAddressOrder( &aOperation ); |
|
983 DASSERT( index != KErrNotFound ); |
|
984 |
|
985 iTransactions.Remove( index ); |
|
986 aOperation.Release(); |
|
987 |
|
988 TInt i = iReports.Count(); |
|
989 while ( i-- ) |
|
990 { |
|
991 if ( iReports[i]->ReportTransaction() == operationPtr ) |
|
992 { |
|
993 iReports[i]->SetReportTransaction( NULL ); |
|
994 |
|
995 CNcdAttributes& att( iReports[i]->Attributes() ); |
|
996 |
|
997 // Update latest sent report status |
|
998 att.SetAttributeL( |
|
999 ENcdReportAttributeLatestSentReport, |
|
1000 att.AttributeInt32( |
|
1001 ENcdReportAttributeReportBeingSent ) ); |
|
1002 |
|
1003 if ( iReports[i]->CanBeRemoved() ) |
|
1004 { |
|
1005 DLTRACE(("Deleting report")); |
|
1006 RemoveReportL( iReports[i]->ReportId() ); |
|
1007 delete iReports[i]; |
|
1008 iReports.Remove( i ); |
|
1009 } |
|
1010 else // save info that report was sent |
|
1011 { |
|
1012 SaveReportL( *iReports[i] ); |
|
1013 } |
|
1014 } |
|
1015 } |
|
1016 |
|
1017 |
|
1018 DLTRACE(("Committing report changes")); |
|
1019 iDb->CommitL(); |
|
1020 |
|
1021 |
|
1022 // Check if all the transactions have been handled. If they are, then no more |
|
1023 // http operations are going on and the reporting is finished. |
|
1024 if ( iTransactions.Count() == 0 ) |
|
1025 { |
|
1026 DLTRACE(("No more pending reports.")); |
|
1027 if ( iReportingMethod == MNcdServerReportManager::EReportingBackground ) |
|
1028 { |
|
1029 DLINFO(("Start handling next patch")); |
|
1030 // Notice, that by calling this, we continue to the next round in the RunL. |
|
1031 // So, then new reports will be sent if they exist then. If there is already new |
|
1032 // items available, then they will be sent. Otherwise the operation |
|
1033 // will end after RunL is called next time. |
|
1034 SetManagerStateL( ENcdReportManagerPreparing ); |
|
1035 } |
|
1036 else |
|
1037 { |
|
1038 DLINFO(("Set to idle because sending is managed by hand.")); |
|
1039 // This will set the state and the RunL loop will not be continued. |
|
1040 SetManagerStateL( ENcdReportManagerIdle ); |
|
1041 } |
|
1042 |
|
1043 // Notice, that observer is set only for the managed reporting. But, in some cases |
|
1044 // the reporting may have been changed to background before the requested managed send |
|
1045 // was finished. So, instead of waiting for the background action to finish in next |
|
1046 // RunL loop, inform the observer already here about the completion. If only background |
|
1047 // operations have been occurring, then the observer is NULL here. |
|
1048 if ( iObserver != NULL ) |
|
1049 { |
|
1050 // Because observer was set for manager to know when managed operation |
|
1051 // was finished, inform the observer. |
|
1052 iObserver->OperationComplete( NULL, aErrorCode ); |
|
1053 iObserver = NULL; |
|
1054 } |
|
1055 } |
|
1056 } |
|
1057 |
|
1058 |
|
1059 // --------------------------------------------------------------------------- |
|
1060 // Server capability check |
|
1061 // --------------------------------------------------------------------------- |
|
1062 TBool CNcdReportManager::ServerSupportsReports( |
|
1063 TNcdReportType aType, |
|
1064 const TDesC& aServerUri, |
|
1065 const TDesC& aServerNamespace ) const |
|
1066 { |
|
1067 DLTRACEIN(("")); |
|
1068 const MNcdServerDetails* serverDetails = |
|
1069 iConfigurationManager.ServerDetails( |
|
1070 iContext, |
|
1071 aServerUri, |
|
1072 aServerNamespace ); |
|
1073 |
|
1074 // No server details so we don't know whether server supports them |
|
1075 // or not |
|
1076 if ( !serverDetails ) |
|
1077 { |
|
1078 DLTRACEOUT(("Server details not found")); |
|
1079 return EFalse; |
|
1080 } |
|
1081 |
|
1082 // Notice, that install capability support is already checked here. |
|
1083 TBool supports = |
|
1084 serverDetails->IsCapabilitySupported( |
|
1085 NcdCapabilities::KInstallationReport() ); |
|
1086 |
|
1087 // Download report requires install capability and also download capability |
|
1088 if ( aType == ENcdReportDownload ) |
|
1089 { |
|
1090 DLTRACE(("Checking for downloadReport capability")); |
|
1091 |
|
1092 supports = supports && |
|
1093 serverDetails->IsCapabilitySupported( |
|
1094 NcdCapabilities::KDownloadReport() ); |
|
1095 } |
|
1096 |
|
1097 DLTRACEOUT(("Required caps supported: %d", supports )); |
|
1098 return supports; |
|
1099 } |
|
1100 |
|
1101 |
|
1102 // --------------------------------------------------------------------------- |
|
1103 // |
|
1104 // --------------------------------------------------------------------------- |
|
1105 CNcdReportManager::CNcdReportManager( |
|
1106 const MCatalogsContext& aContext, |
|
1107 CNcdGeneralManager& aGeneralManager, |
|
1108 MCatalogsHttpSession& aHttpSession, |
|
1109 TBool aClientCrashed ) : |
|
1110 CActive( EPriorityStandard ), |
|
1111 iContext( aContext ), |
|
1112 iGeneralManager( aGeneralManager ), |
|
1113 iConfigurationManager( aGeneralManager.ConfigurationManager() ), |
|
1114 iStorageManager( aGeneralManager.StorageManager() ), |
|
1115 iHttpSession( aHttpSession ), |
|
1116 iReportingMethod( MNcdServerReportManager::EReportingBackground ), |
|
1117 iReportingStyle( MNcdServerReportManager::EReportingStyleGeneral ), |
|
1118 iClientCrashed( aClientCrashed ) |
|
1119 { |
|
1120 } |
|
1121 |
|
1122 |
|
1123 // --------------------------------------------------------------------------- |
|
1124 // |
|
1125 // --------------------------------------------------------------------------- |
|
1126 void CNcdReportManager::ConstructL() |
|
1127 { |
|
1128 CActiveScheduler::Add( this ); |
|
1129 |
|
1130 iNetworkManager = &CCatalogsHttpSessionManager::NetworkManagerL(); |
|
1131 // observe changes in access points |
|
1132 iNetworkManager->AddObserverL( *this ); |
|
1133 LoadReportsL(); |
|
1134 } |
|
1135 |
|
1136 |
|
1137 // --------------------------------------------------------------------------- |
|
1138 // |
|
1139 // --------------------------------------------------------------------------- |
|
1140 CNcdReport* CNcdReportManager::FindReport( |
|
1141 const TNcdReportId& aReportId, |
|
1142 RNcdReportArray& aArray ) const |
|
1143 { |
|
1144 DLTRACEIN(("aReportId: %d", aReportId)); |
|
1145 for ( TInt i = 0; i < aArray.Count(); ++i ) |
|
1146 { |
|
1147 if ( aArray[i]->ReportId() == aReportId ) |
|
1148 { |
|
1149 return aArray[i]; |
|
1150 } |
|
1151 } |
|
1152 DLTRACEOUT(("Not found")); |
|
1153 return NULL; |
|
1154 } |
|
1155 |
|
1156 |
|
1157 // --------------------------------------------------------------------------- |
|
1158 // |
|
1159 // --------------------------------------------------------------------------- |
|
1160 CNcdReport* CNcdReportManager::FindReport( |
|
1161 const TDesC& aId, |
|
1162 const CNcdNodeIdentifier& aNodeId, |
|
1163 const TDesC& aReportUri, |
|
1164 const TNcdReportType& aReportType, |
|
1165 RNcdReportArray& aArray ) const |
|
1166 { |
|
1167 DLTRACEIN(( _L("aId: %S, report URI: %S"), &aId, &aReportUri )); |
|
1168 // Search backwards so that the newest & changeable report is found |
|
1169 TInt count = aArray.Count(); |
|
1170 while( count-- ) |
|
1171 { |
|
1172 if ( aArray[ count ]->Match( aNodeId, aId, aReportUri, aReportType ) ) |
|
1173 { |
|
1174 return aArray[ count ]; |
|
1175 } |
|
1176 } |
|
1177 DLTRACEOUT(("Not found")); |
|
1178 return NULL; |
|
1179 } |
|
1180 |
|
1181 |
|
1182 // --------------------------------------------------------------------------- |
|
1183 // State setter |
|
1184 // --------------------------------------------------------------------------- |
|
1185 void CNcdReportManager::SetManagerStateL( TNcdReportManagerState aState ) |
|
1186 { |
|
1187 DLTRACEIN(("aState: %d", aState)); |
|
1188 |
|
1189 iManagerState = aState; |
|
1190 switch ( iManagerState ) |
|
1191 { |
|
1192 case ENcdReportManagerPreparing: |
|
1193 { |
|
1194 ExecuteRunL( KErrNone ); |
|
1195 break; |
|
1196 } |
|
1197 |
|
1198 case ENcdReportManagerSending: |
|
1199 { |
|
1200 break; |
|
1201 } |
|
1202 |
|
1203 default: |
|
1204 { |
|
1205 break; |
|
1206 } |
|
1207 } |
|
1208 } |
|
1209 |
|
1210 |
|
1211 // --------------------------------------------------------------------------- |
|
1212 // Initiate report sending |
|
1213 // --------------------------------------------------------------------------- |
|
1214 void CNcdReportManager::SendReportsL() |
|
1215 { |
|
1216 DLTRACEIN(("")); |
|
1217 |
|
1218 DASSERT( !iTransactions.Count() ); |
|
1219 |
|
1220 // Update open connections so that IsAccessPointOpen is up-to-date |
|
1221 iNetworkManager->UpdateConnectionsL(); |
|
1222 |
|
1223 TBool defaultApIsOpen = iNetworkManager->IsAccessPointOpen( |
|
1224 DefaultConnectionMethod() ); |
|
1225 |
|
1226 for ( TInt i = 0; i < iReports.Count(); ++i ) |
|
1227 { |
|
1228 CNcdReport& report = *iReports[i]; |
|
1229 |
|
1230 if ( report.IsSendable() && ( |
|
1231 // either report has no AP set -> use default which has to be open |
|
1232 // or its AP needs to be open |
|
1233 ( defaultApIsOpen ) || |
|
1234 ( iNetworkManager->IsAccessPointOpen( report.ConnectionMethod() ) ) ) ) |
|
1235 { |
|
1236 if ( !iNetworkManager->IsAccessPointOpen( report.ConnectionMethod() ) ) |
|
1237 { |
|
1238 DLTRACE(("Using default ap for reporting")); |
|
1239 report.SetAccessPoint( DefaultConnectionMethod() ); |
|
1240 } |
|
1241 |
|
1242 MCatalogsHttpOperation* transaction = |
|
1243 iHttpSession.CreateTransactionL( |
|
1244 report.Attributes().AttributeString16( |
|
1245 ENcdReportAttributeReportUri ), this ); |
|
1246 |
|
1247 CleanupReleasePushL( *transaction ); |
|
1248 |
|
1249 if ( report.CanBundle() ) |
|
1250 { |
|
1251 BundleReportsL( i, *transaction ); |
|
1252 } |
|
1253 else |
|
1254 { |
|
1255 PrepareReportL( report, *transaction ); |
|
1256 } |
|
1257 |
|
1258 report.UpdateTransactionConfigL( *transaction ); |
|
1259 User::LeaveIfError( transaction->Start() ); |
|
1260 |
|
1261 iTransactions.InsertInAddressOrderL( transaction ); |
|
1262 CleanupStack::Pop( transaction ); |
|
1263 } |
|
1264 } |
|
1265 |
|
1266 // The operations that were created above, will call http callback functions |
|
1267 // of this class and the operation will be finished in FinishReportL function. |
|
1268 |
|
1269 // Check if the manager state should be set to idle or if we should |
|
1270 // let the state to be something else and wait for the HTTP operations |
|
1271 // that were created above to complete.. |
|
1272 if ( iTransactions.Count() == 0 ) |
|
1273 { |
|
1274 DLTRACE(("Nothing to send anymore.")); |
|
1275 // This will set the state and operation will not continue RunL loop |
|
1276 // any more. |
|
1277 SetManagerStateL( ENcdReportManagerIdle ); |
|
1278 |
|
1279 if ( iObserver != NULL ) |
|
1280 { |
|
1281 // Because observer was set for manager to know when managed operation |
|
1282 // was finished, inform the observer. |
|
1283 iObserver->OperationComplete( NULL, KErrNone ); |
|
1284 iObserver = NULL; |
|
1285 } |
|
1286 } |
|
1287 } |
|
1288 |
|
1289 |
|
1290 // --------------------------------------------------------------------------- |
|
1291 // Bundle reports |
|
1292 // --------------------------------------------------------------------------- |
|
1293 void CNcdReportManager::BundleReportsL( |
|
1294 TInt aIndex, |
|
1295 MCatalogsHttpOperation& aTransaction ) |
|
1296 { |
|
1297 DLTRACEIN(("Bundling reports from index %d onwards", aIndex )); |
|
1298 DASSERT( aIndex < iReports.Count() ); |
|
1299 |
|
1300 CNcdRequestInstallation* report = |
|
1301 NcdRequestGenerator::CreateInstallationReportRequestLC(); |
|
1302 |
|
1303 |
|
1304 CNcdReport& currentReport( *iReports[ aIndex ] ); |
|
1305 CNcdAttributes& att( currentReport.Attributes() ); |
|
1306 |
|
1307 report->SetNamespaceL( |
|
1308 att.AttributeString16( ENcdReportAttributeReportNamespace ) ); |
|
1309 |
|
1310 currentReport.AddReportDataL( *report ); |
|
1311 currentReport.SetReportTransaction( &aTransaction ); |
|
1312 |
|
1313 // Update report flags: beingSent = current status, |
|
1314 // latestSentReport = none, so we can identify cases were the same |
|
1315 // status is sent multiple times in a row (pause, pause...) |
|
1316 UpdateReportAttributesForSendingL( currentReport ); |
|
1317 |
|
1318 DLTRACE(("Start bundling, report count: %d", iReports.Count() )); |
|
1319 for ( TInt i = aIndex + 1; i < iReports.Count(); ++i ) |
|
1320 { |
|
1321 |
|
1322 TNcdReportBundleMatch bundle = CanBundleWithL( |
|
1323 currentReport, |
|
1324 *iReports[i] ); |
|
1325 |
|
1326 if ( bundle == ENcdReportBundleMatch && |
|
1327 iReports[i]->IsSendable() ) |
|
1328 { |
|
1329 DLTRACE(("Bundling report %d", i )); |
|
1330 iReports[i]->AddReportDataL( *report ); |
|
1331 iReports[i]->SetReportTransaction( &aTransaction ); |
|
1332 |
|
1333 // Update report status |
|
1334 UpdateReportAttributesForSendingL( *iReports[i] ); |
|
1335 } |
|
1336 else if ( bundle == ENcdReportBundleNoMatch ) |
|
1337 { |
|
1338 DLTRACE(("Nothing more to bundle, exit loop")); |
|
1339 break; |
|
1340 } |
|
1341 } |
|
1342 |
|
1343 DLTRACE(("Process report")); |
|
1344 HBufC8* body = |
|
1345 iGeneralManager.ProtocolManager().ProcessPreminetRequestL( |
|
1346 Context(), |
|
1347 *report, |
|
1348 att.AttributeString16( ENcdReportAttributeReportUri ), |
|
1349 ETrue ); |
|
1350 CleanupStack::PopAndDestroy( report ); |
|
1351 |
|
1352 CleanupStack::PushL( body ); |
|
1353 aTransaction.SetBodyL( *body ); |
|
1354 CleanupStack::PopAndDestroy( body ); |
|
1355 } |
|
1356 |
|
1357 |
|
1358 // --------------------------------------------------------------------------- |
|
1359 // Updates common attributes of the report for sending |
|
1360 // --------------------------------------------------------------------------- |
|
1361 void CNcdReportManager::UpdateReportAttributesForSendingL( |
|
1362 CNcdReport& aReport ) |
|
1363 { |
|
1364 DLTRACEIN(("")); |
|
1365 CNcdAttributes& att( aReport.Attributes() ); |
|
1366 |
|
1367 att.SetAttributeL( |
|
1368 ENcdReportAttributeReportBeingSent, |
|
1369 aReport.Status().iStatus ); |
|
1370 |
|
1371 att.SetAttributeL( |
|
1372 ENcdReportAttributeLatestSentReport, |
|
1373 ENcdReportNone ); |
|
1374 |
|
1375 att.SetAttributeL( |
|
1376 ENcdReportAttributeSendable, |
|
1377 EFalse ); |
|
1378 } |
|
1379 |
|
1380 // --------------------------------------------------------------------------- |
|
1381 // Check if reports can be bundled together |
|
1382 // --------------------------------------------------------------------------- |
|
1383 TNcdReportBundleMatch CNcdReportManager::CanBundleWithL( |
|
1384 const CNcdReport& aReport, |
|
1385 const CNcdReport& aReport2 ) const |
|
1386 { |
|
1387 DLTRACEIN(("")); |
|
1388 // Report URIs must match |
|
1389 if ( ( aReport.Attributes().AttributeString16( |
|
1390 ENcdReportAttributeReportUri ).Compare( |
|
1391 aReport2.Attributes().AttributeString16( |
|
1392 ENcdReportAttributeReportUri ) ) != 0 ) ) |
|
1393 { |
|
1394 DLTRACEOUT(("Can stop")); |
|
1395 return ENcdReportBundleNoMatch; |
|
1396 } |
|
1397 |
|
1398 if ( |
|
1399 // Report namespaces must match |
|
1400 ( aReport.Attributes().AttributeString16( |
|
1401 ENcdReportAttributeReportNamespace ).Compare( |
|
1402 aReport2.Attributes().AttributeString16( |
|
1403 ENcdReportAttributeReportNamespace ) ) == 0 ) |
|
1404 |
|
1405 && |
|
1406 // Report access points must match |
|
1407 ( CompareConnectionMethods( aReport, aReport2 ) ) ) |
|
1408 { |
|
1409 return ENcdReportBundleMatch; |
|
1410 } |
|
1411 |
|
1412 DLTRACEOUT(("")); |
|
1413 return ENcdReportBundleUriMatch; |
|
1414 } |
|
1415 |
|
1416 |
|
1417 // --------------------------------------------------------------------------- |
|
1418 // Prepare report for sending |
|
1419 // --------------------------------------------------------------------------- |
|
1420 void CNcdReportManager::PrepareReportL( |
|
1421 CNcdReport& aReport, |
|
1422 MCatalogsHttpOperation& aTransaction ) |
|
1423 { |
|
1424 DLTRACEIN(("")); |
|
1425 |
|
1426 aReport.SetReportTransaction( &aTransaction ); |
|
1427 |
|
1428 UpdateReportAttributesForSendingL( aReport ); |
|
1429 |
|
1430 HBufC8* body = aReport.CreateReportL(); |
|
1431 CleanupStack::PushL( body ); |
|
1432 DLINFO(( "body= %S", body )); |
|
1433 |
|
1434 aTransaction.SetBodyL( *body ); |
|
1435 CleanupStack::PopAndDestroy( body ); |
|
1436 } |
|
1437 |
|
1438 |
|
1439 // --------------------------------------------------------------------------- |
|
1440 // Complete request |
|
1441 // --------------------------------------------------------------------------- |
|
1442 void CNcdReportManager::ExecuteRunL( TInt aError ) |
|
1443 { |
|
1444 DLTRACEIN(("aError: %d", aError)); |
|
1445 |
|
1446 if ( !IsActive() ) |
|
1447 { |
|
1448 iStatus = KRequestPending; |
|
1449 SetActive(); |
|
1450 TRequestStatus* status = &iStatus; |
|
1451 User::RequestComplete( status, aError ); |
|
1452 } |
|
1453 } |
|
1454 |
|
1455 |
|
1456 // --------------------------------------------------------------------------- |
|
1457 // Generate a new report id |
|
1458 // --------------------------------------------------------------------------- |
|
1459 TNcdReportId CNcdReportManager::GenerateReportId() |
|
1460 { |
|
1461 DLTRACEIN(("")); |
|
1462 return iNewReportId++; |
|
1463 } |
|
1464 |
|
1465 |
|
1466 // --------------------------------------------------------------------------- |
|
1467 // |
|
1468 // --------------------------------------------------------------------------- |
|
1469 void CNcdReportManager::SetReportStatusL( |
|
1470 CNcdReport& aReport, |
|
1471 const TNcdReportStatusInfo& aStatus, |
|
1472 TBool aSendable ) |
|
1473 { |
|
1474 DLTRACEIN(("")); |
|
1475 aReport.SetStatus( aStatus ); |
|
1476 aReport.Attributes().SetAttributeL( |
|
1477 ENcdReportAttributeSendable, |
|
1478 aSendable ); |
|
1479 |
|
1480 SaveReportL( aReport ); |
|
1481 |
|
1482 // Start sending if the report is sendable and the manager isn't already |
|
1483 // sending. Also if the operation is not done in the background then do not |
|
1484 // do sending here. But, later when it is separately asked. |
|
1485 if ( aReport.IsSendable() && |
|
1486 iManagerState == ENcdReportManagerIdle && |
|
1487 iReportingMethod == MNcdServerReportManager::EReportingBackground ) |
|
1488 { |
|
1489 SetManagerStateL( ENcdReportManagerPreparing ); |
|
1490 } |
|
1491 } |
|
1492 |
|
1493 |
|
1494 // --------------------------------------------------------------------------- |
|
1495 // |
|
1496 // --------------------------------------------------------------------------- |
|
1497 TBool CNcdReportManager::CompareConnectionMethods( |
|
1498 const CNcdReport& aFirstReport, |
|
1499 const CNcdReport& aSecondReport ) const |
|
1500 { |
|
1501 DLTRACEIN(("")); |
|
1502 const TCatalogsConnectionMethod& first = aFirstReport.ConnectionMethod(); |
|
1503 const TCatalogsConnectionMethod& second = aSecondReport.ConnectionMethod(); |
|
1504 |
|
1505 switch( first.iType ) |
|
1506 { |
|
1507 case ECatalogsConnectionMethodTypeAlwaysAsk: |
|
1508 case ECatalogsConnectionMethodTypeDeviceDefault: // flow-through |
|
1509 { |
|
1510 if ( second.iType == first.iType ) |
|
1511 { |
|
1512 return ETrue; |
|
1513 } |
|
1514 break; |
|
1515 } |
|
1516 |
|
1517 case ECatalogsConnectionMethodTypeDestination: |
|
1518 { |
|
1519 if ( second.iType == ECatalogsConnectionMethodTypeDestination ) |
|
1520 { |
|
1521 return ( first.iId != 0 && first.iId == second.iId ) || |
|
1522 ( first.iApnId != 0 && first.iApnId == second.iApnId ); |
|
1523 } |
|
1524 break; |
|
1525 } |
|
1526 |
|
1527 case ECatalogsConnectionMethodTypeAccessPoint: |
|
1528 { |
|
1529 if ( second.iType == ECatalogsConnectionMethodTypeAccessPoint ) |
|
1530 { |
|
1531 return ( first.iId != 0 && first.iId == second.iId ); |
|
1532 } |
|
1533 break; |
|
1534 } |
|
1535 |
|
1536 default: |
|
1537 { |
|
1538 DASSERT( 0 ); |
|
1539 } |
|
1540 } |
|
1541 |
|
1542 return ( first.iApnId != 0 && first.iApnId == second.iApnId ); |
|
1543 } |