diff -r 9f5ae1728557 -r db3f5fa34ec7 messagingfw/biomsgfw/BITSSRC/BioTestUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/biomsgfw/BITSSRC/BioTestUtils.cpp Wed Nov 03 22:41:46 2010 +0530 @@ -0,0 +1,1305 @@ +// Copyright (c) 2003-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: +// BioTestUtils.h +// + +#include "biotestutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#include +#include +#include "tmsvbioinfo.h" +#endif + +#define KCharSpace ' ' + +EXPORT_C CBioTestUtils::~CBioTestUtils() + { + Reset(); + delete iBioDb; + } + +EXPORT_C CBioTestUtils* CBioTestUtils::NewL(RTest& aRTest) + { + CBioTestUtils* self = new (ELeave) CBioTestUtils(aRTest); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +EXPORT_C CBioTestUtils* CBioTestUtils::NewLC(RTest& aRTest) + { + CBioTestUtils* self = new(ELeave) CBioTestUtils(aRTest); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C CBioTestUtils* CBioTestUtils::NewL(RTest& aRTest, TInt aCreationFlags) + { + CBioTestUtils* self = NewLC(aRTest, aCreationFlags); + CleanupStack::Pop(); + return self; + } + +EXPORT_C CBioTestUtils* CBioTestUtils::NewLC(RTest& aRTest, TInt aCreationFlags) + { + CBioTestUtils* self = new(ELeave) CBioTestUtils(aRTest); + CleanupStack::PushL(self); + self->ConstructL(aCreationFlags); + return self; + } + +void CBioTestUtils::Reset() + { + if(iTestParsedFieldArray) + { + iTestParsedFieldArray->ResetAndDestroy(); + delete iTestParsedFieldArray; + iTestParsedFieldArray=NULL; + } + if(iMessageBody) + { + delete iMessageBody; + iMessageBody = NULL; + } + if(iDir) + { + delete iDir; + iDir = NULL; + } + if(iRegisteredParserDll) + { + delete iRegisteredParserDll; + iRegisteredParserDll = NULL; + } + if (iBioClientMtm) + { + delete iBioClientMtm; + iBioClientMtm=NULL; + } + if (iBioServerMtm) + { + delete iBioServerMtm; + iBioServerMtm = NULL; + iServerEntry = NULL; + } + + iNumFiles = 0; + iFilesProcessed = 0; + iMessagesCreated = 0; + + CMsvTestUtils::Reset(); + } + +// +// Register a Sms Mtm server DLL +// +EXPORT_C void CBioTestUtils::CreateBioServerMtmRegL() + { + CreateServerMtmRegL(KUidMsgTypeSmartMessage, _L("BIO MTM"),KBioServerMtmFileName(), KBioClientMtmFileName(), TMsvTestDllInfo(KBioUiMtmFileName,2), TMsvTestDllInfo(KBioUiMtmFileName,1), KUidMsgTypeSmartMessage, KDataComponentFileName); + } + +CBioTestUtils::CBioTestUtils(RTest& aRTest) +: CMsvTestUtils(aRTest) + { + iBioServiceId = KMsvNullIndexEntryId; + } + +void CBioTestUtils::ConstructL() + { + TInt flags=NULL; // Settings flags for the base ConstructL() function + + // Loading the DLLs + iRTest.Next(_L("Create Data Component FileStores")); + + CMsvTestUtils::ConstructL(flags); + + iBioDb = CBIODatabase::NewL(iFs); + + FileSession().SetSessionPath(_L("c:\\")); + } + +// Overloaded constructor - allows developer to decide what components to create +void CBioTestUtils::ConstructL(TInt aCreationFlags) + { + iRTest.Next(_L("Initialising Data Components")); + // + CMsvTestUtils::ConstructL(aCreationFlags); + + iBioDb = CBIODatabase::NewL(iFs); + FileSession().SetSessionPath(_L("c:\\")); + } + + +void CBioTestUtils::Panic(TBioTestUtilsPanic aPanic) + { + Panic((TInt) aPanic); + } + +void CBioTestUtils::Panic(TInt aPanic) + { + User::Panic(BIOTEST_PANIC, aPanic); + } + +EXPORT_C TMsvId CBioTestUtils::CreateBIOEntryL(TDesC& aText, TBIOMessageType aMessageType ) + { + // Ensure that we have a valid service ID to work with: + if (iBioServiceId==0) + iBioServiceId = SetBIOServiceIdL(); + + // First take the descriptor reference and create a new descriptor to manipulate. + // Then convert '\n' to the paragraph delimiters used in proper SMS. + HBufC* localBuffer = aText.AllocL(); + CleanupStack::PushL(localBuffer); + + TPtr messDes = localBuffer->Des(); + + if (aMessageType != EBiovCardMessage && aMessageType != EBiovCalenderMessage) + { + // convert \r\n to \n since this is what is expected from SMS when not vCard data + for (TInt i=0; iDocumentLength(); // Ought to be 0. + richText->InsertL(pos, messDes); + + TMsvEntry newBioEntry; + newBioEntry.SetNew(ETrue); + newBioEntry.SetComplete(EFalse); + newBioEntry.SetUnread(ETrue); + newBioEntry.SetVisible(ETrue); + newBioEntry.SetReadOnly(EFalse); + newBioEntry.SetFailed(EFalse); + newBioEntry.SetOperation(EFalse); + newBioEntry.SetMultipleRecipients(EFalse); + newBioEntry.SetAttachment(EFalse); + newBioEntry.iMtm= KUidBIOMessageTypeMtm; + newBioEntry.iType=KUidMsvMessageEntry; + newBioEntry.iServiceId=iBioServiceId; + TTime now; + now.UniversalTime(); + newBioEntry.iDate = now; + + newBioEntry.iDescription.Set(richText->Read(0, richText->DocumentLength())); + TBufC telNumber; + HBufC* tempNumber = CreateDummyPhoneNumberL(); + telNumber = tempNumber->Des(); + newBioEntry.iDetails.Set(telNumber); + // Finished with telNumber, so free up the memory: + delete tempNumber; + + // Change the iServiceId, iMtm, iBioType for message: + SetForMtmTypeL(newBioEntry, aMessageType); + // Update the size to that of the attachment length - correct? + // Otherwise just get 68 + newBioEntry.iSize = richText->DocumentLength();// msgSize; + iClientServer == EServerSide ? CreateBioEntryServerSideL(newBioEntry,*richText) : CreateBioEntryClientSideL(newBioEntry,*richText); + + CleanupStack::PopAndDestroy(4); // richText, charFormatLayer, paraFormatLayer, localBuffer + return newBioEntry.Id(); + } + +void CBioTestUtils::SetForMtmTypeL(TMsvEntry& aEntry, TBIOMessageType aType) + { + TInt index; + // Should have a match for the Message Type as the message is created with the SMS id's. + switch(aType) + { + case ENoMessage: + // Just to keep compiler happy! + break; + case EBioIapSettingsMessage: + aEntry.iBioType = KUidBIOInternetAccessPointMsg; + break; + case EBioEnpMessage: + aEntry.iBioType =KUidBIOEmailNotificationMsg; + break; + case EBioRingTonesMessage: + aEntry.iBioType =KUidBIORingingTonesMsg; + break; + case EBioOpLogoMessage: + aEntry.iBioType =KUidBIOOperatorLogoMsg; + break; + case EBioCompBusCardMessage: + aEntry.iBioType =KUidBIOBusinessCardMsg; + break; + case EBiovCardMessage: + aEntry.iBioType =KUidBIOVCardMsg; + break; + case EBiovCalenderMessage: + aEntry.iBioType =KUidBIOVCalenderMsg; + break; + case EBioWAPSettingsMessage: + aEntry.iBioType =KUidBIOWAPAccessPointMsg; + break; + case EBioWPRVSettingsMessage: + aEntry.iBioType =KUidBIOWPRVMsg; + break; + } + // Set other TMsvEntry fields if we have a BIO message type + if (aType != ENoMessage) + { + aEntry.SetMtmData2(0); + aEntry.SetMtmData3(0); + } + + // set description from BIF file + iBioDb->GetBioIndexWithMsgIDL(TUid::Uid(aEntry.iBioType),index); + if(index==KErrNotFound) + User::Leave(KErrNotFound); + aEntry.iDescription.Set(iBioDb->BifReader(index).Description()); + } + +EXPORT_C void CBioTestUtils::LogCurrentMessageTypeL(TMsvId aMsvId) + { + // assume we're already pointing at a BIO message + TMsvEntry entry; + TMsvId oldId; + if(iClientServer == EServerSide) + { + oldId = iServerEntry->Entry().Id(); + User::LeaveIfError(iServerEntry->SetEntry(aMsvId)); + entry = iServerEntry->Entry(); + } + else + { + oldId = iMsvEntry->Entry().Id(); + iMsvEntry->SetEntryL(aMsvId); + entry = iMsvEntry->Entry(); + } + + TInt biotype = entry.iBioType; + if(biotype == KUidBIOInternetAccessPointMsg) + { + switch(entry.MtmData1()) + { + case 1: + WriteComment(_L("IACP basic IAP message")); + break; + case 2: + WriteComment(_L("IACP basic mail message")); + break; + case 3: + WriteComment(_L("IACP basic IAP & mail message")); + break; + case 7: + WriteComment(_L("IACP Internet script message")); + break; + case 8: + WriteComment(_L("IACP SMS settings message")); + break; + case 15: + WriteComment(_L("Telephone settings message")); + break; + default: + WriteComment(_L("Unsupported IACP type")); + break; + } + } + else if(biotype == KUidBIOEmailNotificationMsg) + WriteComment(_L("Email notification message")); + else if(biotype == KUidBIORingingTonesMsg) + WriteComment(_L("Ringing tones message")); + else if(biotype == KUidBIOOperatorLogoMsg) + WriteComment(_L("Operator logo message")); + else if(biotype == KUidBIOBusinessCardMsg) + WriteComment(_L("Compact Business Card message")); + else if(biotype == KUidBIOVCardMsg) + WriteComment(_L("vCard message")); + else if(biotype == KUidBIOVCalenderMsg) + WriteComment(_L("vCalendar")); + else if(biotype == KUidBIOWAPAccessPointMsg) + WriteComment(_L("WAP settings message")); + else + WriteComment(_L("Unknown type")); + + if(iClientServer == EServerSide) + { + User::LeaveIfError(iServerEntry->SetEntry(oldId)); + } + else + { + iMsvEntry->SetEntryL(oldId); + } + } + +EXPORT_C TMsvId CBioTestUtils::CreateBIOEntryFromFileL(const TDesC& aFilename, TBIOMessageType aMessageType) + { + //First use the filename to get the message body, + // then convert '\n' to the paragraph delimiters used in proper SMS + HBufC* tempBuffer; + TMsvId newEntryId; + tempBuffer = ReadFromFileL(aFilename); + CleanupStack::PushL(tempBuffer); + + newEntryId = CreateBIOEntryL(*tempBuffer, aMessageType ); + + // Finished with our local descriptors - free up some memory + CleanupStack::PopAndDestroy(); + return newEntryId; + } + + +EXPORT_C void CBioTestUtils::EmptyInboxMessagesL() + { + // Function gets the Inbox Entry, and then all the children of this entry. + // Then we iterate through the selection deleting each entry. + CMsvEntrySelection* inboxMessageSel; + if(iClientServer == EServerSide) + { + inboxMessageSel = new (ELeave) CMsvEntrySelection; + CleanupStack::PushL(inboxMessageSel); + // Create a local Server entry, and get the children of the Global Inbox: + User::LeaveIfError(iServerEntry->SetEntry(KMsvGlobalInBoxIndexEntryId)); + iServerEntry->GetChildren(*inboxMessageSel ); // children of parent, ie global inbox + if (inboxMessageSel->Count() != 0) + { + iServerEntry->DeleteEntries(*inboxMessageSel); + } + // Point back at something safe before we return: + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + } + else + { + iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId); + inboxMessageSel = iMsvEntry->ChildrenL(); + CleanupStack::PushL(inboxMessageSel); + if (inboxMessageSel->Count() != 0) + { + TInt count; + TMsvId currentMsgId; + for (count = 0; count < inboxMessageSel->Count(); count++) + { + currentMsgId= inboxMessageSel->At(count); + // Delete this entry + DeleteLocalEntrySynchronouslyL(*iMsvEntry, currentMsgId); + } + } + iMsvEntry->SetEntryL(KMsvRootIndexEntryId); + } + CleanupStack::PopAndDestroy(); // inboxMessageSel + } + +void CBioTestUtils::DeleteLocalEntrySynchronouslyL(CMsvEntry& aParentEntry, TMsvId anId) + { + // Creates an entry synchronously by handling the asynchrous parts locally + + const TMsvSelectionOrdering& originalSort=aParentEntry.SortType(); + TMsvSelectionOrdering sort(originalSort); + sort.SetShowInvisibleEntries(ETrue); + aParentEntry.SetSortTypeL(sort); + CMsvOperationWait* myDog=CMsvOperationWait::NewLC(); + CMsvOperation* op=aParentEntry.DeleteL(anId, myDog->iStatus); + myDog->Start(); + CActiveScheduler::Start(); + const TInt err=op->iStatus.Int(); + TMsvLocalOperationProgress progress=McliUtils::GetLocalProgressL(*op); + delete op; + User::LeaveIfError(err); + User::LeaveIfError(progress.iError); + CleanupStack::PopAndDestroy(); + aParentEntry.SetSortTypeL(originalSort); + } +//************************************************************************* +// +// Getting BIO service ID +// +//************************************************************************* + +// Get,or create, the default BIO service: +EXPORT_C TMsvId CBioTestUtils::SetBIOServiceIdL() + { + // If Bio service Id is none zero its already been set - just return the value: + if (iBioServiceId) + return iBioServiceId; + + if(iClientServer == EServerSide) + SetBioServiceServerSideL(); + else + SetBioServiceClientSideL(); + return iBioServiceId; + } + +void CBioTestUtils::SetBioServiceServerSideL() + { + // Set up the RootEntry sort order first: + TMsvSelectionOrdering oldSortType = iServerEntry->Sort(); + TMsvSelectionOrdering sortType(KMsvGroupByType, EMsvSortByNone, ETrue); + iServerEntry->SetSort(sortType); + + // Search the root folder for any entries which are BIO Message services. + // If none are found then create one. + TMsvId localServiceId=KMsvNullIndexEntryId; + localServiceId = DefaultServiceForMTML(KUidBIOMessageTypeMtm, ETrue); + + // Check that the Service id is valid, i.e. set iCurrentEntry context to service entry: + TRAPD( error, iServerEntry->SetEntry(localServiceId) ); + if ( (localServiceId == KMsvUnknownServiceIndexEntryId) || (error == KErrNotFound) ) + { + // Id isn't a valid BIO service, so try and get the first BIO service: + CMsvEntrySelection* sel = GetListOfAccountsWithMTMServerL(KUidBIOMessageTypeMtm); + CleanupStack::PushL(sel); + if (sel->Count()) + iBioServiceId=(*sel)[0]; // Select the first available service. + CleanupStack::PopAndDestroy(); // sel + if (localServiceId == KMsvUnknownServiceIndexEntryId || localServiceId == KMsvNullIndexEntryId) + // Haven't found any valid BIO service, so try and create a BIO service: + localServiceId=CreateDefaultBIOServiceL(); + } + else + User::LeaveIfError(error); // An error other than no service occurred. + + __ASSERT_DEBUG( localServiceId != KMsvNullIndexEntryId, User::Panic(_L("BioGen"), KErrNotFound)); + + // Point back at something safe: + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + iServerEntry->SetSort(oldSortType); + + iBioServiceId = localServiceId; + } + +void CBioTestUtils::SetBioServiceClientSideL() + { + iMsvEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvGroupByType, EMsvSortByNone, ETrue)); +#if defined (_DEBUG) + if (iMsvEntry->EntryId() != KMsvRootIndexEntryId) //iMsvEntry should be set to root + User::Leave(KErrNotFound); //replaces a panic - ENotAServiceEntry +#endif + + TMsvId localServiceId=KMsvNullIndexEntryId; + localServiceId=DefaultServiceForMTML(KUidBIOMessageTypeMtm, ETrue); + + //Check if there is a valid entry for this ID + TRAPD(ret, /*const TMsvEntry& ent=*/iMsvEntry->ChildDataL(localServiceId)); + + if (localServiceId == KMsvUnknownServiceIndexEntryId || ret==KErrNotFound) + { + // Our Id isn't a valid BIO service, possibly because there isn't a default + // BIO service. So try and get the first BIO service. + CMsvEntrySelection* sel=GetListOfAccountsWithMTMClientL(KUidBIOMessageTypeMtm); + if (sel->Count()) + localServiceId=(*sel)[0]; // select the first available service + delete sel; + if (localServiceId == KMsvUnknownServiceIndexEntryId || localServiceId == KMsvNullIndexEntryId) + // No SMS service present, so let's create one + CreateServicesL(); + } + else + User::LeaveIfError(ret); // an error other than no service occurred + +#if defined (_DEBUG) + if (localServiceId == KMsvNullIndexEntryId) + User::Leave(KErrNotFound); //replaces a panic - ENotAServiceEntry +#endif + iBioServiceId = localServiceId; + } + +TMsvId CBioTestUtils::CreateDefaultBIOServiceL() + { + // Haven't found an entry so create a BIO Message service: + TMsvEntry bioServiceEntry; + bioServiceEntry.iMtm = KUidBIOMessageTypeMtm; + bioServiceEntry.iType = KUidMsvServiceEntry; + bioServiceEntry.SetVisible(EFalse); + bioServiceEntry.iDate.UniversalTime(); + bioServiceEntry.iDescription.Set(_L("BIO Message Service ")); // Is there such a thing? + bioServiceEntry.iDetails.Set(_L("BIO Message Service")); + +// no need to set default service for v2, CBaseMtm 'knows' that for services +// where there is a single service entry, it has to be the default + TMsvId newBIOServiceId; + if(iClientServer == EServerSide) + { + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + User::LeaveIfError(iServerEntry->CreateEntry(bioServiceEntry)); // Needs to be a child of the root! + newBIOServiceId =bioServiceEntry.Id(); + + } + else + { + iMsvEntry->SetEntryL(KMsvRootIndexEntryId); + iMsvEntry->CreateL(bioServiceEntry); // Needs to be a child of the root! + newBIOServiceId =bioServiceEntry.Id(); + + } + + // No need to set Server Entry - still pointing at the root. + return newBIOServiceId; + } + + +TMsvId CBioTestUtils::DefaultServiceForMTML(TUid aMtmUid, TBool aFindFirstServiceIfNoDefault) + { + TMsvId serviceId=KMsvUnknownServiceIndexEntryId; + if(iClientServer == EServerSide) + serviceId = DefaultServiceServerL(aMtmUid,aFindFirstServiceIfNoDefault); + else + serviceId = DefaultServiceClientL(aMtmUid,aFindFirstServiceIfNoDefault); + return serviceId; + } + +TMsvId CBioTestUtils::DefaultServiceServerL(TUid aMtmUid, TBool /*aFindFirstServiceIfNoDefault*/) + { + TMsvId serviceId=KMsvUnknownServiceIndexEntryId; + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + + // Find first available service with the desired iMtm value: + CMsvEntrySelection* sel=new (ELeave) CMsvEntrySelection; + CleanupStack::PushL(sel); + + iServerEntry->GetChildren(*sel); + + for (TInt count = 0; serviceId != 0 && count < sel->Count(); count++) + { + User::LeaveIfError(iServerEntry->SetEntry(sel->At(count))); + if (iServerEntry->Entry().iMtm == aMtmUid) + serviceId = sel->At(count); + } + CleanupStack::PopAndDestroy(); // sel + + // Point back at something safe: + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + + return serviceId; + } + +TMsvId CBioTestUtils::DefaultServiceClientL(TUid /*aMtmUid*/, TBool /*aFindFirstServiceIfNoDefault*/) + { + if (!iBioClientMtm) + { + InstantiateClientMtmsL(); + } + return iBioClientMtm->DefaultServiceL(); + } + +CMsvEntrySelection* CBioTestUtils::GetListOfAccountsWithMTMServerL(TUid aMtmUid) + { + // Gets a list of entries with the passed in MTM. + CMsvEntrySelection* returnSelection =new(ELeave) CMsvEntrySelection(); + CleanupStack::PushL(returnSelection); + + CMsvEntrySelection* rootKin = new (ELeave) CMsvEntrySelection(); + CleanupStack::PushL(rootKin); + + CMsvEntrySelection* entryKin = new (ELeave) CMsvEntrySelection(); + CleanupStack::PushL(entryKin); + + TMsvSelectionOrdering oldSortType = iServerEntry->Sort(); + TMsvSelectionOrdering sortType(KMsvGroupByType|KMsvGroupByStandardFolders, EMsvSortByDetailsReverse, ETrue); + + // iCurrentEntry should be pointing towards the root, but make sure: + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryIdValue)); + iServerEntry->SetSort(sortType); + iServerEntry->GetChildren(*rootKin); // Get the child entries of the root. + + TBool visible=EFalse; + TInt err; + if ( rootKin->Count() !=0) + { + TMsvEntry tentry; + for (TInt cc=rootKin->Count(); --cc>=0; ) // N.B. decrements prior to entering loop. + { + // Set the context of our Server Entry to the next child entry of the root: + User::LeaveIfError(iServerEntry->SetEntry(rootKin->At(cc)) ); + // Get the entry and check its mtm type: + tentry =iServerEntry->Entry(); + if (tentry.iMtm==aMtmUid) + { + // Is it a proper service entry? + if (tentry.iType.iUid==KUidMsvServiceEntryValue && tentry.Id()!=KMsvLocalServiceIndexEntryIdValue) + { + // If it's visible or it has no entry in the index - add to our return array: + if (tentry.Visible() || tentry.iRelatedId==KMsvNullIndexEntryId) + returnSelection->AppendL(tentry.Id()); + else if (tentry.iRelatedId!=tentry.Id()) + { + // Check if there are any related entries: + TRAP(err, iServerEntry->GetChildren(*entryKin) ); + TInt count = entryKin->Count(); + while (count--) + { + User::LeaveIfError(iServerEntry->SetEntry( entryKin->At(count) ) ); + if (iServerEntry->Entry().Id() == tentry.iRelatedId) + break; + } + visible=iServerEntry->Entry().Visible(); + if (err==KErrNone && !visible && returnSelection->Find(tentry.iRelatedId)!=KErrNone) + returnSelection->AppendL(tentry.Id()); + } + } + } + } + } + + // Point back at something safe: + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + iServerEntry->SetSort(oldSortType); + CleanupStack::PopAndDestroy(2); // entryKin, rootKin, + CleanupStack::Pop(); // returnSelection + + return returnSelection; + } + +CMsvEntrySelection* CBioTestUtils::GetListOfAccountsWithMTMClientL(TUid aMtmUid) + { + // Gets a list of entries with the passed in MTM + CMsvEntrySelection* returnSelection =new(ELeave) CMsvEntrySelection(); + CleanupStack::PushL(returnSelection); + + CMsvEntrySelection* rootKin; + CMsvEntrySelection* entryKin; + + TMsvSelectionOrdering oldSortType = iMsvEntry->SortType(); + TMsvSelectionOrdering sortType(KMsvGroupByType|KMsvGroupByStandardFolders, EMsvSortByDetailsReverse, ETrue); + + // iCurrentEntry should be pointing towards the root, but make sure + iMsvEntry->SetEntryL(KMsvRootIndexEntryIdValue); + iMsvEntry->SetSortTypeL(sortType); + rootKin=iMsvEntry->ChildrenL(); // Get the child entries of the root + CleanupStack::PushL(rootKin); + + TBool visible=EFalse; + + if ( rootKin->Count() !=0) + { + TMsvEntry tentry; + for (TInt cc=rootKin->Count(); --cc>=0; ) // NB decrements prior to entering loop + { + // Set the context of our Server Entry to the next child entry of the root + iMsvEntry->SetEntryL(rootKin->At(cc)) ; + // get the entry and check it's mtm type + tentry =iMsvEntry->Entry(); + if (tentry.iMtm==aMtmUid) + { + // Is it a proper service entry + if (tentry.iType.iUid==KUidMsvServiceEntryValue && tentry.Id()!=KMsvLocalServiceIndexEntryIdValue) + { + // if it's visible or it has no entry in the index - add to our return array + if (tentry.Visible() || tentry.iRelatedId==KMsvNullIndexEntryId) + returnSelection->AppendL(tentry.Id()); + else if (tentry.iRelatedId!=tentry.Id()) + { + // Check if there are any related entries + entryKin=iMsvEntry->ChildrenL() ; + CleanupStack::PushL(entryKin); + + TInt count = entryKin->Count(); + while (count--) + { + iMsvEntry->SetEntryL( entryKin->At(count) ); + if (iMsvEntry->Entry().Id() == tentry.iRelatedId) + break; + } + visible=iMsvEntry->Entry().Visible(); + if (!visible && returnSelection->Find(tentry.iRelatedId)!=KErrNone) + returnSelection->AppendL(tentry.Id()); + CleanupStack::PopAndDestroy(); // entryKin + } + } + } + } + } + + // Point back at something safe..... + iMsvEntry->SetEntryL(KMsvRootIndexEntryId); + iMsvEntry->SetSortTypeL(oldSortType); + CleanupStack::PopAndDestroy(); // entryKin, rootKin, + CleanupStack::Pop(); //returnSelection + + return returnSelection; + } + + +//***************************************************************************** +// +// File Read and Message Creation functions +// +//***************************************************************************** +EXPORT_C void CBioTestUtils::SetSessionPath(const TDesC& aSessionPath) + { + iFs.SetSessionPath(aSessionPath); + } + +HBufC* CBioTestUtils::ReadFromFileL(const TDesC& aFile) + { + // Reads in data from a file and loads it into a buffer which is later used + // to create an SMS message in the Inbox. This function differs from the others + // in that it also gets any From: field by locating the token in the file. + // NOTE: There is an inherent assumption that the From: token and the field will + // be on a single line in the text file (i.e. less than 1024 characters. + RFile file; + TBuf8<1024> lineBuffer; // Buffer for Read function. + TInt err=KErrNone; + + err = file.Open(iFs,aFile,EFileStreamText|EFileRead|EFileShareAny); + + if(err != KErrNone) // Didn't find the file, so leave - should only get valid filenames! + { + User::Leave(KErrNotFound); + } + + // In real life this is set by the Socket Port Observer, or the SMS server. + // So,in this test code we must do it by creating a random telephone number. + // iMessageDetails = CreateDummyPhoneNumberL(); + + HBufC* bioBuf=HBufC::NewLC(65535); // Create a new descriptor on the heap. + HBufC* copyBuffer=HBufC::NewLC(1024); + + do // Read in the text from file, and also check if there is a name field: + { + err = file.Read(lineBuffer);// Read upto 256 chars, '\n' and all... + //err = ReadLineL(file,lineBuffer); + if (err==KErrNone) // Made a valid read, + if (lineBuffer.Length()==0) // but read 0 chars + err=KErrEof; // so set err value to end processing + + if(err == KErrNone) + { + copyBuffer->Des().Copy(lineBuffer);// Copy, and overwrite existing text + if( (bioBuf->Length() + copyBuffer->Length()) > bioBuf->Des().MaxLength() ) + { + bioBuf = bioBuf->ReAllocL(bioBuf->Length() + copyBuffer->Length()); + } + bioBuf->Des().Append(*copyBuffer); + //bioBuf->Des().Append(_L("\n")); + } + } + while(err != KErrEof); + + CleanupStack::PopAndDestroy(); // Destroy the copyBuffer. + CleanupStack::Pop();// Remove the bioBuf. + + file.Close(); + return bioBuf; // Transfer ownership and responsibility of the buffer. + } + + + +//***************************************************************************** +// +// Creating a dummy phone number for use in messages +// +//***************************************************************************** + + + +HBufC* CBioTestUtils::CreateDummyPhoneNumberL() + { + HBufC* number= HBufC::NewL(32); // Note: function doesn't own this, up to the caller to delete + TInt64 phoneNo; + TInt64 seed; + TTime tempTime; + tempTime.UniversalTime(); + seed=tempTime.Int64(); + phoneNo= Math::Rand(seed); + if (phoneNo <0) + phoneNo = -phoneNo; + number->Des().Num( phoneNo); + number->Des().Insert(0,_L("+44"));// Add a leading '+' to make if an international numbers + return number; + } + + +void CBioTestUtils::CreateBioEntryServerSideL(TMsvEntry& aEntry, CRichText& aBody) + { + // Get the global inbox: + User::LeaveIfError(iServerEntry->SetEntry(KMsvGlobalInBoxIndexEntryId)); + // Entry Context already set, create our entry: + User::LeaveIfError(iServerEntry->CreateEntry(aEntry)); + // Set our context to the the new entry so we can create a store: + User::LeaveIfError(iServerEntry->SetEntry(aEntry.Id()) ); + // Save all the changes: + CMsvStore* store; + store=iServerEntry->EditStoreL(); + CleanupStack::PushL(store); + + if (store->HasBodyTextL()) + { + store->DeleteBodyTextL(); + } + store->StoreBodyTextL(aBody); + store->CommitL(); + CleanupStack::PopAndDestroy(); // Close and destroy the store. + // Set context to the new entry to allow updating of the entry: + aEntry.SetComplete(ETrue); + iServerEntry->ChangeEntry(aEntry); + User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); + } + +void CBioTestUtils::CreateBioEntryClientSideL(TMsvEntry& aEntry, CRichText& aBody) + { + // Get the global inbox. + iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId); + iMsvEntry->CreateL(aEntry); + iMsvEntry->SetEntryL(aEntry.Id()); + + // Save all the changes + CMsvStore* store; + store=iMsvEntry->EditStoreL(); + CleanupStack::PushL(store); + + if (store->HasBodyTextL()) + { + store->DeleteBodyTextL(); + } + store->StoreBodyTextL(aBody); + store->CommitL(); + + CleanupStack::PopAndDestroy(); //store - close the store + + aEntry.SetComplete(ETrue); + // Update the entry + iMsvEntry->ChangeL(aEntry); + iMsvEntry->SetEntryL(KMsvRootIndexEntryId); + } + +void CBioTestUtils::InstantiateClientMtmsL() + { + // client side + __ASSERT_ALWAYS(iMsvSession, User::Panic(BIOTEST_PANIC, KErrBIONotOnClientSide)); + if(iClientMtmRegistry) + delete iClientMtmRegistry; + iClientMtmRegistry = CClientMtmRegistry::NewL(*iMsvSession); + iBioClientMtm = (CBIOClientMtm*) iClientMtmRegistry->NewMtmL(KUidMsgTypeSmartMessage); + } + +void CBioTestUtils::InstantiateServerMtmsL() + { + iBioServerMtm = (CBIOServerMtm*) InstantiateServerMtmL(KUidBIOMessageTypeMtm, iBioServiceId); + const CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection(); + TRequestStatus st; + TMsvId s =0; + TRAP_IGNORE(iBioServerMtm->CopyFromLocalL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->CopyToLocalL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->CopyWithinServiceL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->MoveFromLocalL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->MoveToLocalL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->MoveWithinServiceL(*selection,s, st)); + TRAP_IGNORE(iBioServerMtm->DeleteAllL(*selection,st)); + + TInt intw =0; + + TRAP_IGNORE(iBioServerMtm->Cancel()); + iBioServerMtm->CommandExpected(); + TMsvEntry entry; + + TRAP_IGNORE(iBioServerMtm->ChangeL(entry,st)); + TRAP_IGNORE(iBioServerMtm->CreateL(entry,st)); + delete selection; + } + +void CBioTestUtils::DeleteServicesL() + { + DeleteServiceL(KUidBIOMessageTypeMtm); + } + +void CBioTestUtils::CreateServicesL() + { + iBioServiceId = CreateServiceL(KUidMsgTypeSmartMessage); + } + +void CBioTestUtils::FindExistingServicesL() + { + iBioServiceId = 0; + TRAPD(err,ServiceIdL(KUidMsgTypeSmartMessage, iBioServiceId)); + if (err) + Printf(_L("No existing SMS services found!\n")); + } + +void CBioTestUtils::InstallMtmGroupsL() + { + InstallMtmGroupL(KDataComponentFileName); + } + +void CBioTestUtils::CreateServerMtmRegsL() + { + CreateBioServerMtmRegL(); + } + +// +// stuff to generate test BIO messages +// + +EXPORT_C CMsvEntrySelection* CBioTestUtils::GenerateMessagesL() + { + return GenerateMessagesL(KBIOTxtFilePath); + } + +EXPORT_C CMsvEntrySelection* CBioTestUtils::GenerateMessagesL(const TDesC& aFileDirectory, TBool aLogCreationDetails) + { + TBufC currentFile; + TMsvId messageId; + TBIOMessageType currentMsgType; + + CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection(); + CleanupStack::PushL(selection); + + TInt err = iFs.GetDir(aFileDirectory, KEntryAttMatchMask, ESortByName, iDir); + if (err == KErrPathNotFound) + { + TInt makeDirErr = iFs.MkDirAll(aFileDirectory); + makeDirErr==KErrNone ? User::Leave(KErrNotFound): User::Leave(makeDirErr); + } + else if (err!=KErrNone) + { + User::Leave(err); + } + + // Set the session path for the RFs + SetSessionPath(aFileDirectory); + if (iDir) + delete iDir; + User::LeaveIfError(iFs.GetDir(_L("*.txt"), KEntryAttNormal, ESortByName, iDir)); + TInt count = iDir->Count(); + if(count == 0) + { + User::Leave(KErrNotFound); // No files to process + } + + TBuf<60> outputBuf; + + for(TInt loop = 0; loop < count; loop++) + { + currentFile=( (*iDir)[iFilesProcessed].iName ); + // Not processed all the messages - so keep the current state + iFilesProcessed++; // Here because need to update the counter promptly + currentMsgType = SetMessageType(currentFile); + if (currentMsgType!=ENoMessage) // skip any dodgy filenames + { + messageId = CreateBIOEntryFromFileL( currentFile,currentMsgType); + selection->AppendL(messageId); + TPtrC tempPtr = (currentFile.Des() ); + if (aLogCreationDetails) + { + outputBuf.Format(_L("TMsvId %d - %S"), messageId, &tempPtr); + WriteComment(outputBuf); + } + } + } + CleanupStack::Pop(); // selection + return selection; + } + +EXPORT_C TBIOMessageType CBioTestUtils::SetMessageType(const TDesC& aFileName) + { + + // Check each file prefix in turn with the filename passed as a parameter. + // If cannot find the correct type set to ENoMessage to indicate an error. + // GenerateNextMessage will then skip the file! + + if (aFileName.MatchF(KBIOIapPrefix)==0) // File starts with "iap" + { + return EBioIapSettingsMessage; + } + if(aFileName.MatchF(KBIOEnpPrefix)==0) // File name starts "enp" + { + return EBioEnpMessage; + } + if (aFileName.MatchF(KBIORingTonePrefix)==0)//Filename begins "rtone" + { + return EBioRingTonesMessage; + } + if (aFileName.MatchF(KBIOOpLogoPrefix)==0) // Filename begins "oplogo" + { + return EBioOpLogoMessage; + } + if (aFileName.MatchF(KBIOcBusinessCardPrefix)==0)// Filename begins "cbc" + { + return EBioCompBusCardMessage; + } + if (aFileName.MatchF(KBIOvCardPrefix)==0) + { + return EBiovCardMessage; + } + if (aFileName.MatchF(KBIOvCalenderPrefix)==0) + { + return EBiovCalenderMessage; + } + if (aFileName.MatchF(KBIOWappPrefix)==0) + { + return EBioWAPSettingsMessage; + } + // if we've reached this point it's an unknown filename + return ENoMessage; + } + +EXPORT_C void CBioTestUtils::DoAppendVariantName(TDes& aFileName) + { +#if defined(__WINS__) && defined(__WINSCW__) + aFileName.Append(_L(".WINSCW.")); +#elif(__WINS__) + aFileName.Append(_L(".WINS.")); +#endif +#if (defined(__THUMB__) || defined(__MARM_THUMB__)) + aFileName.Append(_L(".THUMB.")); +#endif +#if (defined(__ARMI__) || defined(__MARM_ARMI__)) + aFileName.Append(_L(".ARMI.")); +#endif +#if (defined(__ARM4__) || defined(__MISA__) || defined(__MARM_ARM4__)) + aFileName.Append(_L(".ARM4.")); +#endif + +#if defined(_DEBUG) + aFileName.Append(_L("DEB.")); +#else + aFileName.Append(_L("REL.")); +#endif + + aFileName.Append(_L("LOG")); + } + +// +// Create a return the appropriate parser for the biomsg with id +// +EXPORT_C CBaseScriptParser2* CBioTestUtils::CreateParserL(TMsvId aBioMsgId) + { + TMsvEntry myBioEntry; + + if(iClientServer==EClientSide) + { + iMsvEntry->SetEntryL(aBioMsgId); + myBioEntry = iMsvEntry->Entry(); + } + else + { + User::Leave(KErrNotSupported); + } + + // check its the right type + if(myBioEntry.iMtm.iUid != KUidMsgTypeSmartMessage.iUid) + User::Leave(KBspInvalidMessage); + + return CreateParserTypeL(myBioEntry.iBioType); + } + +EXPORT_C CBaseScriptParser2* CBioTestUtils::CreateParserTypeL(TInt32 aBioMsgType) + { + // get the bio type and create the parser + TUid messageUid = TUid::Uid(aBioMsgType); + + // look up identification for parser + TFileName parserDllName(iBioDb->GetBioParserNameL(messageUid)); + + if (iRegisteredParserDll) // Already have an old RegParserDll, delete it to stop memory leak. + { + delete iRegisteredParserDll; + iRegisteredParserDll = NULL; + } + + iRegisteredParserDll = CRegisteredParserDll::NewL(parserDllName); // Create a new RegParserDll + + RLibrary parserlibrary; + User::LeaveIfError(iRegisteredParserDll->GetLibrary(iFs, parserlibrary)); + + typedef CBaseScriptParser2* (*NewParserL)(CRegisteredParserDll& aRegisteredParserDll, CMsvEntry& aEntry, RFs& aFs); + + TInt entrypointordinalnumber=1; // The one and only entry point + TLibraryFunction libFunc=parserlibrary.Lookup(entrypointordinalnumber); + if (libFunc==NULL) + User::Leave(KErrBadLibraryEntryPoint); + NewParserL pFunc=(NewParserL) libFunc; + TInt refcount=iRegisteredParserDll->DllRefCount(); + CBaseScriptParser2* parser=NULL; + TRAPD(ret,parser=((*pFunc)(*iRegisteredParserDll, *iMsvEntry, iFs))); + if ((ret!=KErrNone) && (iRegisteredParserDll->DllRefCount()==refcount)) + iRegisteredParserDll->ReleaseLibrary(); + + User::LeaveIfError(ret); + return parser; + } + +EXPORT_C TPtrC CBioTestUtils::MessageBodyL(TMsvId aBioMsgId) + { + CMsvStore* store = NULL; + if(iClientServer==EServerSide) + { + User::LeaveIfError(iServerEntry->SetEntry(aBioMsgId)); + if(iServerEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) + User::Leave(KBspInvalidMessage); + store = iServerEntry->ReadStoreL(); + } + else + { + iMsvEntry->SetEntryL(aBioMsgId); + if(iMsvEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) + User::Leave(KBspInvalidMessage); + store = iMsvEntry->ReadStoreL(); + } + // Extract the body text or leave false if not + CleanupStack::PushL(store); + CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL(); + CleanupStack::PushL(paraFormatLayer); + CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(); + CleanupStack::PushL(charFormatLayer); + CRichText* richText = CRichText::NewL(paraFormatLayer, charFormatLayer); + CleanupStack::PushL(richText); + + store->HasBodyTextL() ? store->RestoreBodyTextL(*richText) : User::Leave( KErrNotFound); + + TInt messageLength = richText->DocumentLength(); + + delete iMessageBody; + iMessageBody = HBufC::NewL(messageLength); + TPtr messDes = iMessageBody->Des(); + + TInt length = messDes.Length(); + while(length < messageLength) + { + TPtrC desc = richText->Read(length, messageLength-length); + messDes.Append(desc); + length+=desc.Length(); + } + + CleanupStack::PopAndDestroy(4); // store, text, charFormatLayer, paraFormatLayer + return messDes; + } + +EXPORT_C void CBioTestUtils::LogExtractedFieldsL(TMsvId aMessage) + { + // make sure we've got the right entry + CMsvStore* store = NULL; + if(iClientServer==EServerSide) + { + User::LeaveIfError(iServerEntry->SetEntry(aMessage)); + if(iServerEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) + User::Leave(KBspInvalidMessage); + store = iServerEntry->ReadStoreL(); + } + else + { + iMsvEntry->SetEntryL(aMessage); + if(iMsvEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) + User::Leave(KBspInvalidMessage); + store = iMsvEntry->ReadStoreL(); + } + // Extract the body text or leave false if not + CleanupStack::PushL(store); + + // try to get our array of parsed fields + RMsvReadStream in; + in.OpenLC( *store, KUidMsvBIODataStream ); + InternalizeL(in); + CleanupStack::PopAndDestroy(); + + HBufC* fieldBuf = NULL; + TInt length = 0; + WriteComment(_L("Extracted fields")); + for(TInt loop = 0; loop < iTestParsedFieldArray->Count(); loop++) + { + CParsedField& field = *(*iTestParsedFieldArray)[loop]; + length = (field.FieldName().Length() + field.FieldValue().Length() + 1); + + delete fieldBuf; + fieldBuf = HBufC::NewL(length); + TPtr des = fieldBuf->Des(); + des.Append(field.FieldName()); + des.Append(KCharSpace); + des.Append(field.FieldValue()); + + //FieldValue may be bigger than '0x100' i.e logging script + //this may exeede max buffer, so we need to break it into chuncks + //of 64 chars and log the chuncks in sequence. + TInt desLength = des.Length(); + TInt BufSize=64; + if (desLength > BufSize) + { + TBuf<64> tempBuf; + TInt count=0; + while(count <= desLength) + { + if(desLength-count > BufSize ) + tempBuf= des.Mid(count,BufSize); + else + tempBuf= des.Mid(count,desLength-count); + + WriteComment(tempBuf); + count+=BufSize; + } + } + else + WriteComment(des); + + } + delete fieldBuf; + CleanupStack::PopAndDestroy(); + } + + +void CBioTestUtils::InternalizeL(RMsvReadStream& aReadStream) + { + if(iTestParsedFieldArray) + { + iTestParsedFieldArray->ResetAndDestroy(); + delete iTestParsedFieldArray; + iTestParsedFieldArray=NULL; + } + + iTestParsedFieldArray = new(ELeave) CArrayPtrSeg(16); + + CParsedField* parsedField = NULL; + TInt count = aReadStream.ReadUint8L(); + for (TInt i=0; i < count; i++) + { + parsedField = new (ELeave) CParsedField(); + TRAPD(err, parsedField->InternalizeL(aReadStream)) + if(err) + { + delete parsedField; //deletes the last allocated object, privious ones will be deleted by iParsedFieldArray->ResetAndDestroy() + User::Leave(err); + } + iTestParsedFieldArray->AppendL(parsedField); + } + } + +EXPORT_C CArrayPtrSeg& CBioTestUtils::ParsedFieldArray() + { + return *iTestParsedFieldArray; + }