phonebookengines/contactsmodel/cntsrv/src/CCntFileManagerMsgHandler.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     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 	}