|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "pbapfoldernodech.h" |
|
17 #include "pbapfolderclient.h" |
|
18 #include "pbaperrorreporter.h" |
|
19 #include "pbapappheader.h" |
|
20 #include "pbapserver.h" |
|
21 #include "pbapchview.h" |
|
22 #include "pbapchexporter.h" |
|
23 |
|
24 #include "btaccesshostlog.h" |
|
25 |
|
26 |
|
27 // constants |
|
28 _LIT(KFolderIch, "ich"); |
|
29 _LIT(KFolderOch, "och"); |
|
30 _LIT(KFolderMch, "mch"); |
|
31 _LIT(KFolderCch, "cch"); |
|
32 |
|
33 |
|
34 CFolderNodeCallHistory::CFolderNodeCallHistory(MVirtualFolderClient& aClient, const TDesC& aFolderName, THistoryType aHistoryType) |
|
35 : CFolderNode(aClient, aFolderName), iHistoryType(aHistoryType), iPendingExport(ENoExport) |
|
36 { |
|
37 LOG_FUNC |
|
38 } |
|
39 |
|
40 // must be called by any class that inherits from CFolderNodeCallHistory |
|
41 void CFolderNodeCallHistory::ConstructL() |
|
42 { |
|
43 LOG_FUNC |
|
44 |
|
45 // create the view for this folder node |
|
46 iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags); |
|
47 } |
|
48 |
|
49 CFolderNodeCallHistory::~CFolderNodeCallHistory() |
|
50 { |
|
51 LOG_FUNC |
|
52 |
|
53 delete iAsyncExporter; |
|
54 delete iFolderView; |
|
55 delete iReadFolderView; |
|
56 } |
|
57 |
|
58 |
|
59 void CFolderNodeCallHistory::CancelGet() |
|
60 { |
|
61 LOG_FUNC |
|
62 |
|
63 // cancel any asynchronous export operations and avoid iAsyncExporter is deleted |
|
64 // by itself |
|
65 CPbapChExporter* tmpExporter = iAsyncExporter; |
|
66 iAsyncExporter = NULL; |
|
67 delete tmpExporter; |
|
68 |
|
69 delete iAppHeader; |
|
70 iAppHeader = NULL; |
|
71 } |
|
72 |
|
73 void CFolderNodeCallHistory::GetComplete() |
|
74 { |
|
75 LOG_FUNC |
|
76 |
|
77 if (iAsyncExporter) |
|
78 { |
|
79 delete iAsyncExporter; |
|
80 iAsyncExporter = NULL; |
|
81 } |
|
82 } |
|
83 |
|
84 TInt CFolderNodeCallHistory::DoExport(TExportType aExportType, TInt aHandle) |
|
85 { |
|
86 LOG_FUNC |
|
87 |
|
88 if(iAsyncExporter) |
|
89 { |
|
90 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists)); |
|
91 return KErrAlreadyExists; |
|
92 } |
|
93 |
|
94 |
|
95 TInt err = KErrNone; |
|
96 |
|
97 if ((aExportType == EExportItem) && (iCallHistoryChanged)) |
|
98 { |
|
99 // the Call History db has been modified since the last get request |
|
100 // report precondition failed error to obex until next listing |
|
101 // request completes (or new Pbap session initiated) |
|
102 iClient.ErrorReporter().SendPreconditionFailedError(); |
|
103 // error already reported above so don't update error |
|
104 |
|
105 delete iAppHeader; |
|
106 iAppHeader = NULL; |
|
107 } |
|
108 else if (iReadyToExport) |
|
109 { |
|
110 err = StartExport(aExportType, aHandle); |
|
111 } |
|
112 else |
|
113 { |
|
114 // views not ready, setup a pending export until they are |
|
115 if(iPendingExport != ENoExport) |
|
116 { |
|
117 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderExportAlreadyPending)); |
|
118 return KErrAlreadyExists; |
|
119 } |
|
120 |
|
121 if (!iFolderView) |
|
122 { |
|
123 // creating the folder view failed before, try again |
|
124 TRAP(err, iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags)); |
|
125 } |
|
126 |
|
127 // setup this export as pending until we are ready to export |
|
128 if (err == KErrNone) |
|
129 { |
|
130 iPendingExport = aExportType; |
|
131 iPendingHandle = aHandle; |
|
132 } |
|
133 } |
|
134 return err; |
|
135 } |
|
136 |
|
137 TInt CFolderNodeCallHistory::DoGetItem(TInt aHandle) |
|
138 { |
|
139 LOG_FUNC |
|
140 return DoExport(EExportItem, aHandle); |
|
141 } |
|
142 |
|
143 TInt CFolderNodeCallHistory::DoGetListing() |
|
144 { |
|
145 LOG_FUNC |
|
146 return DoExport(EExportListing); |
|
147 } |
|
148 |
|
149 TInt CFolderNodeCallHistory::DoGetCount() |
|
150 { |
|
151 LOG_FUNC |
|
152 return DoExport(EExportCount); |
|
153 } |
|
154 |
|
155 TInt CFolderNodeCallHistory::DoGetFolder() |
|
156 { |
|
157 LOG_FUNC |
|
158 return DoExport(EExportFolder); |
|
159 } |
|
160 |
|
161 void CFolderNodeCallHistory::HandleExportComplete(TInt aError) |
|
162 { |
|
163 LOG_FUNC |
|
164 |
|
165 if (aError == KErrNotFound && iAppHeader->Operation() == EPullVCard) |
|
166 { |
|
167 // must report not found to client if attempting to pull a vCard which |
|
168 // doesnot exist |
|
169 iClient.ErrorReporter().SendNotFoundError(); |
|
170 } |
|
171 else if (aError && iCallHistoryChanged) |
|
172 { |
|
173 iClient.ErrorReporter().SendPreconditionFailedError(); |
|
174 } |
|
175 else if (aError) |
|
176 { |
|
177 // error occured during export report service unavailable error to obex |
|
178 iClient.ErrorReporter().SendServiceUnavailableError(); |
|
179 } |
|
180 |
|
181 // a successful listing request allows the ch entries to be pulled again |
|
182 // after the database has been modified |
|
183 if (aError == KErrNone && iAppHeader->Operation() == EPullVCardListing) |
|
184 { |
|
185 iCallHistoryChanged = EFalse; |
|
186 } |
|
187 |
|
188 delete iAppHeader; |
|
189 iAppHeader = NULL; |
|
190 } |
|
191 |
|
192 |
|
193 void CFolderNodeCallHistory::CancelPendingExport(TInt err) |
|
194 { |
|
195 LOG_FUNC |
|
196 |
|
197 if (iPendingExport != ENoExport) |
|
198 { |
|
199 // complete the export with an error |
|
200 HandleExportComplete(err); |
|
201 |
|
202 // pending export done |
|
203 iPendingExport = ENoExport; |
|
204 } |
|
205 } |
|
206 |
|
207 TInt CFolderNodeCallHistory::StartExport(TExportType aExportType, TInt aHandle) |
|
208 { |
|
209 LOG_FUNC |
|
210 |
|
211 if(iAsyncExporter) |
|
212 { |
|
213 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists)); |
|
214 return KErrAlreadyExists; |
|
215 } |
|
216 if(iReadyToExport == EFalse) |
|
217 { |
|
218 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderNotReadyToExport)); |
|
219 return KErrNotReady; |
|
220 } |
|
221 if(!iFolderView) |
|
222 { |
|
223 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews)); |
|
224 return KErrNotFound; |
|
225 } |
|
226 |
|
227 TInt err = KErrNone; |
|
228 |
|
229 switch(aExportType) |
|
230 { |
|
231 case EExportItem: |
|
232 // aHandle is decremented here as the PBAP handles for call histories start at 1 and our event index starts at 0 |
|
233 TRAP(err, iAsyncExporter = CPbapChSingleItemExporter::NewL(iClient, *this, *iFolderView, aHandle - 1, iAppHeader->VCardVersion(), iAppHeader->Filter())); |
|
234 break; |
|
235 |
|
236 case EExportListing: |
|
237 TRAP(err, iAsyncExporter = CPbapChListingExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount())); |
|
238 break; |
|
239 |
|
240 case EExportCount: |
|
241 TRAP(err, iAsyncExporter = CPbapChCountExporter::NewL(iClient, *this, *iFolderView, iReadFolderView)); |
|
242 break; |
|
243 |
|
244 case EExportFolder: |
|
245 TRAP(err, iAsyncExporter = CPbapChItemExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount(), iAppHeader->VCardVersion(), iAppHeader->Filter())); |
|
246 break; |
|
247 |
|
248 case ENoExport: |
|
249 // nothing to do |
|
250 break; |
|
251 default: |
|
252 break; |
|
253 } |
|
254 return err; |
|
255 } |
|
256 |
|
257 // From MPbapChViewObserver. |
|
258 void CFolderNodeCallHistory::CallHistoryViewReady(TInt aError) |
|
259 { |
|
260 LOG_FUNC |
|
261 |
|
262 if(aError != KErrNone) |
|
263 { |
|
264 __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews)); |
|
265 } |
|
266 |
|
267 // assume we are ready to export unless we determine otherwise |
|
268 iReadyToExport = ETrue; |
|
269 |
|
270 // make sure that we have all the view required to be able to export |
|
271 if ((aError == KErrNone) && (iHistoryType == EMissed) && (!iReadFolderView)) |
|
272 { |
|
273 // create view of read missed events, used to determine the number of unread events |
|
274 TRAP(aError, iReadFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogEventRead)); |
|
275 |
|
276 if (aError == KErrNone) |
|
277 { |
|
278 // we will be notified again when the read missed events view is ready so wait for |
|
279 // that notification before we are ready to export |
|
280 iReadyToExport = EFalse; |
|
281 } |
|
282 else |
|
283 { |
|
284 // log error but still allow exports to take place, they will just not include the |
|
285 // new unread event count in any export |
|
286 LOG1(_L("Failed to create read missed call view, error: %d"), aError); |
|
287 } |
|
288 } |
|
289 else if (aError != KErrNone) |
|
290 { |
|
291 if (iReadFolderView) |
|
292 { |
|
293 // log error but still allow exports to take place, they will just not include the |
|
294 // new unread event count in any export |
|
295 LOG1(_L("Failed to create read missed call view, error: %d"), aError); |
|
296 |
|
297 delete iReadFolderView; |
|
298 iReadFolderView = NULL; |
|
299 } |
|
300 else |
|
301 { |
|
302 // log error and attempt to create views again on next export |
|
303 LOG1(_L("Failed to create folder call history view, error: %d"), aError); |
|
304 |
|
305 delete iFolderView; |
|
306 iFolderView = NULL; |
|
307 |
|
308 iReadyToExport = EFalse; |
|
309 CancelPendingExport(aError); |
|
310 } |
|
311 } |
|
312 |
|
313 // check for any pending exports |
|
314 if ((iReadyToExport) && (iPendingExport != ENoExport)) |
|
315 { |
|
316 aError = StartExport(iPendingExport, iPendingHandle); |
|
317 |
|
318 if (aError != KErrNone) |
|
319 { |
|
320 // complete the export with an error |
|
321 HandleExportComplete(aError); |
|
322 } |
|
323 |
|
324 // pending export done |
|
325 iPendingExport = ENoExport; |
|
326 } |
|
327 } |
|
328 |
|
329 void CFolderNodeCallHistory::CallHistoryChangeNotification(TBool aViewReady) |
|
330 { |
|
331 LOG_FUNC |
|
332 |
|
333 // Force the PCE to issue a PullvCardListing before we will respond to another |
|
334 // PullvCardEntry request for this folder |
|
335 iCallHistoryChanged = ETrue; |
|
336 |
|
337 // check to see if there is an export in progress |
|
338 if (iAsyncExporter) |
|
339 { |
|
340 // cancel the export and report error according to the error reporting |
|
341 // scheme for modified/deleted handles |
|
342 CancelGet(); |
|
343 } |
|
344 |
|
345 // the view may need refreshing after a change and therefore we are ready to |
|
346 // export if the view is ready to use. If not, then we will get notification |
|
347 // via the CallHistoryViewReady callback |
|
348 iReadyToExport = aViewReady; |
|
349 } |
|
350 |
|
351 |
|
352 // |
|
353 // CFolderNodeIch |
|
354 // |
|
355 /*static*/ CFolderNodeIch* CFolderNodeIch::NewL(MVirtualFolderClient& aClient) |
|
356 { |
|
357 LOG_STATIC_FUNC |
|
358 CFolderNodeIch* self = new (ELeave) CFolderNodeIch(aClient); |
|
359 CleanupStack::PushL(self); |
|
360 self->ConstructL(); |
|
361 CleanupStack::Pop(self); |
|
362 return self; |
|
363 } |
|
364 |
|
365 CFolderNodeIch::CFolderNodeIch(MVirtualFolderClient& aClient) |
|
366 : CFolderNodeCallHistory(aClient, KFolderIch(), EIncoming) |
|
367 { |
|
368 LOG_FUNC |
|
369 } |
|
370 |
|
371 |
|
372 // |
|
373 // CFolderNodeOch |
|
374 // |
|
375 /*static*/ CFolderNodeOch* CFolderNodeOch::NewL(MVirtualFolderClient& aClient) |
|
376 { |
|
377 LOG_STATIC_FUNC |
|
378 CFolderNodeOch* self = new (ELeave) CFolderNodeOch(aClient); |
|
379 CleanupStack::PushL(self); |
|
380 self->ConstructL(); |
|
381 CleanupStack::Pop(self); |
|
382 return self; |
|
383 } |
|
384 |
|
385 CFolderNodeOch::CFolderNodeOch(MVirtualFolderClient& aClient) |
|
386 : CFolderNodeCallHistory(aClient, KFolderOch(), EOutgoing) |
|
387 { |
|
388 LOG_FUNC |
|
389 } |
|
390 |
|
391 |
|
392 // |
|
393 // CFolderNodeMch |
|
394 // |
|
395 /*static*/ CFolderNodeMch* CFolderNodeMch::NewL(MVirtualFolderClient& aClient) |
|
396 { |
|
397 LOG_STATIC_FUNC |
|
398 CFolderNodeMch* self = new (ELeave) CFolderNodeMch(aClient); |
|
399 CleanupStack::PushL(self); |
|
400 self->ConstructL(); |
|
401 CleanupStack::Pop(self); |
|
402 return self; |
|
403 } |
|
404 |
|
405 CFolderNodeMch::CFolderNodeMch(MVirtualFolderClient& aClient) |
|
406 : CFolderNodeCallHistory(aClient, KFolderMch(), EMissed) |
|
407 { |
|
408 LOG_FUNC |
|
409 } |
|
410 |
|
411 |
|
412 // |
|
413 // CFolderNodeCch |
|
414 // |
|
415 /*static*/ CFolderNodeCch* CFolderNodeCch::NewL(MVirtualFolderClient& aClient) |
|
416 { |
|
417 LOG_STATIC_FUNC |
|
418 CFolderNodeCch* self = new (ELeave) CFolderNodeCch(aClient); |
|
419 CleanupStack::PushL(self); |
|
420 self->ConstructL(); |
|
421 CleanupStack::Pop(self); |
|
422 return self; |
|
423 } |
|
424 |
|
425 CFolderNodeCch::CFolderNodeCch(MVirtualFolderClient& aClient) |
|
426 : CFolderNodeCallHistory(aClient, KFolderCch(), ECombined) |
|
427 { |
|
428 LOG_FUNC |
|
429 } |