|
1 // Copyright (c) 2007-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 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include "CCntMsgHandler.h" |
|
22 #include "CCntMsgHandlerFptr.h" |
|
23 #include "CCntFileManagerMsgHandler.h" |
|
24 |
|
25 #include "CCntServer.h" |
|
26 #include "CCntSession.h" |
|
27 #include "CCntIpcCodes.h" |
|
28 #include "CCntRequest.h" |
|
29 #include "CCntDbManager.h" |
|
30 #include "CCntStateMachine.h" |
|
31 #include "CCntDbManagerController.h" |
|
32 #include "CCntPackager.h" |
|
33 #include "CCntIpcCodes.h" |
|
34 #include <cntviewstore.h> |
|
35 #include "cntviewprivate.h" |
|
36 #include "CViewSubSessions.h" |
|
37 |
|
38 const TInt KCntFileManagerIpcCodes[] = |
|
39 { |
|
40 ECntOpenDataBase, |
|
41 ECntCreateDatabase, |
|
42 ECntReplaceDatabase, |
|
43 ECntCancelAsyncOpenDatabase, |
|
44 ECntCloseDataBase, |
|
45 ECntCloseDbTables, |
|
46 ECntReOpenDbTables, |
|
47 ECntDeleteDatabase, |
|
48 ECntGetDefaultDatabaseName, |
|
49 ECntDatabaseDrive, |
|
50 ECntSetDatabaseDrive, |
|
51 ECntDatabaseExists, |
|
52 ECntListDatabases, |
|
53 ECntGetDatabaseReady, |
|
54 ECntFetchTemplateIds, |
|
55 ECntFetchGroupIdLists, |
|
56 ECntFilesSize, |
|
57 ECntGetDefinitionsForExistingView |
|
58 }; |
|
59 |
|
60 CCntFileManagerMsgHandler* CCntFileManagerMsgHandler::NewLC(CCntSession& aSession) |
|
61 { |
|
62 CCntFileManagerMsgHandler* CntFileManagerMsgHandler = new (ELeave) CCntFileManagerMsgHandler(aSession); |
|
63 CleanupStack::PushL(CntFileManagerMsgHandler); |
|
64 return CntFileManagerMsgHandler; |
|
65 } |
|
66 |
|
67 |
|
68 CCntFileManagerMsgHandler::CCntFileManagerMsgHandler(CCntSession& aSession) |
|
69 :CCntMsgHandler(aSession) |
|
70 { |
|
71 } |
|
72 |
|
73 CCntFileManagerMsgHandler::~CCntFileManagerMsgHandler() |
|
74 { |
|
75 } |
|
76 |
|
77 /** |
|
78 Delegates the incoming op code to a message handling method. |
|
79 |
|
80 First checks if this class services the op code, it then uses the lookup table and finds |
|
81 function pointer(to message handling method) mapped to the incoming message function (op code) |
|
82 and finally delegates the message to handling method. |
|
83 |
|
84 It returns KErrNotFound if op code not handled. |
|
85 */ |
|
86 TInt CCntFileManagerMsgHandler::HandleMessageL(const RMessage2& aMessage) |
|
87 { |
|
88 MsgHandlerFptr func_ptr = LookupHandlerMethodL(aMessage.Function(), KCntFileManagerIpcCodes, sizeof(KCntFileManagerIpcCodes)/sizeof(TInt)); |
|
89 |
|
90 if(func_ptr) |
|
91 { |
|
92 FileManagerMsgHandlerFptr mem_func_ptr = static_cast<FileManagerMsgHandlerFptr>(func_ptr); |
|
93 (this->*mem_func_ptr)(aMessage); |
|
94 return (KErrNone); |
|
95 } |
|
96 |
|
97 return (KErrNotFound); |
|
98 } |
|
99 |
|
100 /** |
|
101 This method contains all database file open/create/replace functionality. |
|
102 */ |
|
103 void CCntFileManagerMsgHandler::FileOpenCreateReplaceL(const RMessage2& aMessage, TCntFileMode aMode) |
|
104 { |
|
105 // Sanity check: there can be only one CCntDbManager instance per session. |
|
106 if(iManager) |
|
107 { |
|
108 aMessage.Complete(KErrAlreadyExists); |
|
109 return; |
|
110 } |
|
111 |
|
112 CReqAsyncOpen* openReq = CReqAsyncOpen::NewLC(iSessionId, aMessage, iTimeOut); |
|
113 |
|
114 // Get an instance of the CCntDbManager class for this file. One instance |
|
115 // is created per Contacts database file and shared among sessions using |
|
116 // that file. |
|
117 iManager = Server().Controller().GetDbManagerL(openReq->FileName(), aMode); |
|
118 |
|
119 // Register this session as a database event observer. |
|
120 iManager->RegisterDatabaseEventObserverL(iSession); |
|
121 |
|
122 // Process the open request via the State Machine. The State Machine |
|
123 // ensures that the file (owned by the CCntDbManager instance) is in a valid |
|
124 // state to process the request. |
|
125 iManager->StateMachineL().ProcessRequestL(openReq); // ownership transferred |
|
126 |
|
127 // ProcessRequestL received ownership of the request, the request only need |
|
128 // to be popped from CleanupStack. |
|
129 CleanupStack::Pop(openReq); |
|
130 } |
|
131 |
|
132 #if defined(_DEBUG) |
|
133 void CCntFileManagerMsgHandler::DefinitionsOfExistingViewsL(const RMessage2& aMessage) |
|
134 { |
|
135 TFileName fileName; |
|
136 ReadL(aMessage,KSlot0,fileName); |
|
137 if (fileName.Length() == 0) |
|
138 { |
|
139 Server().Controller().DefaultDatabaseL(fileName); |
|
140 } |
|
141 |
|
142 RPointerArray<CContactDefaultViewDefinition> viewDefs; |
|
143 CleanupResetAndDestroyPushL(viewDefs); |
|
144 CCntDbManager* manager = Server().Controller().DbManagerL(fileName); |
|
145 if (manager) |
|
146 { |
|
147 manager->ViewManagerL().GetDefinitionsOfExistingViewsL(viewDefs); |
|
148 } |
|
149 |
|
150 // Compute the size of the buffer that is needed. |
|
151 CBufFlat* buffer = CBufFlat::NewL(32); |
|
152 CleanupStack::PushL(buffer); |
|
153 RBufWriteStream writeStream(*buffer); |
|
154 CleanupClosePushL(writeStream); |
|
155 |
|
156 const TInt32 count = viewDefs.Count(); |
|
157 writeStream << count; |
|
158 for (TInt i = 0; i < count; i++) |
|
159 { |
|
160 writeStream << *viewDefs[i]; |
|
161 } |
|
162 |
|
163 // Check that the client-side write buffer is large enough. |
|
164 TInt length = buffer->Size(); |
|
165 if(aMessage.GetDesMaxLength(1) >= length) |
|
166 { |
|
167 aMessage.WriteL(1, buffer->Ptr(0)); |
|
168 aMessage.Complete(KErrNone); |
|
169 } |
|
170 else |
|
171 { |
|
172 aMessage.Complete(length); |
|
173 } |
|
174 CleanupStack::PopAndDestroy(3, &viewDefs); // writeStream, buffer, viewDefs |
|
175 } |
|
176 #else |
|
177 void CCntFileManagerMsgHandler::DefinitionsOfExistingViewsL(const RMessage2& aMessage) |
|
178 { |
|
179 aMessage.Complete(KErrNone); |
|
180 } |
|
181 |
|
182 #endif // _DEBUG |
|
183 |
|
184 /** |
|
185 Message handling methods. |
|
186 */ |
|
187 |
|
188 // CRUD file operations. Methods delegate to the appropriate CCntDbManagerController method. |
|
189 void CCntFileManagerMsgHandler::OpenDataBaseL(const RMessage2& aMessage) |
|
190 { |
|
191 // Maps to RCntModel::OpenDatabase(). |
|
192 FileOpenCreateReplaceL(aMessage, ECntFileOpen); |
|
193 } |
|
194 void CCntFileManagerMsgHandler::CreateDatabaseL(const RMessage2& aMessage) |
|
195 { |
|
196 // Maps to RCntModel::CreateDatabase(). |
|
197 FileOpenCreateReplaceL(aMessage, ECntFileCreate); |
|
198 } |
|
199 |
|
200 void CCntFileManagerMsgHandler::ReplaceDatabaseL(const RMessage2& aMessage) |
|
201 { |
|
202 // Maps to RCntModel::ReplaceDatabase(). |
|
203 FileOpenCreateReplaceL(aMessage, ECntFileReplace); |
|
204 } |
|
205 |
|
206 void CCntFileManagerMsgHandler::CancelAsyncOpenDatabaseL(const RMessage2& aMessage) |
|
207 { |
|
208 CheckForManagerL(); |
|
209 CReqCancelAsyncOpen* request = CReqCancelAsyncOpen::NewLC(iSessionId, aMessage, iTimeOut); |
|
210 |
|
211 iManager->StateMachineL().ProcessRequestL(request); // ownership transferred |
|
212 |
|
213 // ProcessRequestL received ownership of the request, the request only need |
|
214 // to be popped from CleanupStack. |
|
215 CleanupStack::Pop(request); |
|
216 } |
|
217 |
|
218 void CCntFileManagerMsgHandler::CloseDataBaseL(const RMessage2& aMessage) |
|
219 { |
|
220 UnRegisterDatabaseEventObserver(); |
|
221 // Call the controller to deallocate. The controller may have more than |
|
222 // one session mapped to a single manager so the controller only deletes |
|
223 // the manager if this is the last session to close the database. There |
|
224 // is no need to move to the Closed state since it is the manager which |
|
225 // processes state transition requests and the manager is about to be |
|
226 // destroyed within CloseDatatbase(). |
|
227 Server().Controller().CloseDatabase(*iManager); |
|
228 iManager = NULL; |
|
229 |
|
230 aMessage.Complete(KErrNone); |
|
231 } |
|
232 |
|
233 void CCntFileManagerMsgHandler::CloseDbTablesL(const RMessage2& aMessage) |
|
234 { |
|
235 CheckForManagerL(); |
|
236 CReqCloseTables* request = CReqCloseTables::NewLC(iSessionId, aMessage, iTimeOut); |
|
237 iManager->StateMachineL().ProcessRequestL(request); // ownership transferred |
|
238 |
|
239 // ProcessRequestL received ownership of the request, the request only need |
|
240 // to be popped from CleanupStack. |
|
241 CleanupStack::Pop(request); |
|
242 } |
|
243 |
|
244 void CCntFileManagerMsgHandler::ReOpenDbTablesL(const RMessage2& aMessage) |
|
245 { |
|
246 // Maps to RCntModel::OpenTablesL(). |
|
247 CheckForManagerL(); |
|
248 CReqReOpen* request = CReqReOpen::NewLC(iSessionId, aMessage, iTimeOut); |
|
249 iManager->StateMachineL().ProcessRequestL(request); // ownership transferred |
|
250 |
|
251 // ProcessRequestL received ownership of the request, the request only need |
|
252 // to be popped from CleanupStack. |
|
253 CleanupStack::Pop(request); |
|
254 } |
|
255 |
|
256 void CCntFileManagerMsgHandler::DeleteDatabaseL(const RMessage2& aMessage) |
|
257 { |
|
258 // Non file-specific. Does not require manager instance. |
|
259 // Full name and path. Path length is validated on client-side. |
|
260 TBuf<KCntMaxFilePath> path; |
|
261 aMessage.ReadL(0,path); |
|
262 Server().Controller().DeleteDatabaseL(path); |
|
263 aMessage.Complete(KErrNone); |
|
264 } |
|
265 |
|
266 void CCntFileManagerMsgHandler::GetDefaultDatabaseNameL(const RMessage2& aMessage) |
|
267 { |
|
268 // Non file-specific. Does not require manager instance. |
|
269 TBuf<KCntMaxFilePath> path; |
|
270 // Call controller to retrieve default database name. |
|
271 Server().Controller().DefaultDatabaseL(path); |
|
272 aMessage.WriteL(0,path); |
|
273 aMessage.Complete(KErrNone); |
|
274 } |
|
275 |
|
276 void CCntFileManagerMsgHandler::DatabaseDrive(const RMessage2& aMessage) |
|
277 { |
|
278 // Non file-specific. Does not require manager instance. |
|
279 TDriveUnit drive; |
|
280 // Call controller to retrieve default database drive. |
|
281 Server().Controller().DatabaseDrive(drive); |
|
282 aMessage.Complete(drive); |
|
283 } |
|
284 |
|
285 void CCntFileManagerMsgHandler::SetDatabaseDriveL(const RMessage2& aMessage) |
|
286 { |
|
287 // Non file-specific. Does not require manager instance. |
|
288 // Parameter 1 is the integer drive 0-25. |
|
289 // Parameter 2 in the copy boolean. |
|
290 Server().Controller().SetDatabaseDriveL(TDriveNumber(aMessage.Int0()),TBool(aMessage.Int1())); |
|
291 aMessage.Complete(KErrNone); |
|
292 } |
|
293 |
|
294 void CCntFileManagerMsgHandler::DatabaseExistsL(const RMessage2& aMessage) |
|
295 { |
|
296 // Non file-specific. Does not require manager instance. |
|
297 // Full name and path. Path length is validated on client-side. |
|
298 TBuf<KCntMaxFilePath> path; |
|
299 aMessage.ReadL(0,path); |
|
300 aMessage.Complete(Server().Controller().DatabaseExistsL(path)); |
|
301 } |
|
302 |
|
303 void CCntFileManagerMsgHandler::ListDatabasesL(const RMessage2& aMessage) |
|
304 { |
|
305 // Non file-specific. Does not require manager instance. |
|
306 // Client request to list contact databases on a specific or all system |
|
307 // drives. |
|
308 // Return parameter for serialized CDesCArray. |
|
309 CBufFlat* listBuffer; |
|
310 // IPC args thus: |
|
311 // 0 (Return param) - Address of our return buffer |
|
312 // 1 (Param) - The drive number 0 - 25 or ECntAllDrives |
|
313 // 2 (Return param) - The size of buffer we are returning or want to return |
|
314 TInt driveNumber = aMessage.Int1(); |
|
315 // Call controller to retrieve list of databases. |
|
316 if(driveNumber == ECntAllDrives) |
|
317 { |
|
318 Server().Controller().ListDatabasesL(listBuffer); |
|
319 } |
|
320 else |
|
321 { |
|
322 Server().Controller().ListDatabasesL(listBuffer,(TDriveUnit*)&driveNumber); |
|
323 } |
|
324 // Controller will have filled the listBuffer with a serialized |
|
325 // CDesCArray. |
|
326 CleanupStack::PushL(listBuffer); |
|
327 // Size of the buffer we want to return to client. |
|
328 TInt size = listBuffer->Size(); |
|
329 TPckg<TInt> pckg(size); |
|
330 // Write return buffer size to client. |
|
331 aMessage.WriteL(2,pckg); |
|
332 // Only write if client has provided large enough buffer. Client can |
|
333 // call us again with a larger buffer if contents are too large. |
|
334 if(aMessage.GetDesMaxLength(0) >= size) |
|
335 { |
|
336 aMessage.WriteL(0,listBuffer->Ptr(0)); |
|
337 } |
|
338 aMessage.Complete(KErrNone); |
|
339 CleanupStack::PopAndDestroy(listBuffer); |
|
340 } |
|
341 |
|
342 void CCntFileManagerMsgHandler::GetDatabaseReadyL(const RMessage2& aMessage) |
|
343 { |
|
344 CheckForManagerL(); |
|
345 TBool databaseReady = iManager->StateMachineL().DatabaseReady(); |
|
346 aMessage.Complete(databaseReady); |
|
347 } |
|
348 |
|
349 void CCntFileManagerMsgHandler::FetchTemplateIdsL(const RMessage2& aMessage) |
|
350 { |
|
351 CheckForManagerL(); |
|
352 CContactIdArray& ArrayPtr = iManager->GetPersistenceLayer().ContactProperties().CardTemplateIdsL(); |
|
353 TPtr8 cntIDBuff = iPackager.PackL(ArrayPtr); |
|
354 TInt length = cntIDBuff.Length(); |
|
355 // Write data if client buffer is large enough otherwise return the |
|
356 // required buffer size. |
|
357 if(aMessage.GetDesMaxLength(0) >= length) |
|
358 { |
|
359 aMessage.WriteL(0, cntIDBuff); |
|
360 aMessage.Complete(KErrNone); |
|
361 } |
|
362 else |
|
363 { |
|
364 aMessage.Complete(length); |
|
365 } |
|
366 } |
|
367 |
|
368 void CCntFileManagerMsgHandler::FetchGroupIdListsL(const RMessage2& aMessage) |
|
369 { |
|
370 CheckForManagerL(); |
|
371 CContactIdArray& arrayPtr = iManager->GetPersistenceLayer().ContactProperties().GroupIdListL(); |
|
372 TPtr8 cntIDBuff = iPackager.PackL(arrayPtr); |
|
373 TInt length = cntIDBuff.Length(); |
|
374 // Write data if client buffer is large enough otherwise return the |
|
375 // required buffer size. |
|
376 if(aMessage.GetDesMaxLength(0) >= length) |
|
377 { |
|
378 aMessage.WriteL(0, cntIDBuff); |
|
379 aMessage.Complete(KErrNone); |
|
380 } |
|
381 else |
|
382 { |
|
383 aMessage.Complete(length); |
|
384 } |
|
385 } |
|
386 |
|
387 void CCntFileManagerMsgHandler::GetDefinitionsForExistingViewL(const RMessage2& aMessage) |
|
388 { |
|
389 DefinitionsOfExistingViewsL(aMessage); |
|
390 } |
|
391 |
|
392 void CCntFileManagerMsgHandler::FilesSizeL(const RMessage2& aMessage) |
|
393 { |
|
394 CheckForManagerL(); |
|
395 aMessage.Complete(iManager->FileSizeL()); |
|
396 } |