|
1 /* |
|
2 * Copyright (c) 2007-2009 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 /** |
|
20 @file |
|
21 @internalComponent |
|
22 */ |
|
23 |
|
24 #include "ccntmsghandler.h" |
|
25 #include "ccntmsghandlerfptr.h" |
|
26 #include "ccntviewmsghandler.h" |
|
27 |
|
28 #include "ccntrequest.h" |
|
29 #include "ccntserver.h" |
|
30 #include "ccntpackager.h" |
|
31 #include "ccntipccodes.h" |
|
32 #include "cviewsubsessions.h" |
|
33 |
|
34 const TInt KCntViewIpcCodes[] = |
|
35 { |
|
36 ECntItemAtL, |
|
37 ECntReadContactTextDef, |
|
38 ECntTextField, |
|
39 ECntOpenViewSession, |
|
40 ECntCloseViewSession, |
|
41 ECntViewChangeSortOrderL, |
|
42 ECntViewBeginIterate, |
|
43 ECntViewEndIterate, |
|
44 ECntViewNextItemL, |
|
45 ECntCreateView, |
|
46 ECntCreateNamedView, |
|
47 ECntCloseView, |
|
48 ECntMatchesHintField |
|
49 }; |
|
50 |
|
51 CCntViewMsgHandler* CCntViewMsgHandler::NewLC(CCntSession& aSession) |
|
52 { |
|
53 CCntViewMsgHandler* self = new (ELeave) CCntViewMsgHandler(aSession); |
|
54 CleanupStack::PushL(self); |
|
55 self->ConstructorL(); |
|
56 return self; |
|
57 } |
|
58 |
|
59 void CCntViewMsgHandler::ConstructorL() |
|
60 { |
|
61 iSubSessions=CObjectIx::NewL(); |
|
62 } |
|
63 |
|
64 CCntViewMsgHandler::CCntViewMsgHandler(CCntSession& aSession) |
|
65 :CCntMsgHandler(aSession) |
|
66 { |
|
67 } |
|
68 |
|
69 CCntViewMsgHandler::~CCntViewMsgHandler() |
|
70 { |
|
71 delete iSubSessions; |
|
72 |
|
73 /* Remove container from server. CServer2 instance which created session object exists! **/ |
|
74 if(iContainer) |
|
75 { |
|
76 Server().RemoveObjectContainer(*iContainer); |
|
77 } |
|
78 } |
|
79 |
|
80 /** |
|
81 Delegates the incoming op code to a message handling method. |
|
82 |
|
83 First checks if this class services the op code, it then uses the lookup table and finds |
|
84 function pointer(to message handling method) mapped to the incoming message function (op code) |
|
85 and finally delegates the message to handling method. |
|
86 |
|
87 It leaves with KErrNotFound if op code not handled. |
|
88 */ |
|
89 TInt CCntViewMsgHandler::HandleMessageL(const RMessage2& aMessage) |
|
90 { |
|
91 MsgHandlerFptr func_ptr = LookupHandlerMethodL(aMessage.Function(), KCntViewIpcCodes, sizeof(KCntViewIpcCodes)/sizeof(TInt)); |
|
92 |
|
93 if(func_ptr) |
|
94 { |
|
95 ViewMsgHandlerFptr mem_func_ptr = static_cast<ViewMsgHandlerFptr>(func_ptr); |
|
96 (this->*mem_func_ptr)(aMessage); |
|
97 return (KErrNone); |
|
98 } |
|
99 |
|
100 /** Other opcodes processed by view subsession ServiceL() method. |
|
101 View subsession ServiceL() leaves with KErrNotFound if opcode not consumed. |
|
102 */ |
|
103 ViewSubSessionServiceL(aMessage); |
|
104 return (KErrNone); |
|
105 } |
|
106 |
|
107 void CCntViewMsgHandler::CreateViewSubSessionL(const RMessage2& aMessage) |
|
108 { |
|
109 CheckForManagerL(); |
|
110 TObjectCleanup* cleanupData=new(ELeave) TObjectCleanup(); |
|
111 CleanupStack::PushL(TCleanupItem(TObjectCleanup::Cleanup,cleanupData)); |
|
112 CViewSubSession* subSession=CViewSubSession::NewL(iManager->ViewManagerL(),aMessage); |
|
113 cleanupData->iObject=subSession; |
|
114 |
|
115 if(iContainer == NULL) |
|
116 { |
|
117 //Have to get new container after contruction, as CSession2::Server() always |
|
118 //returns empty pointer in contructor. |
|
119 iContainer = Server().NewContainerL(); |
|
120 } |
|
121 iContainer->AddL(subSession); |
|
122 TInt handle=iSubSessions->AddL(subSession); |
|
123 cleanupData->iIndex=iSubSessions; |
|
124 cleanupData->iHandle=handle; |
|
125 TPckg<TInt> handlePckg(handle); |
|
126 aMessage.WriteL(3,handlePckg); |
|
127 CleanupStack::Pop(); // The TCleanupItem. |
|
128 delete cleanupData; |
|
129 } |
|
130 |
|
131 void CCntViewMsgHandler::CreateNamedViewSubSessionL(const RMessage2& aMessage) |
|
132 { |
|
133 CheckForManagerL(); |
|
134 TObjectCleanup* cleanupData=new(ELeave) TObjectCleanup(); |
|
135 CleanupStack::PushL(TCleanupItem(TObjectCleanup::Cleanup,cleanupData)); |
|
136 CNamedViewSubSession* subSession=CNamedViewSubSession::NewL(iManager->ViewManagerL(),aMessage); |
|
137 cleanupData->iObject=subSession; |
|
138 if(iContainer == NULL) |
|
139 { |
|
140 //Have to get new container after contruction, as CSession2::Server() always |
|
141 //returns empty pointer in contructor. |
|
142 iContainer = Server().NewContainerL(); |
|
143 } |
|
144 iContainer->AddL(subSession); |
|
145 TInt handle=iSubSessions->AddL(subSession); |
|
146 cleanupData->iIndex=iSubSessions; |
|
147 cleanupData->iHandle=handle; |
|
148 TPckg<TInt> handlePckg(handle); |
|
149 aMessage.WriteL(3,handlePckg); |
|
150 CleanupStack::Pop(); // The TCleanupItem. |
|
151 delete cleanupData; |
|
152 } |
|
153 |
|
154 void CCntViewMsgHandler::CloseViewSubSessionL(const RMessage2 &aMessage) |
|
155 { |
|
156 const TInt handle=aMessage.Int3(); |
|
157 ViewFromHandleL(handle); // To panic client if passed a bad handle. |
|
158 iSubSessions->Remove(handle); |
|
159 } |
|
160 |
|
161 CViewSubSessionBase& CCntViewMsgHandler::ViewFromHandleL(TUint aHandle) |
|
162 { |
|
163 CViewSubSessionBase* subSession = STATIC_CAST(CViewSubSessionBase*,iSubSessions->At(aHandle)); |
|
164 if (subSession==NULL) |
|
165 { |
|
166 User::Leave(KErrBadHandle); // Will result in client getting panic'd. |
|
167 } |
|
168 return *subSession; |
|
169 } |
|
170 |
|
171 void CCntViewMsgHandler::CompleteMessage(TInt aRet, const RMessage2& aMessage) |
|
172 { |
|
173 if(aRet != KErrNoComplete) |
|
174 { |
|
175 aMessage.Complete(aRet); |
|
176 } |
|
177 } |
|
178 |
|
179 /** |
|
180 Message handling methods. |
|
181 */ |
|
182 void CCntViewMsgHandler::ReadContactTextDefL(const RMessage2& aMessage) |
|
183 { |
|
184 TInt ret(KErrNone); |
|
185 CheckForManagerL(); |
|
186 const TInt receivingBufLen = aMessage.GetDesMaxLength(1); |
|
187 // We cannot return anything, so we can complete the request |
|
188 // immediately. |
|
189 if (receivingBufLen == 0) |
|
190 { |
|
191 aMessage.Complete(ret); |
|
192 return; |
|
193 } |
|
194 // Read CContactTextDef from packager buffer. |
|
195 iPackager.SetBufferFromMessageL(aMessage); |
|
196 // Packager reads from message slot 0. |
|
197 CContactTextDef* textDef = iPackager.UnpackCntTextDefLC(); |
|
198 |
|
199 // Get the iterator manager reference from Persistence Layer. |
|
200 MLplViewIteratorManager& iterManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
201 |
|
202 HBufC* buf = HBufC::NewLC(receivingBufLen); |
|
203 TPtr ptr(const_cast<TUint16*>(buf->Ptr()), receivingBufLen); |
|
204 |
|
205 TInt contactId = aMessage.Int2(); |
|
206 TUid typeUid = iterManager.ReadContactTextDefL(contactId, ptr, *textDef); |
|
207 if(typeUid == KUidContactICCEntry) |
|
208 { |
|
209 MLplPersistenceLayerFactory& factory = iManager->GetPersistenceLayer().FactoryL(); |
|
210 User::LeaveIfError(factory.GetContactSynchroniserL(iSessionId).ValidateContact(MContactSynchroniser::ERead, contactId)); |
|
211 } |
|
212 |
|
213 aMessage.WriteL(1,ptr); |
|
214 CleanupStack::PopAndDestroy(2, textDef); //buf |
|
215 aMessage.Complete(ret); |
|
216 } |
|
217 |
|
218 void CCntViewMsgHandler::TextFieldL(const RMessage2& aMessage) |
|
219 { |
|
220 TInt ret(KErrNone); |
|
221 CheckForManagerL(); |
|
222 MLplViewIteratorManager& iterManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
223 TPckgBuf<TFieldType> package; |
|
224 aMessage.ReadL(1, package); |
|
225 TBuf<64> field; |
|
226 iterManager.TextFieldL(aMessage.Int0(),package(),field); |
|
227 aMessage.WriteL(2,field); |
|
228 aMessage.Complete(ret); |
|
229 } |
|
230 |
|
231 void CCntViewMsgHandler::ValidateViewContactL(const CViewContact& aViewContact, TInt aSessionId) |
|
232 { |
|
233 // If the contact is an ICC entry (held on the phone's SIM), ensure we have |
|
234 // read permission. |
|
235 if(aViewContact.ContactTypeUid() == KUidContactICCEntry) |
|
236 { |
|
237 MLplPersistenceLayerFactory& factory = iManager->GetPersistenceLayer().FactoryL(); |
|
238 User::LeaveIfError(factory.GetContactSynchroniserL(aSessionId).ValidateContact(MContactSynchroniser::ERead, aViewContact.Id())); |
|
239 } |
|
240 } |
|
241 |
|
242 /* |
|
243 Maps to RCntModel::ItemAtL() method. Use real Persistence Layer this side. |
|
244 Call the Persistence Layer view item manager directly. |
|
245 **/ |
|
246 void CCntViewMsgHandler::ItemAtL(const RMessage2& aMessage) |
|
247 { |
|
248 TInt ret(KErrNone); |
|
249 CheckForManagerL(); |
|
250 |
|
251 // Get the pl view item manager reference from persistence layer |
|
252 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
253 |
|
254 // Persistence layer call |
|
255 CViewContact* viewContact = viewManager.ItemAtL(aMessage.Int0(), aMessage.Int1()); |
|
256 // Don't write NULL back across IPC. |
|
257 // Leave KErrNotFound will be picked up by client and propagated as NULL to caller |
|
258 if(viewContact == NULL) |
|
259 { |
|
260 User::Leave(KErrNotFound); |
|
261 } |
|
262 |
|
263 CleanupStack::PushL(viewContact); |
|
264 |
|
265 ValidateViewContactL(*viewContact, iSessionId); |
|
266 |
|
267 // Compare with maximum length of descriptor argument in the client's process. |
|
268 if(viewContact->ExternalizedSize() > aMessage.GetDesMaxLength(2) ) |
|
269 { |
|
270 // Return required size of buffer to the client. |
|
271 aMessage.Complete(viewContact->ExternalizedSize()); |
|
272 ret = KErrNoComplete; |
|
273 } |
|
274 else |
|
275 { |
|
276 // Packager's buffer large enough so write back CViewContact. |
|
277 TPtr8 ptr = iPackager.PackL(*viewContact); |
|
278 aMessage.WriteL(2,ptr); |
|
279 } |
|
280 |
|
281 CleanupStack::PopAndDestroy(viewContact); |
|
282 CompleteMessage(ret, aMessage); |
|
283 } |
|
284 |
|
285 /* |
|
286 Maps to RCntModel::OpenViewL() method. Use real Persistence Layer this side. |
|
287 Call the Persistence Layer view item manager directly. |
|
288 **/ |
|
289 void CCntViewMsgHandler::OpenViewSessionL(const RMessage2& aMessage) |
|
290 { |
|
291 CheckForManagerL(); |
|
292 |
|
293 // Read CContactTextDef from packager buffer |
|
294 iPackager.SetBufferFromMessageL(aMessage); |
|
295 // Packager reads from message slot 0 |
|
296 CContactTextDef* textDef = iPackager.UnpackCntTextDefLC(); |
|
297 |
|
298 // Get the pl view item manager reference from persistence layer |
|
299 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
300 |
|
301 // Persistence layer call |
|
302 TInt viewSessionId = viewManager.OpenViewL(*textDef, static_cast<TContactViewPreferences>(aMessage.Int1())); |
|
303 CleanupStack::PopAndDestroy(textDef); |
|
304 |
|
305 TPckg<TInt> idPckg(viewSessionId); |
|
306 aMessage.WriteL(2,idPckg); |
|
307 |
|
308 aMessage.Complete(KErrNone); |
|
309 } |
|
310 |
|
311 /* |
|
312 Maps to RCntModel::CloseView() method. Use real Persistence Layer this side. |
|
313 Call the Persistence Layer view item manager directly. |
|
314 **/ |
|
315 void CCntViewMsgHandler::CloseViewSessionL(const RMessage2& aMessage) |
|
316 { |
|
317 CheckForManagerL(); |
|
318 |
|
319 // Get the pl view item manager reference from persistence layer |
|
320 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
321 |
|
322 // Persistence layer call |
|
323 viewManager.CloseView(aMessage.Int0()); |
|
324 aMessage.Complete(KErrNone); |
|
325 } |
|
326 |
|
327 void CCntViewMsgHandler::ChangeSortOrderL(const RMessage2& aMessage) |
|
328 { |
|
329 CheckForManagerL(); |
|
330 |
|
331 // Read CContactTextDef from packager buffer, packager reads from message slot 1 |
|
332 iPackager.SetBufferFromMessageL(aMessage, 1); |
|
333 CContactTextDef* textDef = iPackager.UnpackCntTextDefLC(); |
|
334 |
|
335 // Get the pl view item manager reference from persistence layer |
|
336 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
337 |
|
338 // Persistence layer call |
|
339 viewManager.ChangeSortOrderL(aMessage.Int0(), *textDef); |
|
340 CleanupStack::PopAndDestroy(textDef); |
|
341 |
|
342 aMessage.Complete(KErrNone); |
|
343 } |
|
344 |
|
345 void CCntViewMsgHandler::BeginIterateL(const RMessage2& aMessage) |
|
346 { |
|
347 CheckForManagerL(); |
|
348 |
|
349 // Get the pl view item manager reference from persistence layer |
|
350 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
351 viewManager.BeginIterateL(aMessage.Int0()); |
|
352 aMessage.Complete(KErrNone); |
|
353 } |
|
354 |
|
355 void CCntViewMsgHandler::EndIterateL(const RMessage2& aMessage) |
|
356 { |
|
357 CheckForManagerL(); |
|
358 |
|
359 // Get the pl view item manager reference from persistence layer |
|
360 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
361 viewManager.EndIterateL(aMessage.Int0()); |
|
362 aMessage.Complete(KErrNone); |
|
363 } |
|
364 |
|
365 void CCntViewMsgHandler::NextItemL(const RMessage2& aMessage) |
|
366 { |
|
367 TInt ret(KErrNone); |
|
368 CheckForManagerL(); |
|
369 |
|
370 // Get the pl view item manager reference from persistence layer |
|
371 MLplViewIteratorManager& viewManager = iManager->GetPersistenceLayer().FactoryL().GetViewIteratorManagerL(); |
|
372 |
|
373 // Persistence layer call |
|
374 CViewContact* viewContact = viewManager.NextItemL(aMessage.Int0(), static_cast<TContactViewPreferences>(aMessage.Int1())); |
|
375 |
|
376 // Don't write NULL back across IPC. |
|
377 // Leave KErrNotFound will be picked up by client and propagated as NULL to caller |
|
378 if(viewContact == NULL) |
|
379 { |
|
380 User::Leave(KErrNotFound); |
|
381 } |
|
382 |
|
383 CleanupStack::PushL(viewContact); |
|
384 |
|
385 ValidateViewContactL(*viewContact, iSessionId); |
|
386 |
|
387 // Compare with maximum length of descriptor argument in the client's process. |
|
388 if(viewContact->ExternalizedSize() > aMessage.GetDesMaxLength(2) ) |
|
389 { |
|
390 // Return required size of buffer to the client. |
|
391 aMessage.Complete(viewContact->ExternalizedSize()); |
|
392 ret = KErrNoComplete; |
|
393 } |
|
394 else |
|
395 { |
|
396 // Packager's buffer large enough so write back CViewContact. |
|
397 TPtr8 ptr = iPackager.PackL(*viewContact); |
|
398 aMessage.WriteL(2,ptr); |
|
399 } |
|
400 |
|
401 CleanupStack::PopAndDestroy(viewContact); |
|
402 CompleteMessage(ret, aMessage); |
|
403 } |
|
404 |
|
405 void CCntViewMsgHandler::CreateViewL(const RMessage2& aMessage) |
|
406 { |
|
407 // Subsession create anonymous view from client. Create subsession |
|
408 // objects on demand. |
|
409 TInt ret(KErrNone); |
|
410 CreateViewSubSessionL(aMessage); |
|
411 aMessage.Complete(ret); |
|
412 } |
|
413 |
|
414 void CCntViewMsgHandler::CreateNamedViewL(const RMessage2& aMessage) |
|
415 { |
|
416 // Subsession create named view from client. Create subsession |
|
417 // objects on demand. |
|
418 TInt ret(KErrNone); |
|
419 CreateNamedViewSubSessionL(aMessage); |
|
420 aMessage.Complete(ret); |
|
421 } |
|
422 |
|
423 void CCntViewMsgHandler::CloseViewL(const RMessage2& aMessage) |
|
424 { |
|
425 // Subsession close view from client. |
|
426 |
|
427 TInt ret(KErrNone); |
|
428 CloseViewSubSessionL(aMessage); |
|
429 aMessage.Complete(ret); |
|
430 } |
|
431 |
|
432 void CCntViewMsgHandler::MatchesHintFieldL(const RMessage2& aMessage) |
|
433 { |
|
434 // Maps to RCntModel::ContactMatchesHintFieldL(). |
|
435 |
|
436 TInt ret(KErrNone); |
|
437 CheckForManagerL(); |
|
438 TInt bitWiseFilter = aMessage.Int0(); |
|
439 TContactItemId cntId = aMessage.Int1(); |
|
440 ret = iManager->GetPersistenceLayer().FactoryL().GetCollectorL().ContactMatchesHintFieldL(bitWiseFilter, cntId); |
|
441 CompleteMessage(ret, aMessage); |
|
442 } |
|
443 |
|
444 void CCntViewMsgHandler::ViewSubSessionServiceL(const RMessage2& aMessage) |
|
445 { |
|
446 // Other opcodes processed by view subsession ServiceL() method. |
|
447 |
|
448 TInt ret(KErrNone); |
|
449 ret = ViewFromHandleL(aMessage.Int3()).ServiceL(aMessage); |
|
450 CompleteMessage(ret, aMessage); |
|
451 } |
|
452 |