phonebookengines_old/contactsmodel/tsrc/T_RefineFindViewL.cpp
changeset 40 b46a585f6909
equal deleted inserted replaced
37:fd64c38c277d 40:b46a585f6909
       
     1 // Copyright (c) 2001-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 #include <e32test.h>
       
    17 #include <cntdef.h>
       
    18 #include <cntdb.h>
       
    19 #include <cntitem.h>
       
    20 #include <cntfield.h>
       
    21 #include <cntfldst.h>
       
    22 #include <cntviewbase.h>
       
    23 #include <cntview.h>
       
    24 
       
    25 #include "CContactViewEventQueue.h"
       
    26 #include "cfindtext.h"
       
    27 #include "t_utils2.h"
       
    28 #include "T_UTILS.H"
       
    29 
       
    30 _LIT(KTestName, "T_RefineFindViewL");
       
    31 
       
    32 _LIT(KTestDbName, "c:T_RefineFindViewL.cdb");
       
    33 
       
    34 const TInt KMaxNumContacts=1000;
       
    35 
       
    36 LOCAL_D RTest test(KTestName);
       
    37 
       
    38 
       
    39 class CTestResources : public CBase
       
    40     {
       
    41     public:
       
    42         static CTestResources* NewLC();
       
    43         void ConstructL();
       
    44         void CreateTestContactsL();
       
    45 		void CreateMoreTestContactsL();
       
    46         ~CTestResources();
       
    47 
       
    48         CContactDatabase* iDb;
       
    49         CContactViewEventQueue* iViewEventQueue;
       
    50         RContactViewSortOrder iViewSortOrder;
       
    51         CContactLocalView* iLocalView;
       
    52         CContactViewEventQueue* iFindViewEventQueue;
       
    53         CContactFindView* iFindView;
       
    54         CFindText* iFindText;
       
    55     };
       
    56 
       
    57 CTestResources* CTestResources::NewLC()
       
    58     {
       
    59     CTestResources* self = new(ELeave) CTestResources;
       
    60     CleanupStack::PushL(self);
       
    61     self->ConstructL();
       
    62     return self;
       
    63     }
       
    64 
       
    65 void CTestResources::ConstructL()
       
    66     {
       
    67     iDb = CContactDatabase::ReplaceL(KTestDbName);
       
    68 
       
    69     CreateTestContactsL();
       
    70 
       
    71     iViewEventQueue = CContactViewEventQueue::NewL();
       
    72 
       
    73     iViewSortOrder.AppendL(KUidContactFieldFamilyName);
       
    74     iViewSortOrder.AppendL(KUidContactFieldGivenName);
       
    75     iViewSortOrder.AppendL(KUidContactFieldCompanyName);
       
    76     
       
    77     const TContactViewPreferences prefs = 
       
    78         static_cast<TContactViewPreferences>(EContactsOnly);
       
    79     iLocalView = CContactLocalView::NewL
       
    80         (*iViewEventQueue, *iDb, iViewSortOrder, prefs);
       
    81 
       
    82     // Wait for view to get ready
       
    83     TContactViewEvent event;
       
    84     __ASSERT_ALWAYS(iViewEventQueue->ListenForEvent(10,event),User::Invariant());
       
    85     __ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady,User::Invariant());
       
    86     }
       
    87 
       
    88 void CTestResources::CreateTestContactsL()
       
    89     {
       
    90     // Create a few test contacts in the db
       
    91     CContactCard* card;
       
    92     CContactItemField* field;
       
    93     card = CContactCard::NewLC();
       
    94     field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
       
    95     field->TextStorage()->SetTextL(_L("Graham"));
       
    96     card->AddFieldL(*field);
       
    97     CleanupStack::Pop(field);
       
    98     iDb->AddNewContactL(*card);
       
    99     CleanupStack::PopAndDestroy(card);
       
   100 
       
   101     card = CContactCard::NewLC();
       
   102     field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
       
   103     field->TextStorage()->SetTextL(_L("Sami"));
       
   104     card->AddFieldL(*field);
       
   105     CleanupStack::Pop(field);
       
   106     iDb->AddNewContactL(*card);
       
   107     CleanupStack::PopAndDestroy(card);
       
   108 
       
   109     card = CContactCard::NewLC();
       
   110     field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
       
   111     field->TextStorage()->SetTextL(_L("Sarah"));
       
   112     card->AddFieldL(*field);
       
   113     CleanupStack::Pop(field);
       
   114     iDb->AddNewContactL(*card);
       
   115     CleanupStack::PopAndDestroy(card);
       
   116     }
       
   117 
       
   118 
       
   119 void CTestResources::CreateMoreTestContactsL()
       
   120 	{
       
   121 	CRandomContactGenerator* generator = CRandomContactGenerator::NewL();
       
   122 	CleanupStack::PushL(generator);
       
   123 	generator->SetDbL(*iDb);
       
   124 	for (TInt i=0;i<KMaxNumContacts;i++)
       
   125 		{
       
   126 		generator->AddTypicalRandomContactL();
       
   127 		if (i%100==0)
       
   128 			{
       
   129 			iDb->CompactL();
       
   130 			test.Printf(_L("Added %d contacts\n"),i);
       
   131 			}
       
   132 		}
       
   133 	CleanupStack::PopAndDestroy(generator);
       
   134 
       
   135 	}
       
   136 
       
   137 CTestResources::~CTestResources()
       
   138     {
       
   139     if (iFindView) iFindView->Close(*iFindViewEventQueue);
       
   140     delete iFindViewEventQueue;
       
   141     delete iFindText;
       
   142     if (iLocalView) iLocalView->Close(*iViewEventQueue);
       
   143     iViewSortOrder.Close();
       
   144     delete iViewEventQueue;
       
   145     delete iDb;
       
   146     TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
       
   147     }
       
   148 
       
   149 /**
       
   150  * Simulates using CContactFindView to filter contacts as the user types 
       
   151  * characters to an UI "find box".
       
   152  */
       
   153 
       
   154 LOCAL_C void TestRefineFindViewL()
       
   155     {
       
   156 	__UHEAP_MARK;
       
   157 
       
   158 	test.Next(_L("Repeatedly call CContactFindView::RefineFindViewL()"));
       
   159 
       
   160     CTestResources* res = CTestResources::NewLC();
       
   161 
       
   162     // Simulate the user typing 's', 'a', 'm', 'i' into a find box
       
   163     _LIT(KFindText, "sami");
       
   164     for (TInt c=1; c <= KFindText().Length(); ++c)
       
   165         {
       
   166         // Allocate a dummy buffer to keep the heap from recycling a previous
       
   167         // CFindText's address to newFindText below.
       
   168         HBufC* dummy = HBufC::NewLC(c*c);
       
   169 
       
   170         // Create a find word array
       
   171         CFindText* newFindText = CFindText::NewLC(KFindText().Left(c));
       
   172 
       
   173         if (!res->iFindView)
       
   174             {
       
   175             // create find view when first find character is entered
       
   176             res->iFindViewEventQueue = CContactViewEventQueue::NewL();
       
   177 			RDebug::Print(_L("=== %S\n"),&newFindText->Text());
       
   178             res->iFindView = CContactFindView::NewL
       
   179                 (*res->iDb, *res->iLocalView, *res->iFindViewEventQueue, newFindText);
       
   180             // Wait for the find view to get ready
       
   181             TContactViewEvent event;
       
   182             __ASSERT_ALWAYS(res->iFindViewEventQueue->ListenForEvent(10,event),User::Invariant());
       
   183             __ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady,User::Invariant());
       
   184             }
       
   185         else
       
   186             {
       
   187             // Find view exists -> just refine search
       
   188             // (Note: I also noticed a memory leak if you comment out the line
       
   189             //  below and execute the test. The leaked object is a CViewContact
       
   190             //  and it seems to be allocated in CContactLocalView::InsertL().)
       
   191 			RDebug::Print(_L("=== %S\n"),&newFindText->Text());
       
   192             res->iFindView->RefineFindViewL(newFindText);
       
   193             }
       
   194 
       
   195         // keep the find words array because RefineFindViewL accesses the previous
       
   196         // array on the next cycle
       
   197         CleanupStack::Pop(newFindText);
       
   198         delete res->iFindText;
       
   199         res->iFindText = newFindText;
       
   200 
       
   201         CleanupStack::PopAndDestroy(dummy);
       
   202         }
       
   203 
       
   204     CleanupStack::PopAndDestroy(res);
       
   205 
       
   206 	__UHEAP_MARKEND;
       
   207     }
       
   208 
       
   209 LOCAL_C void CleanupContactArray(TAny* aArray)	
       
   210 	{
       
   211 	RPointerArray<CViewContact>* array=REINTERPRET_CAST(RPointerArray<CViewContact>*,aArray);
       
   212 	if (array)
       
   213 		array->ResetAndDestroy();
       
   214 	array->Close();
       
   215 	}
       
   216 
       
   217 /** Profile the speed of CContactLocalView::ContactsMatchingCriteriaL */
       
   218 LOCAL_C void ProfileContactMatchingCriteriaL()
       
   219 	{
       
   220 	CTestResources* res = CTestResources::NewLC();
       
   221 	res->CreateMoreTestContactsL();
       
   222 	
       
   223 	while (res->iLocalView->CountL()<KMaxNumContacts)
       
   224 		{
       
   225 		TContactViewEvent event;
       
   226 		__ASSERT_ALWAYS(res->iViewEventQueue->ListenForEvent(10,event), User::Invariant());
       
   227 		
       
   228 		if (event.iEventType == TContactViewEvent::EUnavailable)
       
   229 			{
       
   230 			// It is likely that when adding 1000 contacts to the database, the view
       
   231 			// event queue will have overflowed at the server side, and instead
       
   232 			// the client view will be totally recreated.
       
   233 			break;
       
   234 			}
       
   235 		
       
   236 		__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EItemAdded, User::Invariant());
       
   237 		}
       
   238 
       
   239 	CFindText* findText = CFindText::NewLC(_L("S"));
       
   240 	RPointerArray<CViewContact> contactArray;
       
   241 	CleanupStack::PushL(TCleanupItem(CleanupContactArray,&contactArray));
       
   242 	CCntTest::ProfileReset(0,2);
       
   243 	CCntTest::ProfileStart(0);
       
   244 	res->iLocalView->ContactsMatchingPrefixL(*findText,contactArray);
       
   245 	CCntTest::ProfileEnd(0);
       
   246 	CleanupStack::PopAndDestroy(&contactArray);
       
   247 
       
   248 	res->iViewEventQueue->Flush();
       
   249 	const TContactViewPreferences prefs = static_cast<TContactViewPreferences>(EContactsOnly);
       
   250 	CContactRemoteView* rv = CContactRemoteView::NewL(*res->iViewEventQueue, *res->iDb, res->iViewSortOrder, prefs);
       
   251 	CleanupStack::PushL(rv);
       
   252 	TContactViewEvent event(TContactViewEvent::EUnavailable);
       
   253 	while (event.iEventType != TContactViewEvent::EReady)
       
   254 		{
       
   255 		__ASSERT_ALWAYS(res->iViewEventQueue->ListenForEvent(10,event), User::Invariant());
       
   256 		}
       
   257 	__ASSERT_ALWAYS(rv->CountL()>=KMaxNumContacts, User::Invariant());
       
   258 
       
   259 	RPointerArray<CViewContact> contactArray2;
       
   260 	CleanupStack::PushL(TCleanupItem(CleanupContactArray,&contactArray2));
       
   261 	CCntTest::ProfileStart(1);
       
   262 	rv->ContactsMatchingPrefixL(*findText,contactArray2);
       
   263 	CCntTest::ProfileEnd(1);
       
   264 	CleanupStack::PopAndDestroy(&contactArray2);
       
   265 
       
   266 	TCntProfile profile[2];
       
   267 	CCntTest::ProfileResult(profile,0,2);
       
   268 	_LIT(KProfileLocal,"LocalView PrefixSearch %d.%03d sec (%d hits)\n");
       
   269 	_LIT(KProfileRemote,"RemoteView PrefixSearch %d.%03d sec (%d hits)\n");
       
   270 	test.Printf(KProfileLocal,profile[0].iTime/1000000, profile[0].iTime%1000000, profile[0].iCount);
       
   271 	RDebug::Print(KProfileLocal,profile[0].iTime/1000000, profile[0].iTime%1000000, profile[0].iCount);
       
   272 	test.Printf(KProfileRemote,profile[1].iTime/1000000, profile[1].iTime%1000000, profile[1].iCount);
       
   273 	RDebug::Print(KProfileLocal,profile[1].iTime/1000000, profile[1].iTime%1000000, profile[1].iCount);
       
   274 
       
   275 	CleanupStack::PopAndDestroy(rv);
       
   276 	CleanupStack::PopAndDestroy(findText);
       
   277 	CleanupStack::PopAndDestroy(res);
       
   278 	}
       
   279 
       
   280 /**
       
   281 
       
   282 @SYMTestCaseID     PIM-T-REFINEFINDVIEWL-0001
       
   283 
       
   284 */
       
   285 
       
   286 void DoTestsL()
       
   287     {
       
   288 	test.Start(_L("@SYMTESTCaseID:PIM-T-REFINEFINDVIEWL-0001 T_RefineFindViewL"));
       
   289 
       
   290     TestRefineFindViewL();
       
   291 	ProfileContactMatchingCriteriaL();
       
   292     test.End();
       
   293     }
       
   294 
       
   295 GLDEF_C TInt E32Main()
       
   296 	{
       
   297     // Init
       
   298 	__UHEAP_MARK;
       
   299     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   300     if (!cleanupStack)
       
   301         {
       
   302         return KErrNoMemory;
       
   303         }
       
   304 
       
   305     CActiveScheduler* activeScheduler = new CActiveScheduler;
       
   306     if (!activeScheduler)
       
   307         {
       
   308         return KErrNoMemory;
       
   309         }
       
   310     CActiveScheduler::Install(activeScheduler);
       
   311 
       
   312 	//Get rid of the warnings.
       
   313 	//T_utils2 uses efsrv.dll, but we don't use this functions in this test code.
       
   314 	//So we pretend to use efsrv to keep T_utils2.obj and linker happy
       
   315 	RFs fs;
       
   316 	fs.Connect();
       
   317 	fs.Close();
       
   318 
       
   319     // Run the tests
       
   320     TRAPD(err, DoTestsL());
       
   321 
       
   322     // Cleanup
       
   323     delete activeScheduler;
       
   324     delete cleanupStack;
       
   325 	test.Close();
       
   326 	__UHEAP_MARKEND;
       
   327 	return err;
       
   328     }