plugins/contacts/symbian/contactsmodel/cntsrv/src/ccntitemmsghandler.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     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 "ccntitemmsghandler.h"
       
    27 
       
    28 #include "ccntipccodes.h"
       
    29 #include "ccntrequest.h"
       
    30 #include "ccntdbmanager.h"
       
    31 #include "ccntstatemachine.h"
       
    32 #include "ccntdbmanagercontroller.h"
       
    33 #include "ccntbackuprestoreagent.h"
       
    34 #include "ccntpackager.h"
       
    35 #include "cntspeeddials.h"
       
    36 
       
    37 const TInt KCntItemIpcCodes[] =
       
    38 	{
       
    39 	ECntItemCreate,
       
    40 	ECntItemUpdate,
       
    41 	ECntItemDelete,
       
    42 	ECntItemRead,
       
    43 	ECntItemCommit,
       
    44 	ECntItemOpen,
       
    45 	ECntItemClose,
       
    46 	ECntConnectionId,
       
    47 	ECntGetCurrentItem,
       
    48 	ECntRemoveCurrentItem,
       
    49 	ECntSetCurrentItem,
       
    50 	ECntGetCurrentDb,
       
    51 	ECntSetCurrentDb,
       
    52 	ECntGetSpeedDialContactIdAndPhoneNumber,
       
    53 	ECntSetSpeedDialIdForPosition,
       
    54 	ECntSetOwnCard,
       
    55 	ECntGetOwnCard,
       
    56 	ECntGetCollection,
       
    57 	ECntSetSortPrefs,
       
    58 	ECntGetSortPrefs,
       
    59 	ECntSetDbViewContactType,
       
    60 	ECntGetDbViewContactType,
       
    61 	ECntDbContactCount,
       
    62 	ECntFindAsync,
       
    63 	ECntFindAsyncInit,
       
    64 	ECntFindAsyncTextDefInit,
       
    65 	ECntFind,
       
    66 	ECntFilterDatabase,
       
    67 	ECntSetAsyncActivity,
       
    68 	ECntResourceCount,
       
    69 	ECntSetHeapFailure,
       
    70 	ECntSeekContactInCollection
       
    71 	};
       
    72 
       
    73 CCntItemMsgHandler* CCntItemMsgHandler::NewLC(CCntSession& aSession)
       
    74 	{	
       
    75 	CCntItemMsgHandler* CntItemMsgHandler = new (ELeave) CCntItemMsgHandler(aSession);
       
    76 	CleanupStack::PushL(CntItemMsgHandler);
       
    77 	return CntItemMsgHandler;
       
    78 	}	
       
    79 
       
    80 CCntItemMsgHandler::CCntItemMsgHandler(CCntSession& aSession)
       
    81 :CCntMsgHandler(aSession)
       
    82 	{	
       
    83 	}
       
    84 	
       
    85 CCntItemMsgHandler::~CCntItemMsgHandler()
       
    86 	{
       
    87 	}
       
    88 	
       
    89 /**
       
    90 Delegates the incoming op code to a message handling method.
       
    91 
       
    92 First checks if this class services the op code, it then uses the lookup table and finds 
       
    93 function pointer(to message handling method) mapped to the incoming message function (op code)
       
    94 and finally delegates the message to handling method.
       
    95 
       
    96 It returns KErrNotFound if op code not handled.
       
    97 */
       
    98 TInt CCntItemMsgHandler::HandleMessageL(const RMessage2& aMessage)
       
    99 	{	
       
   100 	MsgHandlerFptr func_ptr = LookupHandlerMethodL(aMessage.Function(), KCntItemIpcCodes, sizeof(KCntItemIpcCodes)/sizeof(TInt));
       
   101 	
       
   102 	if(func_ptr)
       
   103 		{
       
   104 		ItemMsgHandlerFptr mem_func_ptr = static_cast<ItemMsgHandlerFptr>(func_ptr);
       
   105 		(this->*mem_func_ptr)(aMessage);
       
   106 		return (KErrNone);
       
   107 		}
       
   108 	
       
   109 	return (KErrNotFound);
       
   110 	}
       
   111 	
       
   112 /**
       
   113 Message handling methods.
       
   114 
       
   115 N.B.: Some operations use aMessage.Complete() to return the a contact ID.  This
       
   116 is not convention but saves on IPC overhead.  Only one parameter is returned as
       
   117 opposed to two (error code and contact ID).
       
   118 
       
   119 @param aMessage The message typically containing the Contact Item.
       
   120 */
       
   121 void CCntItemMsgHandler::ItemCreateL(const RMessage2& aMessage)
       
   122 	{
       
   123 	CheckForManagerL();
       
   124 	CReqCreateCnt* request = CReqCreateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   125 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   126 	
       
   127 	// ProcessRequestL received ownership of the request, the request only need
       
   128 	// to be popped from CleanupStack.		
       
   129 	CleanupStack::Pop(request);
       
   130 	}
       
   131 	
       
   132 void CCntItemMsgHandler::ItemUpdateL(const RMessage2& aMessage)
       
   133 	{
       
   134 	CheckForManagerL();
       
   135 	CReqUpdateCnt* request = CReqUpdateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   136 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   137 	
       
   138 	// ProcessRequestL received ownership of the request, the request only need
       
   139 	// to be popped from CleanupStack.		
       
   140 	CleanupStack::Pop(request);
       
   141 	}
       
   142 	
       
   143 void CCntItemMsgHandler::ItemDeleteL(const RMessage2& aMessage)
       
   144 	{
       
   145 	CheckForManagerL();
       
   146 	CReqDeleteCnt* request = CReqDeleteCnt::NewLC(iSessionId, aMessage, iTimeOut);
       
   147 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   148 	
       
   149 	// ProcessRequestL received ownership of the request, the request only need
       
   150 	// to be popped from CleanupStack.		
       
   151 	CleanupStack::Pop(request);
       
   152 	}
       
   153 	
       
   154 void CCntItemMsgHandler::ItemReadL(const RMessage2& aMessage)
       
   155 	{
       
   156 	CheckForManagerL();
       
   157 	CReqReadCnt* request = CReqReadCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
       
   158 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   159 	
       
   160 	// ProcessRequestL received ownership of the request, the request only need
       
   161 	// to be popped from CleanupStack.		
       
   162 	CleanupStack::Pop(request);
       
   163 	}
       
   164 	
       
   165 void CCntItemMsgHandler::ItemCommitL(const RMessage2& aMessage)
       
   166 	{
       
   167 	CheckForManagerL();
       
   168 	CReqCommitCnt* request = CReqCommitCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   169 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   170 	
       
   171 	// ProcessRequestL received ownership of the request, the request only need
       
   172 	// to be popped from CleanupStack.		
       
   173 	CleanupStack::Pop(request);
       
   174 	}
       
   175 	
       
   176 void CCntItemMsgHandler::ItemOpenL(const RMessage2& aMessage)
       
   177 	{
       
   178 	CheckForManagerL();
       
   179 	CReqOpenCnt* request = CReqOpenCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
       
   180 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   181 	
       
   182 	// ProcessRequestL received ownership of the request, the request only need
       
   183 	// to be popped from CleanupStack.		
       
   184 	CleanupStack::Pop(request);
       
   185 	}
       
   186 	
       
   187 void CCntItemMsgHandler::ItemCloseL(const RMessage2& aMessage)
       
   188 	{
       
   189 	CheckForManagerL();
       
   190 	CReqCloseCnt* request = CReqCloseCnt::NewLC(iSessionId, aMessage, iTimeOut);
       
   191 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   192 	
       
   193 	// ProcessRequestL received ownership of the request, the request only need
       
   194 	// to be popped from CleanupStack.		
       
   195 	CleanupStack::Pop(request);
       
   196 	}
       
   197 
       
   198 void CCntItemMsgHandler::ConnectionId(const RMessage2& aMessage)
       
   199 	{
       
   200 	// Complete the request with the session ID.
       
   201 	aMessage.Complete(iSessionId);
       
   202 	}
       
   203 	
       
   204 void CCntItemMsgHandler::GetCurrentItemL(const RMessage2& aMessage)
       
   205 	{
       
   206 	CheckForManagerL();			
       
   207 	TContactItemId currentItem(iManager->CurrentItem());
       
   208  	// Complete the request with the contact ID of the current item.
       
   209  	aMessage.Complete(currentItem);
       
   210 	}
       
   211 	
       
   212 void CCntItemMsgHandler::RemoveCurrentItemL(const RMessage2& aMessage)
       
   213 	{
       
   214 	CheckForManagerL();
       
   215 	iManager->RemoveCurrentItemL(iSessionId);
       
   216 	aMessage.Complete(KErrNone);
       
   217 	}
       
   218 	
       
   219 void CCntItemMsgHandler::SetCurrentItemL(const RMessage2& aMessage)
       
   220 	{
       
   221 	CheckForManagerL();
       
   222 	TContactItemId newCurrentItem = aMessage.Int0();
       
   223 	iManager->SetCurrentItemL(newCurrentItem, iSessionId);
       
   224 	aMessage.Complete(KErrNone);
       
   225 	}
       
   226 
       
   227 void CCntItemMsgHandler::GetCurrentDb(const RMessage2& aMessage)
       
   228 	{
       
   229 	WriteL(aMessage, KSlot0, Server().Controller().CurrentDb());
       
   230 	aMessage.Complete(KErrNone);
       
   231 	}
       
   232 	
       
   233 void CCntItemMsgHandler::SetCurrentDbL(const RMessage2& aMessage)
       
   234 	{
       
   235 	CheckForManagerL();
       
   236 	// Slot 0 in aMessage contains the new current database.
       
   237 	TFileName newCurrentDb;
       
   238 	ReadL(aMessage, KSlot0, newCurrentDb);
       
   239 	// Is this database already open for this session? We make it a
       
   240 	// pre-condition that you cannot set the current database to be one
       
   241 	// that isn't already open by this client.  This prevents errors
       
   242 	// whereby a client updates the current database, but then fails to
       
   243 	// open it.
       
   244 	if	(newCurrentDb.CompareF(iManager->CntFile()) == 0)
       
   245 		{
       
   246 		Server().Controller().SetCurrentDbL(newCurrentDb, iSessionId);				
       
   247 		}
       
   248 	aMessage.Complete(KErrNone);
       
   249 	}
       
   250 	
       
   251 void CCntItemMsgHandler::GetSpeedDialContactIdAndPhoneNumberL(const RMessage2& aMessage)
       
   252 	{
       
   253 	CheckForManagerL();
       
   254 	const TInt speedDialIndex = aMessage.Int0();		
       
   255 	TSpeedDialPhoneNumber phoneNumber;
       
   256 	TContactItemId contactId;
       
   257 	iManager->GetSpeedDialContactIdAndPhoneNumberL(speedDialIndex, phoneNumber, contactId);
       
   258 	aMessage.WriteL(KSlot1, phoneNumber);
       
   259 	aMessage.Complete(contactId);
       
   260 	}
       
   261 	
       
   262 void CCntItemMsgHandler::SetSpeedDialIdForPositionL(const RMessage2& aMessage)
       
   263 	{
       
   264 	CheckForManagerL();
       
   265 	// fetch the old contacts ID
       
   266 	const CCntServerSpeedDialTable& table = iManager->IniFileManager().SpeedDialManager().TableL(iManager->CntFile());
       
   267 	CReqSetSpeedDial* request = CReqSetSpeedDial::NewLC(iSessionId, 
       
   268 														aMessage, 
       
   269 														iTimeOut,
       
   270 														iView->ItemDef(),
       
   271 														iManager->IniFileManager().SpeedDialManager(),
       
   272 														table,
       
   273 														*iManager);
       
   274 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   275 	
       
   276 	// ProcessRequestL received ownership of the request, the request only need
       
   277 	// to be popped from CleanupStack.		
       
   278 	CleanupStack::Pop(request);
       
   279 	}
       
   280 	
       
   281 void CCntItemMsgHandler::SetOwnCardL(const RMessage2& aMessage)
       
   282 	{
       
   283 	CheckForManagerL();
       
   284 	CReqSetOwnCard* request = CReqSetOwnCard::NewLC(iSessionId, 
       
   285 													aMessage, 
       
   286 													iTimeOut,
       
   287 													iPackager,
       
   288 													iView->ItemDef(),
       
   289 													*iManager);
       
   290 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   291 	
       
   292 	// ProcessRequestL received ownership of the request, the request only need
       
   293 	// to be popped from CleanupStack.		
       
   294 	CleanupStack::Pop(request);
       
   295 	}
       
   296 	
       
   297 void CCntItemMsgHandler::GetOwnCardL(const RMessage2& aMessage)
       
   298 	{
       
   299 	CheckForManagerL();
       
   300 	aMessage.Complete(iManager->GetPersistenceLayer().ContactProperties().OwnCardIdL());
       
   301 	}
       
   302 	
       
   303 void CCntItemMsgHandler::GetCollectionL(const RMessage2& aMessage)
       
   304 	{
       
   305 	CheckForManagerL();
       
   306 	
       
   307 	// If backup or restore is in progress then database cannot be accessed.
       
   308 	CCntBackupRestoreAgent& burAgent = iManager->BackupRestoreAgent();
       
   309 	if(burAgent.BackupInProgress() || burAgent.RestoreInProgress())
       
   310 		{
       
   311 		User::Leave(KErrLocked);
       
   312 		}
       
   313 
       
   314 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   315 	MLplCollection::TLplViewType type = static_cast<MLplCollection::TLplViewType>(aMessage.Int1());
       
   316 	CContactIdArray* idArray = NULL;
       
   317 
       
   318 	switch(type)
       
   319 		{
       
   320 		case MLplCollection::EChangedSince :
       
   321 			{
       
   322 			TTime time(0);
       
   323 			TPckgBuf<TTime> buf(time);
       
   324 			aMessage.ReadL(2,buf);
       
   325 			time = buf();
       
   326 			idArray = collection.CollectionL(type,time,KNullDesC);
       
   327 			}
       
   328 			break;
       
   329 
       
   330 		case MLplCollection::EFindGuid :
       
   331 			{
       
   332 			TTime time(0);
       
   333 			TBuf<64> buf;
       
   334 			aMessage.ReadL(2,buf);
       
   335 			idArray = collection.CollectionL(type,time,buf);
       
   336 			}
       
   337 			break;
       
   338 
       
   339 		// Maps to RCntModel::MatchPhoneNumberL().
       
   340 		case MLplCollection::EMatchPhoneNos:
       
   341 			{
       
   342 			const TInt receivingBufLen = aMessage.GetDesLengthL(2);
       
   343 			HBufC* buf = HBufC::NewLC(receivingBufLen); // digits in the number
       
   344 			TPtr ptr(const_cast<TUint16*>(buf->Ptr()), receivingBufLen);
       
   345 			aMessage.ReadL(2, ptr);
       
   346 			idArray = collection.MatchPhoneNumberL(ptr, aMessage.Int3());
       
   347 			CleanupStack::PopAndDestroy(buf);
       
   348 			}
       
   349 			break;	
       
   350 
       
   351 		default :
       
   352 			{
       
   353 			idArray = collection.CollectionL(type);
       
   354 			}
       
   355 			break;
       
   356 		}
       
   357 	
       
   358 	CleanupStack::PushL(idArray);
       
   359 	TPtr8 ptr = iPackager.PackL(*idArray);
       
   360 	TInt length = ptr.Length();
       
   361 	
       
   362 	if(aMessage.GetDesMaxLength(0) >= length)
       
   363 		{
       
   364 		aMessage.WriteL(0,ptr); 
       
   365 		aMessage.Complete(KErrNone);
       
   366 		}
       
   367 	else
       
   368 		{
       
   369 		aMessage.Complete(length);
       
   370 		}
       
   371 	
       
   372 	CleanupStack::PopAndDestroy(idArray);
       
   373 	}
       
   374 	
       
   375 void CCntItemMsgHandler::SetSortPrefsL(const RMessage2& aMessage)
       
   376 	{
       
   377 	CheckForManagerL();
       
   378 	iPackager.SetBufferFromMessageL(aMessage);
       
   379 	CArrayFix<CContactDatabase::TSortPref>* prefs = iPackager.UnpackCArrayFixLC();
       
   380 	iManager->GetPersistenceLayer().ContactProperties().SetSortPrefsL(prefs);
       
   381 	CleanupStack::Pop(prefs);
       
   382 	aMessage.Complete(KErrNone);
       
   383 	}
       
   384 	
       
   385 void CCntItemMsgHandler::GetSortPrefsL(const RMessage2& aMessage)
       
   386 	{
       
   387 	CheckForManagerL();
       
   388 	const CArrayFix<CContactDatabase::TSortPref>& prefs = iManager->GetPersistenceLayer().ContactProperties().SortPrefsL();
       
   389 	TPtr8 ptr = iPackager.PackL(prefs);
       
   390 	TInt length = ptr.Length();
       
   391 	if(aMessage.GetDesMaxLength(0) >= length)
       
   392 		{
       
   393 		aMessage.WriteL(0,ptr); 
       
   394 		aMessage.Complete(KErrNone);
       
   395 		}
       
   396 	else
       
   397 		{
       
   398 		aMessage.Complete(length);
       
   399 		}
       
   400 	}
       
   401 	
       
   402 void CCntItemMsgHandler::SetDbViewContactTypeL(const RMessage2& aMessage)
       
   403 	{
       
   404 	CheckForManagerL();
       
   405 	iManager->GetPersistenceLayer().ContactProperties().SetDbViewContactType(TUid::Uid(aMessage.Int0()));
       
   406 	aMessage.Complete(KErrNone);
       
   407 	}
       
   408 	
       
   409 void CCntItemMsgHandler::GetDbViewContactTypeL(const RMessage2& aMessage)
       
   410 	{
       
   411 	CheckForManagerL();
       
   412 	TPckg<TUid> dbViewContactType(iManager->GetPersistenceLayer().ContactProperties().GetDbViewContactType());
       
   413 	aMessage.WriteL(0,dbViewContactType);
       
   414 	aMessage.Complete(KErrNone);
       
   415 	}
       
   416 	
       
   417 void CCntItemMsgHandler::DbContactCountL(const RMessage2& aMessage)
       
   418 	{
       
   419 	CheckForManagerL();
       
   420 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   421 	aMessage.Complete(collection.ContactCountL());
       
   422 	}
       
   423 	
       
   424 void CCntItemMsgHandler::FindAsyncL(const RMessage2& aMessage)
       
   425 	{
       
   426 	/* Maps to client side AsyncFindL().  Can and will be called iteratively by the 
       
   427 	client. One of the two intitialisations below (i.e. ECntFindAsyncInit or 
       
   428 	ECntFindAsyncTextDefInit will have been called prior to this call.
       
   429 	**/
       
   430 	
       
   431 	CheckForManagerL();
       
   432 			
       
   433 	TBool moreToGo(EFalse);
       
   434 	
       
   435 	// Call Persistence Layer to do the work.  moreToGo will be set to
       
   436 	// ETrue if client should call again.  CContactIdArray and TBool are
       
   437 	// return parameters to the client.
       
   438 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   439 	CContactIdArray* idArray = collection.FindAsyncL(moreToGo, iSessionId);
       
   440 	CleanupStack::PushL(idArray);
       
   441 	
       
   442 	TPckg<TBool> morePckg(moreToGo);
       
   443 	aMessage.WriteL(1,morePckg);
       
   444 	
       
   445 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   446 	// Iterative calls rely on packager having large enough buffer.
       
   447 	// Client expands it to 4k before calling.
       
   448 	// Write back to client
       
   449 	aMessage.WriteL(0,ptr8);
       
   450 	
       
   451 	CleanupStack::PopAndDestroy(idArray); 
       
   452 	aMessage.Complete(KErrNone);
       
   453 	}
       
   454 	
       
   455 //
       
   456 void CCntItemMsgHandler::FindAsyncInitL(const RMessage2& aMessage)
       
   457 	{
       
   458 	/* Asynchronous find can use 2 types of initialisation which map to the 
       
   459 	two construction types in the old Contacts Model. One uses a CContactTextDef 
       
   460 	and CDesCArray and the other a CContactItemFieldDef and text descriptor. 
       
   461 	Once initialisation is complete the client-side CIdleFinder::doFindL() method 
       
   462 	calls AsyncFind().
       
   463 
       
   464 	Initialisation for asynchronous find using CContactItemFileldDef and TDesC.
       
   465 	**/
       
   466 	
       
   467 	CheckForManagerL();
       
   468 
       
   469 	// Read descriptor into HBuf.
       
   470 	HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(0));
       
   471 	TPtr ptr(text->Des());
       
   472 	aMessage.ReadL(0,ptr);
       
   473 
       
   474 	CContactItemFieldDef* fieldDef = NULL;
       
   475 	if(aMessage.GetDesLengthL(1) > 0)
       
   476 		{
       
   477 		// Use packager to unpack CContactItemFieldDef.
       
   478 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   479 		fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
       
   480 		CleanupStack::Pop(fieldDef);
       
   481 		}
       
   482 	
       
   483 	// Persistence Layer does the actual initialisation and also takes
       
   484 	// ownership of fielDef.
       
   485 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   486 	collection.FindAsyncInitL(text->Des(),fieldDef);
       
   487 	
       
   488 	CleanupStack::PopAndDestroy(text);
       
   489 	aMessage.Complete(KErrNone);
       
   490 	}
       
   491 	
       
   492 void CCntItemMsgHandler::FindAsyncTextDefInitL(const RMessage2& aMessage)
       
   493 	{
       
   494 	/* Initialisation for asynchronous find using CContactTextDef and array of 
       
   495 	"find words" constructed on the client-side and required on the server-side 
       
   496 	for matching.
       
   497 	**/
       
   498 	
       
   499 	CheckForManagerL();
       
   500 
       
   501 	// CContactTextDef can be NULL in which case the client will have
       
   502 	// passed an empty descriptor.
       
   503 	CContactTextDef* textDef = NULL;
       
   504 	// Assuming that a KNullDesC parameter results in max length of 0.
       
   505 	if(aMessage.GetDesLengthL(1) > 0)
       
   506 		{
       
   507 		// Use packager to unpack CContactTextDef.
       
   508 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   509 		textDef = iPackager.UnpackCntTextDefLC();
       
   510 		CleanupStack::Pop(textDef);
       
   511 		}
       
   512 
       
   513 	// Unpack the CDesCArray manually as the packager does not package
       
   514 	// both.			
       
   515 	CBufFlat* bufFlat = CBufFlat::NewL(1 << 8);
       
   516 	CleanupStack::PushL(bufFlat);
       
   517 	bufFlat->ExpandL(0,aMessage.GetDesLengthL(0));
       
   518 	TPtr8 ptr8(bufFlat->Ptr(0));
       
   519 	aMessage.ReadL(0,ptr8);
       
   520 	RBufReadStream readStream;
       
   521 	readStream.Open(*bufFlat);
       
   522 	TInt count = readStream.ReadInt32L();
       
   523 	CDesCArray* unpacked = new (ELeave) CDesCArrayFlat(8);
       
   524 	CleanupStack::PushL(unpacked);
       
   525 	for(TInt i=0;i<count;++i)
       
   526 		{
       
   527 		TBuf<256> buf;
       
   528 		TInt length = readStream.ReadInt32L();
       
   529 		readStream.ReadL(buf,length);
       
   530 		unpacked->AppendL(buf);
       
   531 		}
       
   532 	readStream.Close();
       
   533 	
       
   534 	// Persistence Layer does the actual initialisation and also takes
       
   535 	// ownership of textDef.
       
   536 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   537 	collection.FindAsyncTextDefInitL(*unpacked,textDef);
       
   538 	
       
   539 	CleanupStack::PopAndDestroy(unpacked);
       
   540 	CleanupStack::PopAndDestroy(bufFlat);
       
   541 	aMessage.Complete(KErrNone);
       
   542 	}
       
   543 	
       
   544 void CCntItemMsgHandler::SeekContactL(const RMessage2& aMessage)
       
   545 	{
       
   546 	CheckForManagerL();
       
   547 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   548 	
       
   549 	TContactItemId actualId;
       
   550 	TUid contactType;
       
   551 	TBool deleted(EFalse);
       
   552 	// SeekContactL returns the Deleted Flag, the Contact ID and the
       
   553 	// contact type.
       
   554 	TBool seekRet = collection.SeekContactL(aMessage.Int0(),actualId,contactType,deleted);
       
   555 	
       
   556 	if(seekRet)
       
   557 		{
       
   558 		TPckg<TInt> idPckg(actualId);
       
   559 		aMessage.WriteL(1,idPckg);
       
   560 		TPckg<TUid> typePckg(contactType);
       
   561 		aMessage.WriteL(2,typePckg);
       
   562 		TPckg<TInt> deletePckg(deleted);
       
   563 		aMessage.WriteL(3,deletePckg);				
       
   564 		}
       
   565 		
       
   566 	aMessage.Complete(seekRet);	
       
   567 	}
       
   568 	
       
   569 void CCntItemMsgHandler::FindL(const RMessage2& aMessage)
       
   570 	{
       
   571 	// Maps to RCntModel::FindL() method.
       
   572 	
       
   573 	CheckForManagerL();
       
   574 						
       
   575 	// CContactItemFieldDef can be NULL in which case the client will
       
   576 	// have passed an empty descriptor.
       
   577 	CContactItemFieldDef* fieldDef = NULL;
       
   578 	// Assuming that a KNullDesC parameter results in max length of 0.
       
   579 	if(aMessage.GetDesLengthL(1) != 0)
       
   580 		{
       
   581 		// Slot 1 contains a serialized CArrayFixFlat<TUid>.  Since
       
   582 		// CContactItemFieldDef derives from it we can use the packager
       
   583 		// to unpack it.
       
   584 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   585 		fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
       
   586 		}
       
   587 	
       
   588 	// Get the search text from slot 2
       
   589 	HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(2));
       
   590 	TPtr ptr(text->Des());
       
   591 	aMessage.ReadL(2,ptr);
       
   592 
       
   593 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   594 	collection.Reset();
       
   595 	
       
   596 	// Call the Persistence Layer to perform the find.
       
   597 	CContactIdArray* idArray = collection.FindL(ptr,fieldDef, iSessionId);
       
   598 	CleanupStack::PopAndDestroy(text);
       
   599 
       
   600 	// Package the contact ID array for return.
       
   601 	CleanupStack::PushL(idArray);
       
   602 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   603 	TInt length = ptr8.Length();
       
   604 	
       
   605 	// Check the descriptor from the client is large enough.
       
   606 	if(aMessage.GetDesMaxLength(0) >= length)
       
   607 		{
       
   608 		// Write back to client.
       
   609 		aMessage.WriteL(0,ptr8); 
       
   610 		aMessage.Complete(KErrNone);
       
   611 		}
       
   612 	else
       
   613 		{
       
   614 		// Return required size of buffer to the client.
       
   615 		aMessage.Complete(length);
       
   616 		}
       
   617 	CleanupStack::PopAndDestroy(idArray);
       
   618 	if(fieldDef)
       
   619 		{
       
   620 		CleanupStack::PopAndDestroy(fieldDef);
       
   621 		}	
       
   622 	}
       
   623 	
       
   624 void CCntItemMsgHandler::FilterDatabaseL(const RMessage2& aMessage)
       
   625 	{
       
   626 	CheckForManagerL();
       
   627 	iPackager.SetBufferFromMessageL(aMessage);
       
   628 	CCntFilter* filter = iPackager.UnpackCntFilterLC();
       
   629 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   630 	CContactIdArray* idArray = collection.FilterDatabaseL(*filter);
       
   631 	CleanupStack::PopAndDestroy(filter);
       
   632 	CleanupStack::PushL(idArray);
       
   633 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   634 	TInt length = ptr8.Length();
       
   635 	// Check the descriptor from the client is large enough.
       
   636 	if(aMessage.GetDesMaxLength(0) >= length)
       
   637 		{
       
   638 		// Write back to client.
       
   639 		aMessage.WriteL(0,ptr8); 
       
   640 		aMessage.Complete(KErrNone);
       
   641 		}
       
   642 	else
       
   643 		{
       
   644 		// Return required size of buffer to the client.
       
   645 		aMessage.Complete(length);
       
   646 		}
       
   647 	CleanupStack::PopAndDestroy(idArray);
       
   648 	}
       
   649 	
       
   650 void CCntItemMsgHandler::SetAsyncActivityL(const RMessage2& aMessage)
       
   651 	{
       
   652 	CheckForManagerL();
       
   653 	TBool asyncActivity = TBool(aMessage.Int0());
       
   654 	// Create and then process appropriate request using state machine.
       
   655 	CCntRequest* request = NULL;
       
   656 	if (asyncActivity)
       
   657 		{
       
   658 		request = CReqAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
       
   659 		}
       
   660 	else
       
   661 		{
       
   662 		request = CReqNoAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
       
   663 		}
       
   664 	iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
       
   665 	
       
   666 	// ProcessRequestL received ownership of the request, the request only need
       
   667 	// to be popped from CleanupStack.		
       
   668 	CleanupStack::Pop(request);
       
   669 	}
       
   670 	
       
   671 void CCntItemMsgHandler::ResourceCount(const RMessage2& aMessage)
       
   672 	{
       
   673 	#if defined(_DEBUG)
       
   674 	TInt totalAllocSize(0);
       
   675 	User::Heap().AllocSize(totalAllocSize);
       
   676 	RDebug::Print(_L("[CNTMODEL] Heap count: %d cells, total heap size: %d bytes"), User::Heap().Count(), User::Heap().Size());
       
   677 	RDebug::Print(_L("[CNTMODEL] cntsrv heap size: %d bytes"), totalAllocSize);
       
   678 	aMessage.Complete(User::Heap().Count());
       
   679 	#else
       
   680 	aMessage.Complete(KErrNone);
       
   681 	#endif
       
   682 	}
       
   683 	
       
   684 void CCntItemMsgHandler::SetHeapFailure(const RMessage2& aMessage)
       
   685 	{
       
   686 	#if defined(_DEBUG)
       
   687 	User::__DbgSetAllocFail(RHeap::EUser,(RHeap::TAllocFail)aMessage.Int0(),aMessage.Int1());
       
   688 	#endif
       
   689 	aMessage.Complete(KErrNone);
       
   690 	}
       
   691