--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntsrv/src/CCntItemMsgHandler.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,688 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "CCntMsgHandler.h"
+#include "CCntMsgHandlerFptr.h"
+#include "CCntItemMsgHandler.h"
+
+#include "CCntIpcCodes.h"
+#include "CCntRequest.h"
+#include "CCntDbManager.h"
+#include "CCntStateMachine.h"
+#include "CCntDbManagerController.h"
+#include "CCntBackupRestoreAgent.h"
+#include "CCntPackager.h"
+#include "CntSpeedDials.h"
+
+const TInt KCntItemIpcCodes[] =
+ {
+ ECntItemCreate,
+ ECntItemUpdate,
+ ECntItemDelete,
+ ECntItemRead,
+ ECntItemCommit,
+ ECntItemOpen,
+ ECntItemClose,
+ ECntConnectionId,
+ ECntGetCurrentItem,
+ ECntRemoveCurrentItem,
+ ECntSetCurrentItem,
+ ECntGetCurrentDb,
+ ECntSetCurrentDb,
+ ECntGetSpeedDialContactIdAndPhoneNumber,
+ ECntSetSpeedDialIdForPosition,
+ ECntSetOwnCard,
+ ECntGetOwnCard,
+ ECntGetCollection,
+ ECntSetSortPrefs,
+ ECntGetSortPrefs,
+ ECntSetDbViewContactType,
+ ECntGetDbViewContactType,
+ ECntDbContactCount,
+ ECntFindAsync,
+ ECntFindAsyncInit,
+ ECntFindAsyncTextDefInit,
+ ECntFind,
+ ECntFilterDatabase,
+ ECntSetAsyncActivity,
+ ECntResourceCount,
+ ECntSetHeapFailure,
+ ECntSeekContactInCollection
+ };
+
+CCntItemMsgHandler* CCntItemMsgHandler::NewLC(CCntSession& aSession)
+ {
+ CCntItemMsgHandler* CntItemMsgHandler = new (ELeave) CCntItemMsgHandler(aSession);
+ CleanupStack::PushL(CntItemMsgHandler);
+ return CntItemMsgHandler;
+ }
+
+CCntItemMsgHandler::CCntItemMsgHandler(CCntSession& aSession)
+:CCntMsgHandler(aSession)
+ {
+ }
+
+CCntItemMsgHandler::~CCntItemMsgHandler()
+ {
+ }
+
+/**
+Delegates the incoming op code to a message handling method.
+
+First checks if this class services the op code, it then uses the lookup table and finds
+function pointer(to message handling method) mapped to the incoming message function (op code)
+and finally delegates the message to handling method.
+
+It returns KErrNotFound if op code not handled.
+*/
+TInt CCntItemMsgHandler::HandleMessageL(const RMessage2& aMessage)
+ {
+ MsgHandlerFptr func_ptr = LookupHandlerMethodL(aMessage.Function(), KCntItemIpcCodes, sizeof(KCntItemIpcCodes)/sizeof(TInt));
+
+ if(func_ptr)
+ {
+ ItemMsgHandlerFptr mem_func_ptr = static_cast<ItemMsgHandlerFptr>(func_ptr);
+ (this->*mem_func_ptr)(aMessage);
+ return (KErrNone);
+ }
+
+ return (KErrNotFound);
+ }
+
+/**
+Message handling methods.
+
+N.B.: Some operations use aMessage.Complete() to return the a contact ID. This
+is not convention but saves on IPC overhead. Only one parameter is returned as
+opposed to two (error code and contact ID).
+
+@param aMessage The message typically containing the Contact Item.
+*/
+void CCntItemMsgHandler::ItemCreateL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqCreateCnt* request = CReqCreateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemUpdateL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqUpdateCnt* request = CReqUpdateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemDeleteL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqDeleteCnt* request = CReqDeleteCnt::NewLC(iSessionId, aMessage, iTimeOut);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemReadL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqReadCnt* request = CReqReadCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemCommitL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqCommitCnt* request = CReqCommitCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemOpenL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqOpenCnt* request = CReqOpenCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ItemCloseL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqCloseCnt* request = CReqCloseCnt::NewLC(iSessionId, aMessage, iTimeOut);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ConnectionId(const RMessage2& aMessage)
+ {
+ // Complete the request with the session ID.
+ aMessage.Complete(iSessionId);
+ }
+
+void CCntItemMsgHandler::GetCurrentItemL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ TContactItemId currentItem(iManager->CurrentItem());
+ // Complete the request with the contact ID of the current item.
+ aMessage.Complete(currentItem);
+ }
+
+void CCntItemMsgHandler::RemoveCurrentItemL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ iManager->RemoveCurrentItemL(iSessionId);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::SetCurrentItemL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ TContactItemId newCurrentItem = aMessage.Int0();
+ iManager->SetCurrentItemL(newCurrentItem, iSessionId);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::GetCurrentDb(const RMessage2& aMessage)
+ {
+ WriteL(aMessage, KSlot0, Server().Controller().CurrentDb());
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::SetCurrentDbL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ // Slot 0 in aMessage contains the new current database.
+ TFileName newCurrentDb;
+ ReadL(aMessage, KSlot0, newCurrentDb);
+ // Is this database already open for this session? We make it a
+ // pre-condition that you cannot set the current database to be one
+ // that isn't already open by this client. This prevents errors
+ // whereby a client updates the current database, but then fails to
+ // open it.
+ if (newCurrentDb.CompareF(iManager->CntFile()) == 0)
+ {
+ Server().Controller().SetCurrentDbL(newCurrentDb, iSessionId);
+ }
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::GetSpeedDialContactIdAndPhoneNumberL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ const TInt speedDialIndex = aMessage.Int0();
+ TSpeedDialPhoneNumber phoneNumber;
+ TContactItemId contactId;
+ iManager->GetSpeedDialContactIdAndPhoneNumberL(speedDialIndex, phoneNumber, contactId);
+ aMessage.WriteL(KSlot1, phoneNumber);
+ aMessage.Complete(contactId);
+ }
+
+void CCntItemMsgHandler::SetSpeedDialIdForPositionL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ // fetch the old contacts ID
+ const CCntServerSpeedDialTable& table = iManager->IniFileManager().SpeedDialManager().TableL(iManager->CntFile());
+ CReqSetSpeedDial* request = CReqSetSpeedDial::NewLC(iSessionId,
+ aMessage,
+ iTimeOut,
+ iView->ItemDef(),
+ iManager->IniFileManager().SpeedDialManager(),
+ table,
+ *iManager);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::SetOwnCardL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ CReqSetOwnCard* request = CReqSetOwnCard::NewLC(iSessionId,
+ aMessage,
+ iTimeOut,
+ iPackager,
+ iView->ItemDef(),
+ *iManager);
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::GetOwnCardL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ aMessage.Complete(iManager->GetPersistenceLayer().ContactProperties().OwnCardIdL());
+ }
+
+void CCntItemMsgHandler::GetCollectionL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+
+ // If backup or restore is in progress then database cannot be accessed.
+ CCntBackupRestoreAgent& burAgent = iManager->BackupRestoreAgent();
+ if(burAgent.BackupInProgress() || burAgent.RestoreInProgress())
+ {
+ User::Leave(KErrLocked);
+ }
+
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ MLplCollection::TLplViewType type = static_cast<MLplCollection::TLplViewType>(aMessage.Int1());
+ CContactIdArray* idArray = NULL;
+
+ switch(type)
+ {
+ case MLplCollection::EChangedSince :
+ {
+ TTime time(0);
+ TPckgBuf<TTime> buf(time);
+ aMessage.ReadL(2,buf);
+ time = buf();
+ idArray = collection.CollectionL(type,time,KNullDesC);
+ }
+ break;
+
+ case MLplCollection::EFindGuid :
+ {
+ TTime time(0);
+ TBuf<64> buf;
+ aMessage.ReadL(2,buf);
+ idArray = collection.CollectionL(type,time,buf);
+ }
+ break;
+
+ // Maps to RCntModel::MatchPhoneNumberL().
+ case MLplCollection::EMatchPhoneNos:
+ {
+ const TInt receivingBufLen = aMessage.GetDesLengthL(2);
+ HBufC* buf = HBufC::NewLC(receivingBufLen); // digits in the number
+ TPtr ptr(const_cast<TUint16*>(buf->Ptr()), receivingBufLen);
+ aMessage.ReadL(2, ptr);
+ idArray = collection.MatchPhoneNumberL(ptr, aMessage.Int3());
+ CleanupStack::PopAndDestroy(buf);
+ }
+ break;
+
+ default :
+ {
+ idArray = collection.CollectionL(type);
+ }
+ break;
+ }
+
+ CleanupStack::PushL(idArray);
+ TPtr8 ptr = iPackager.PackL(*idArray);
+ TInt length = ptr.Length();
+
+ if(aMessage.GetDesMaxLength(0) >= length)
+ {
+ aMessage.WriteL(0,ptr);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ aMessage.Complete(length);
+ }
+
+ CleanupStack::PopAndDestroy(idArray);
+ }
+
+void CCntItemMsgHandler::SetSortPrefsL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ iPackager.SetBufferFromMessageL(aMessage);
+ CArrayFix<CContactDatabase::TSortPref>* prefs = iPackager.UnpackCArrayFixLC();
+ iManager->GetPersistenceLayer().ContactProperties().SetSortPrefsL(prefs);
+ CleanupStack::Pop(prefs);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::GetSortPrefsL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ const CArrayFix<CContactDatabase::TSortPref>& prefs = iManager->GetPersistenceLayer().ContactProperties().SortPrefsL();
+ TPtr8 ptr = iPackager.PackL(prefs);
+ TInt length = ptr.Length();
+ if(aMessage.GetDesMaxLength(0) >= length)
+ {
+ aMessage.WriteL(0,ptr);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ aMessage.Complete(length);
+ }
+ }
+
+void CCntItemMsgHandler::SetDbViewContactTypeL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ iManager->GetPersistenceLayer().ContactProperties().SetDbViewContactType(TUid::Uid(aMessage.Int0()));
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::GetDbViewContactTypeL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ TPckg<TUid> dbViewContactType(iManager->GetPersistenceLayer().ContactProperties().GetDbViewContactType());
+ aMessage.WriteL(0,dbViewContactType);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::DbContactCountL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ aMessage.Complete(collection.ContactCountL());
+ }
+
+void CCntItemMsgHandler::FindAsyncL(const RMessage2& aMessage)
+ {
+ /* Maps to client side AsyncFindL(). Can and will be called iteratively by the
+ client. One of the two intitialisations below (i.e. ECntFindAsyncInit or
+ ECntFindAsyncTextDefInit will have been called prior to this call.
+ **/
+
+ CheckForManagerL();
+
+ TBool moreToGo(EFalse);
+
+ // Call Persistence Layer to do the work. moreToGo will be set to
+ // ETrue if client should call again. CContactIdArray and TBool are
+ // return parameters to the client.
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ CContactIdArray* idArray = collection.FindAsyncL(moreToGo, iSessionId);
+ CleanupStack::PushL(idArray);
+
+ TPckg<TBool> morePckg(moreToGo);
+ aMessage.WriteL(1,morePckg);
+
+ TPtr8 ptr8 = iPackager.PackL(*idArray);
+ // Iterative calls rely on packager having large enough buffer.
+ // Client expands it to 4k before calling.
+ // Write back to client
+ aMessage.WriteL(0,ptr8);
+
+ CleanupStack::PopAndDestroy(idArray);
+ aMessage.Complete(KErrNone);
+ }
+
+//
+void CCntItemMsgHandler::FindAsyncInitL(const RMessage2& aMessage)
+ {
+ /* Asynchronous find can use 2 types of initialisation which map to the
+ two construction types in the old Contacts Model. One uses a CContactTextDef
+ and CDesCArray and the other a CContactItemFieldDef and text descriptor.
+ Once initialisation is complete the client-side CIdleFinder::doFindL() method
+ calls AsyncFind().
+
+ Initialisation for asynchronous find using CContactItemFileldDef and TDesC.
+ **/
+
+ CheckForManagerL();
+
+ // Read descriptor into HBuf.
+ HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(0));
+ TPtr ptr(text->Des());
+ aMessage.ReadL(0,ptr);
+
+ CContactItemFieldDef* fieldDef = NULL;
+ if(aMessage.GetDesLengthL(1) > 0)
+ {
+ // Use packager to unpack CContactItemFieldDef.
+ iPackager.SetBufferFromMessageL(aMessage,1);
+ fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
+ CleanupStack::Pop(fieldDef);
+ }
+
+ // Persistence Layer does the actual initialisation and also takes
+ // ownership of fielDef.
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ collection.FindAsyncInitL(text->Des(),fieldDef);
+
+ CleanupStack::PopAndDestroy(text);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::FindAsyncTextDefInitL(const RMessage2& aMessage)
+ {
+ /* Initialisation for asynchronous find using CContactTextDef and array of
+ "find words" constructed on the client-side and required on the server-side
+ for matching.
+ **/
+
+ CheckForManagerL();
+
+ // CContactTextDef can be NULL in which case the client will have
+ // passed an empty descriptor.
+ CContactTextDef* textDef = NULL;
+ // Assuming that a KNullDesC parameter results in max length of 0.
+ if(aMessage.GetDesLengthL(1) > 0)
+ {
+ // Use packager to unpack CContactTextDef.
+ iPackager.SetBufferFromMessageL(aMessage,1);
+ textDef = iPackager.UnpackCntTextDefLC();
+ CleanupStack::Pop(textDef);
+ }
+
+ // Unpack the CDesCArray manually as the packager does not package
+ // both.
+ CBufFlat* bufFlat = CBufFlat::NewL(1 << 8);
+ CleanupStack::PushL(bufFlat);
+ bufFlat->ExpandL(0,aMessage.GetDesLengthL(0));
+ TPtr8 ptr8(bufFlat->Ptr(0));
+ aMessage.ReadL(0,ptr8);
+ RBufReadStream readStream;
+ readStream.Open(*bufFlat);
+ TInt count = readStream.ReadInt32L();
+ CDesCArray* unpacked = new (ELeave) CDesCArrayFlat(8);
+ CleanupStack::PushL(unpacked);
+ for(TInt i=0;i<count;++i)
+ {
+ TBuf<256> buf;
+ TInt length = readStream.ReadInt32L();
+ readStream.ReadL(buf,length);
+ unpacked->AppendL(buf);
+ }
+ readStream.Close();
+
+ // Persistence Layer does the actual initialisation and also takes
+ // ownership of textDef.
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ collection.FindAsyncTextDefInitL(*unpacked,textDef);
+
+ CleanupStack::PopAndDestroy(unpacked);
+ CleanupStack::PopAndDestroy(bufFlat);
+ aMessage.Complete(KErrNone);
+ }
+
+void CCntItemMsgHandler::SeekContactL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+
+ TContactItemId actualId;
+ TUid contactType;
+ TBool deleted(EFalse);
+ // SeekContactL returns the Deleted Flag, the Contact ID and the
+ // contact type.
+ TBool seekRet = collection.SeekContactL(aMessage.Int0(),actualId,contactType,deleted);
+
+ if(seekRet)
+ {
+ TPckg<TInt> idPckg(actualId);
+ aMessage.WriteL(1,idPckg);
+ TPckg<TUid> typePckg(contactType);
+ aMessage.WriteL(2,typePckg);
+ TPckg<TInt> deletePckg(deleted);
+ aMessage.WriteL(3,deletePckg);
+ }
+
+ aMessage.Complete(seekRet);
+ }
+
+void CCntItemMsgHandler::FindL(const RMessage2& aMessage)
+ {
+ // Maps to RCntModel::FindL() method.
+
+ CheckForManagerL();
+
+ // CContactItemFieldDef can be NULL in which case the client will
+ // have passed an empty descriptor.
+ CContactItemFieldDef* fieldDef = NULL;
+ // Assuming that a KNullDesC parameter results in max length of 0.
+ if(aMessage.GetDesLengthL(1) != 0)
+ {
+ // Slot 1 contains a serialized CArrayFixFlat<TUid>. Since
+ // CContactItemFieldDef derives from it we can use the packager
+ // to unpack it.
+ iPackager.SetBufferFromMessageL(aMessage,1);
+ fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
+ }
+
+ // Get the search text from slot 2
+ HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(2));
+ TPtr ptr(text->Des());
+ aMessage.ReadL(2,ptr);
+
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ collection.Reset();
+
+ // Call the Persistence Layer to perform the find.
+ CContactIdArray* idArray = collection.FindL(ptr,fieldDef, iSessionId);
+ CleanupStack::PopAndDestroy(text);
+
+ // Package the contact ID array for return.
+ CleanupStack::PushL(idArray);
+ TPtr8 ptr8 = iPackager.PackL(*idArray);
+ TInt length = ptr8.Length();
+
+ // Check the descriptor from the client is large enough.
+ if(aMessage.GetDesMaxLength(0) >= length)
+ {
+ // Write back to client.
+ aMessage.WriteL(0,ptr8);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ // Return required size of buffer to the client.
+ aMessage.Complete(length);
+ }
+ CleanupStack::PopAndDestroy(idArray);
+ if(fieldDef)
+ {
+ CleanupStack::PopAndDestroy(fieldDef);
+ }
+ }
+
+void CCntItemMsgHandler::FilterDatabaseL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ iPackager.SetBufferFromMessageL(aMessage);
+ CCntFilter* filter = iPackager.UnpackCntFilterLC();
+ MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
+ CContactIdArray* idArray = collection.FilterDatabaseL(*filter);
+ CleanupStack::PopAndDestroy(filter);
+ CleanupStack::PushL(idArray);
+ TPtr8 ptr8 = iPackager.PackL(*idArray);
+ TInt length = ptr8.Length();
+ // Check the descriptor from the client is large enough.
+ if(aMessage.GetDesMaxLength(0) >= length)
+ {
+ // Write back to client.
+ aMessage.WriteL(0,ptr8);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ // Return required size of buffer to the client.
+ aMessage.Complete(length);
+ }
+ CleanupStack::PopAndDestroy(idArray);
+ }
+
+void CCntItemMsgHandler::SetAsyncActivityL(const RMessage2& aMessage)
+ {
+ CheckForManagerL();
+ TBool asyncActivity = TBool(aMessage.Int0());
+ // Create and then process appropriate request using state machine.
+ CCntRequest* request = NULL;
+ if (asyncActivity)
+ {
+ request = CReqAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
+ }
+ else
+ {
+ request = CReqNoAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
+ }
+ iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
+
+ // ProcessRequestL received ownership of the request, the request only need
+ // to be popped from CleanupStack.
+ CleanupStack::Pop(request);
+ }
+
+void CCntItemMsgHandler::ResourceCount(const RMessage2& aMessage)
+ {
+ #if defined(_DEBUG)
+ TInt totalAllocSize(0);
+ User::Heap().AllocSize(totalAllocSize);
+ RDebug::Print(_L("[CNTMODEL] Heap count: %d cells, total heap size: %d bytes"), User::Heap().Count(), User::Heap().Size());
+ RDebug::Print(_L("[CNTMODEL] cntsrv heap size: %d bytes"), totalAllocSize);
+ aMessage.Complete(User::Heap().Count());
+ #else
+ aMessage.Complete(KErrNone);
+ #endif
+ }
+
+void CCntItemMsgHandler::SetHeapFailure(const RMessage2& aMessage)
+ {
+ #if defined(_DEBUG)
+ User::__DbgSetAllocFail(RHeap::EUser,(RHeap::TAllocFail)aMessage.Int0(),aMessage.Int1());
+ #endif
+ aMessage.Complete(KErrNone);
+ }
+