pimprotocols/phonebooksync/Test/TE_cntsync/te_cntsyncview.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 // Copyright (c) 2003-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 // Tests that PhBkSync adds contacts from USIM address books to the contacts database,
       
    15 // and that they appear correctly in the Contacts Model local view.
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <e32test.h>
       
    20 #include "te_cntsyncbase.h"
       
    21 #include "te_cntsyncview.h"
       
    22 #include <cntview.h>
       
    23 
       
    24 // Values for User::After()
       
    25 const TInt	K1SecondWait(1000000);
       
    26 const TInt	K5SecondWait(5*K1SecondWait);
       
    27 const TInt	K20SecondWait(20*K1SecondWait);
       
    28 
       
    29 // Test config numbers...
       
    30 const TInt  KNormalSIMTestConfig(0);
       
    31 const TInt  KLockedSIMTestConfig(8);
       
    32 
       
    33 // Number of contacts on SIM cards
       
    34 const TInt	KNumContactsNormalSIM(5);
       
    35 const TInt	KNumContactsLockedSIM(25);
       
    36 
       
    37 class TViewCleanup
       
    38 	{
       
    39 	public:
       
    40 		TViewCleanup(CContactLocalView* aLocalView, CContactViewEventWait* aViewWaitEvent)
       
    41 			{
       
    42 			iLocalView = aLocalView;
       
    43 			iViewWaitEvent = aViewWaitEvent;
       
    44 			}
       
    45 		CContactViewEventWait* iViewWaitEvent;
       
    46 		CContactLocalView* iLocalView;
       
    47 	};
       
    48 
       
    49 static void ViewCleanup(TAny* aPointer)
       
    50 	{
       
    51 	TViewCleanup* cleanup = static_cast<TViewCleanup*> (aPointer);
       
    52 	CContactLocalView* iLocalView = cleanup->iLocalView;
       
    53 	CContactViewEventWait* iViewWaitEvent = cleanup->iViewWaitEvent;
       
    54 	iLocalView->Close(*iViewWaitEvent);
       
    55 	delete iViewWaitEvent;
       
    56 	}
       
    57 
       
    58 /** 
       
    59  * Factory construction method.
       
    60  * @return Pointer to CPhbkViewICCSyncTest object
       
    61  */
       
    62 CPhbkViewICCSyncTest* CPhbkViewICCSyncTest::NewL()
       
    63 	{
       
    64 	CPhbkViewICCSyncTest* self = new(ELeave) CPhbkViewICCSyncTest();
       
    65 	return self;
       
    66 	}
       
    67 
       
    68 /**
       
    69  *  Default constructor.  Each test step initialises it's own name.
       
    70  */
       
    71 CPhbkViewICCSyncTest::CPhbkViewICCSyncTest()
       
    72 	{
       
    73 	SetTestStepName(_L("ViewICCSyncTest"));
       
    74 	}
       
    75 
       
    76 /**
       
    77  * Synchronisation of normal, unlocked, ICC.  Creates a Contacts View
       
    78  * with ICC entries only.
       
    79  */
       
    80 enum TVerdict CPhbkViewICCSyncTest::doTestStepL()
       
    81 	{
       
    82 	SetSimTsyTestNumberL(0);
       
    83 	DoSyncL();
       
    84 	
       
    85 	// all View tests use Manual Sync mode
       
    86 	User::LeaveIfError(iSession.SetSyncMode(RPhoneBookSession::EManual)); // Set mode to manual to avoid getting KErrInUse
       
    87 	CheckSyncModeL(RPhoneBookSession::EManual);
       
    88 	
       
    89 	// ICC unlocked
       
    90 	SetSimTsyTestNumberL(KNormalSIMTestConfig);
       
    91 	CleanupClosePushL(iViewSortOrder);
       
    92 
       
    93 	// A sort order (only Family Name is present in ADN phonebooks)
       
    94     iViewSortOrder.AppendL(KUidContactFieldFamilyName);
       
    95     iViewSortOrder.AppendL(KUidContactFieldGivenName);
       
    96     iViewSortOrder.AppendL(KUidContactFieldCompanyName);
       
    97 
       
    98 	// Helper class that gives timed wait for View events
       
    99 	CContactViewEventWait *viewEventWait = CContactViewEventWait::NewL();
       
   100 	CleanupStack::PushL(viewEventWait);
       
   101 
       
   102 	// View with just ICC entries
       
   103 	iIccView = CContactLocalView::NewL(*viewEventWait, *iDb, iViewSortOrder, EICCEntriesOnly);
       
   104 
       
   105 	CleanupStack::Pop();//viewEventWait will be deleted with cleanup below
       
   106 	TViewCleanup cleanup(iIccView, viewEventWait);
       
   107 	CleanupStack::PushL(TCleanupItem(ViewCleanup, &cleanup));
       
   108 
       
   109 	INFO_PRINTF1(_L("  Manual Sync"));
       
   110 	// do manual synchronisation
       
   111 	DoSyncL();
       
   112 	WaitForSyncToCompleteL();
       
   113 
       
   114 	// let view catch up, waits 2s
       
   115 	INFO_PRINTF1(_L("  Wait for ICC view to become ready"));
       
   116 	// Wait 30s for View Event: EReady or ESortOrderChanged only
       
   117 	TBool eventReceived = viewEventWait->WaitForViewEvent(iIccView, 30, iEvent, EFalse);
       
   118 	// check that event was received
       
   119 	TESTCHECKCONDITIONL(eventReceived);
       
   120 	TESTCHECKL(iEvent.iEventType, TContactViewEvent::EReady);
       
   121 
       
   122 	INFO_PRINTF1(_L("  Check all PhoneBook entries are in view"));
       
   123 	TInt count = iIccView->CountL();
       
   124 	if (count != KNumContactsNormalSIM)
       
   125 		{
       
   126 		INFO_PRINTF3(_L("  Expecting %d entries in View but found %d:"),
       
   127 			KNumContactsNormalSIM, count);
       
   128 		DumpICCViewL();
       
   129 		}
       
   130 	TESTCHECK(count, KNumContactsNormalSIM);
       
   131 
       
   132 	User::After(K5SecondWait);
       
   133 	CleanupStack::PopAndDestroy(2);//iIccView, viewEventWait and iViewSortOrder
       
   134 
       
   135 	return TestStepResult();
       
   136 	}
       
   137 	
       
   138 	
       
   139 /** 
       
   140  * Factory construction method.
       
   141  * @return Pointer to CPhbkViewICCLockedICCTest object
       
   142  */
       
   143 CPhbkViewICCLockedICCTest* CPhbkViewICCLockedICCTest::NewL()
       
   144 	{
       
   145 	CPhbkViewICCLockedICCTest* self = new(ELeave) CPhbkViewICCLockedICCTest();
       
   146 	return self;
       
   147 	}
       
   148 
       
   149 /**
       
   150  *  Default constructor.  Each test step initialises it's own name.
       
   151  */
       
   152 CPhbkViewICCLockedICCTest::CPhbkViewICCLockedICCTest()
       
   153 	{
       
   154 	SetTestStepName(_L("ViewICCLockedICCTest"));
       
   155 	}
       
   156 
       
   157 /**
       
   158  * Synchronisation when ICC is locked.  Creates a Contacts View of ICC entries
       
   159  * only.
       
   160  *
       
   161  * Synchroniser is initially unable to perform synchronisation because ICC is locked. The
       
   162  * Local View class recognises that the ICC is locked, and creates an empty View.
       
   163  *
       
   164  * When ICC becomes unlocked the synchronisation completes successfully. The Contacts Local 
       
   165  * View sees this, and re-sorts itself making the ICC entries appear in the View.
       
   166  */
       
   167 enum TVerdict CPhbkViewICCLockedICCTest::doTestStepL()
       
   168 	{
       
   169 	// ICC locked, so initial Synchronisation is not carried out 
       
   170 	SetSimTsyTestNumberL(KLockedSIMTestConfig);
       
   171 	CleanupClosePushL(iViewSortOrder);
       
   172 	// A sort order (only Family Name is present in ADN phonebooks)
       
   173     iViewSortOrder.AppendL(KUidContactFieldFamilyName);
       
   174     iViewSortOrder.AppendL(KUidContactFieldGivenName);
       
   175     iViewSortOrder.AppendL(KUidContactFieldCompanyName);
       
   176 
       
   177 	// Helper class that gives timed wait for View events
       
   178 	CContactViewEventWait *viewEventWait = CContactViewEventWait::NewL();
       
   179 	CleanupStack::PushL(viewEventWait);
       
   180 
       
   181 	// View with just ICC entries
       
   182 	iIccView = CContactLocalView::NewL(*viewEventWait, *iDb, iViewSortOrder, EICCEntriesOnly);
       
   183 	CleanupStack::Pop();//viewEventWait will be deleted with cleanup below
       
   184 	TViewCleanup cleanup(iIccView, viewEventWait);
       
   185 	CleanupStack::PushL(TCleanupItem(ViewCleanup, &cleanup));
       
   186 
       
   187 	INFO_PRINTF1(_L("  Initial Sync Failure"));
       
   188 	// check that ICC is locked
       
   189 	TRAPD(err, DoSyncFailL());
       
   190 	if(err == KErrGeneral)
       
   191 		{
       
   192 		INFO_PRINTF1(_L("The view has already been created before we attempt to sync, so sync won't fail. We should finsh test here"));
       
   193 		SetTestStepResult(EPass);
       
   194 		CleanupStack::PopAndDestroy(2);//iIccView, viewEventWait and iViewSortOrder
       
   195 		return TestStepResult(); 
       
   196 		}
       
   197 	TESTCHECKL(err, KErrNone);
       
   198 	User::After(K1SecondWait);
       
   199 
       
   200 	RPhoneBookSession::TSyncState state;
       
   201 	iSession.GetPhoneBookCacheState(state);
       
   202 
       
   203 	TESTCHECKL(state, RPhoneBookSession::EErrorDuringSync); // Cache not in valid state 
       
   204 
       
   205 	iSession.GetLastSyncError(err);
       
   206 	TESTCHECKL(err, KErrAccessDenied); // ICC locked
       
   207 
       
   208 	// initially ready with no entries as ICC (SIM) card is not ready, waits 2s
       
   209 	INFO_PRINTF1(_L("  Check View becomes ready with no entries"));
       
   210 	// Wait 30seconds at max for View Event: EReady or ESortOrderChanged only
       
   211 	TBool eventReceived = viewEventWait->WaitForViewEvent(iIccView, 30, iEvent, EFalse);
       
   212 	// check that event was received
       
   213 	TESTCHECKCONDITIONL(eventReceived);
       
   214 
       
   215 	TESTCHECKL(iEvent.iEventType, TContactViewEvent::EReady);
       
   216 	TESTCHECKL(iIccView->CountL(), 0); // view should be empty
       
   217 
       
   218 	// wait for ICC to become unlocked
       
   219 	INFO_PRINTF1(_L("  Start Sync when ICC becomes unlocked"));
       
   220 	User::After(K20SecondWait); // ICC should become unlocked now 
       
   221 	DoSyncL();
       
   222 	WaitForSyncToCompleteL();
       
   223 
       
   224 	// let the view catch up, waits 2s
       
   225 	INFO_PRINTF1(_L("  Wait for View to Re-Sort with ICC entries"));
       
   226 	// Wait 30seconds at max for View Event: EReady or ESortOrderChanged only
       
   227 	eventReceived = viewEventWait->WaitForViewEvent(iIccView, 30, iEvent, EFalse);
       
   228 	// check that event was received
       
   229 	TESTCHECKCONDITIONL(eventReceived);
       
   230 
       
   231 	INFO_PRINTF1(_L("  Contacts View should be resorted"));
       
   232 	TESTCHECKL(iEvent.iEventType, TContactViewEvent::ESortOrderChanged);
       
   233 
       
   234 	INFO_PRINTF1(_L("  Check all PhoneBook entries are in view"));
       
   235 	TInt count = iIccView->CountL();
       
   236 	if (count != KNumContactsLockedSIM)
       
   237 		{
       
   238 		INFO_PRINTF3(_L("  Expecting %d entries in View but found %d:"),
       
   239 			KNumContactsLockedSIM, count);
       
   240 		DumpICCViewL();
       
   241 		}
       
   242 	TESTCHECK(count, KNumContactsLockedSIM);
       
   243 
       
   244 	User::After(K5SecondWait);
       
   245 	CleanupStack::PopAndDestroy(2);//iIccView, viewEventWait and iViewSortOrder
       
   246 
       
   247 	return TestStepResult();
       
   248 	}
       
   249 	
       
   250 	
       
   251 /** 
       
   252  * Factory construction method.
       
   253  * @return Pointer to CPhbkViewICCLockedMixedTest object
       
   254  */
       
   255 CPhbkViewICCLockedMixedTest* CPhbkViewICCLockedMixedTest::NewL()
       
   256 	{
       
   257 	CPhbkViewICCLockedMixedTest* self = new(ELeave) CPhbkViewICCLockedMixedTest();
       
   258 	return self;
       
   259 	}
       
   260 
       
   261 /**
       
   262  *  Default constructor.  Each test step initialises it's own name.
       
   263  */
       
   264 CPhbkViewICCLockedMixedTest::CPhbkViewICCLockedMixedTest()
       
   265 	{
       
   266 	SetTestStepName(_L("ViewICCLockedMixedTest"));
       
   267 	}
       
   268 
       
   269 /**
       
   270  * Synchronisation when ICC is locked.  Creates a Contacts View of Contacts
       
   271  * and ICC entries.  This is similar to the ICC entries only test, but timing
       
   272  * and behaviour of Contacts model is different.
       
   273  *
       
   274  * Synchroniser is initially unable to perform synchronisation because ICC is locked. The
       
   275  * Local View class recognises that the ICC is locked, and creates a View without ICC entries.
       
   276  *
       
   277  * When ICC becomes unlocked the synchronisation completes successfully. The Contacts Local 
       
   278  * View sees this, and re-sorts itself making the ICC entries appear in the View.
       
   279  */
       
   280 enum TVerdict CPhbkViewICCLockedMixedTest::doTestStepL()
       
   281 	{
       
   282 	// ICC locked, so initial Synchronisation is not carried out
       
   283 	SetSimTsyTestNumberL(KLockedSIMTestConfig);
       
   284 	CleanupClosePushL(iViewSortOrder);
       
   285 
       
   286 	// A sort order (only Family Name is present in ADN phonebooks)
       
   287     iViewSortOrder.AppendL(KUidContactFieldFamilyName);
       
   288     iViewSortOrder.AppendL(KUidContactFieldGivenName);
       
   289     iViewSortOrder.AppendL(KUidContactFieldCompanyName);
       
   290 
       
   291 	// Helper class that gives timed wait for View events
       
   292 	CContactViewEventWait *viewEventWait = CContactViewEventWait::NewL();
       
   293 	CleanupStack::PushL(viewEventWait);
       
   294 
       
   295 	// View with ICC entries and contacts
       
   296 	iIccView = CContactLocalView::NewL(*viewEventWait, *iDb, iViewSortOrder, EICCEntriesAndContacts);
       
   297 	
       
   298 	CleanupStack::Pop();//viewEventWait will be deleted with cleanup below
       
   299 	TViewCleanup cleanup(iIccView, viewEventWait);
       
   300 	CleanupStack::PushL(TCleanupItem(ViewCleanup, &cleanup));
       
   301 
       
   302 	INFO_PRINTF1(_L("  Initial Sync Failure"));
       
   303 	// check that ICC is locked
       
   304 	TRAPD(err, DoSyncFailL());
       
   305 	if(err == KErrGeneral)
       
   306 		{
       
   307 		INFO_PRINTF1(_L("The view has already been created before we attempt to sync, so sync won't fail. We should finsh test here"));		
       
   308 		SetTestStepResult(EPass);
       
   309 		CleanupStack::PopAndDestroy(2);//iIccView, viewEventWait and iViewSortOrder
       
   310 		return TestStepResult(); 
       
   311 		}
       
   312 	TESTCHECKL(err, KErrNone);
       
   313 	User::After(K1SecondWait);
       
   314 
       
   315 	RPhoneBookSession::TSyncState state;
       
   316 	iSession.GetPhoneBookCacheState(state);
       
   317 
       
   318 	TESTCHECKL(state, RPhoneBookSession::EErrorDuringSync); // Cache not in valid state 
       
   319 
       
   320 	iSession.GetLastSyncError(err);
       
   321 	TESTCHECKL(err, KErrAccessDenied); // ICC locked
       
   322 
       
   323 	// initially ready with no entries as ICC (SIM) card is not ready, waits 2s
       
   324 	INFO_PRINTF1(_L("  Check View becomes ready without ICC entries"));
       
   325 	// Wait 30seconds at max for View Event: EReady or ESortOrderChanged only
       
   326 	TBool eventReceived = viewEventWait->WaitForViewEvent(iIccView, 30, iEvent, EFalse);
       
   327 	// check that event was received
       
   328 	TESTCHECKCONDITIONL(eventReceived);
       
   329 
       
   330 	TESTCHECKL(iEvent.iEventType, TContactViewEvent::EReady);
       
   331 	TESTCHECKL(iIccView->CountL(), 0); // view should be empty
       
   332 
       
   333 	// wait for ICC to become unlocked
       
   334 	INFO_PRINTF1(_L("  Start Sync when ICC becomes unlocked"));
       
   335 	User::After(K20SecondWait); // ICC should become unlocked now 
       
   336 	DoSyncL();
       
   337 	WaitForSyncToCompleteL();
       
   338 
       
   339 	// let the view catch up, waits 2s
       
   340 	INFO_PRINTF1(_L("  Wait for View to Re-Sort with ICC entries"));
       
   341 	// Wait 30seconds at max for View Event: EReady or ESortOrderChanged only
       
   342 	eventReceived = viewEventWait->WaitForViewEvent(iIccView, 30, iEvent, EFalse);
       
   343 	// check that event was received
       
   344 	TESTCHECKCONDITIONL(eventReceived);
       
   345 
       
   346 	INFO_PRINTF1(_L("  Contacts View should be resorted"));
       
   347 	TESTCHECKL(iEvent.iEventType, TContactViewEvent::ESortOrderChanged);
       
   348 
       
   349 	INFO_PRINTF1(_L("  Check all PhoneBook entries are in view"));
       
   350 	TInt count = iIccView->CountL();
       
   351 	if (count != KNumContactsLockedSIM)
       
   352 		{
       
   353 		INFO_PRINTF3(_L("  Expecting %d entries in View but found %d:"),
       
   354 			KNumContactsLockedSIM, count);
       
   355 		DumpICCViewL();
       
   356 		}
       
   357 	TESTCHECK(count, KNumContactsLockedSIM);
       
   358 
       
   359 	User::After(K5SecondWait);
       
   360 	CleanupStack::PopAndDestroy(2);//iIccView, viewEventWait and iViewSortOrder
       
   361 	return TestStepResult();
       
   362 	}
       
   363 
       
   364 
       
   365 /**
       
   366  *  Synchronisation and create a view when just one phonebook exists. Previously
       
   367  *  a defect existed which would fail if no FDN phonebook was defined.
       
   368  */
       
   369 enum TVerdict CPhbkViewICCSinglePhonebookTest::doTestStepL()
       
   370 	{
       
   371 	SetSimTsyTestNumberL(30);
       
   372 
       
   373 	//
       
   374 	// Setup a sort order (only Family Name is present in ADN phonebooks)
       
   375     //
       
   376 	INFO_PRINTF1(_L("Setup a sort order (only Family Name is present in ADN phonebooks)"));
       
   377 	CleanupClosePushL(iViewSortOrder);
       
   378     iViewSortOrder.AppendL(KUidContactFieldFamilyName);
       
   379     iViewSortOrder.AppendL(KUidContactFieldGivenName);
       
   380     iViewSortOrder.AppendL(KUidContactFieldCompanyName);
       
   381 	
       
   382 	//
       
   383     // Helper class that gives timed wait for View events
       
   384 	//
       
   385 	CContactViewEventWait *viewEventWait = CContactViewEventWait::NewL();
       
   386 	CleanupStack::PushL(viewEventWait);
       
   387 
       
   388 	//
       
   389 	// Create a view with ICC entries and contacts
       
   390 	//
       
   391 	INFO_PRINTF1(_L("Create a view with ICC entries and contacts"));
       
   392 	iIccView = CContactLocalView::NewL(*viewEventWait, *iDb, iViewSortOrder, EICCEntriesAndContacts);
       
   393 	
       
   394 	CleanupStack::Pop();//viewEventWait will be deleted with cleanup below
       
   395 	TViewCleanup cleanup(iIccView, viewEventWait);
       
   396 	CleanupStack::PushL(TCleanupItem(ViewCleanup, &cleanup));	
       
   397 
       
   398 	//
       
   399 	// Sync ADN phonebook...
       
   400 	//
       
   401 	INFO_PRINTF1(_L(" Sync ADN phonebook..."));
       
   402 	TRequestStatus  status; 
       
   403 
       
   404 	iSession.DoSynchronisation(status, KUidIccGlobalAdnPhonebook);
       
   405 	User::WaitForRequest(status);
       
   406 	TESTCHECKL(status.Int(), KErrNone);
       
   407 
       
   408 	//
       
   409 	// Close view and clean up...
       
   410 	//
       
   411 	INFO_PRINTF1(_L(" Close view and clean up..."));
       
   412 	CleanupStack::PopAndDestroy(2);
       
   413 
       
   414 	return TestStepResult();
       
   415 	} // CPhbkViewICCSinglePhonebookTest::doTestStepL
       
   416 
       
   417 
       
   418 void CPhbkSyncViewIntegrationTestBase::DumpICCViewL()
       
   419 	{
       
   420 	const TInt count = iIccView->CountL();
       
   421 
       
   422 	if (count == 0)
       
   423 		{
       
   424 		INFO_PRINTF1(_L("  No contacts to list."));
       
   425 		return;
       
   426 		}
       
   427 
       
   428 	CContactItem* contact = NULL;
       
   429 	TInt  index;
       
   430 
       
   431 	for (index = 0;  index < count;  index++)
       
   432 		{
       
   433 		const CViewContact&  viewContact = iIccView->ContactAtL(index);
       
   434 		const TInt  id = viewContact.Id();
       
   435 		
       
   436 		// get actual Contact from DB
       
   437 		contact = iDb->ReadMinimalContactLC(id);
       
   438 
       
   439 		// Get & print Contact's phone number
       
   440 		CContactItemFieldSet& fieldset = contact->CardFields();
       
   441 		// look for Phone Number field in record
       
   442 		const TInt pos = fieldset.Find(KUidContactFieldPhoneNumber);	
       
   443 		User::LeaveIfError(pos);	// field must be present
       
   444 		CContactItemField& field = fieldset[pos];
       
   445 		CContactTextField* textfield = field.TextStorage();
       
   446 
       
   447 		TBuf<128>  outputString;
       
   448 		outputString.AppendFormat(_L("    [%04i]  Id=%04i Name=\""), index+1, id);
       
   449 		outputString.Append(viewContact.Field(0));
       
   450 		outputString.AppendFormat(_L("\" Number=\""));
       
   451 		outputString.Append(textfield->Text());
       
   452 		outputString.AppendFormat(_L("\""));
       
   453 		INFO_PRINTF1(outputString);
       
   454 
       
   455 		CleanupStack::PopAndDestroy(contact);
       
   456 		contact = NULL;
       
   457 		}
       
   458 	}
       
   459 
       
   460 // support class implementation, timed wait for View Event; (based on CContactViewEventQueue)
       
   461 
       
   462 CContactViewEventWait* CContactViewEventWait::NewL()
       
   463     {
       
   464     CContactViewEventWait* self = new(ELeave) CContactViewEventWait;
       
   465     CleanupStack::PushL(self);
       
   466     self->ConstructL();
       
   467     CleanupStack::Pop(self);
       
   468     return self;
       
   469     }
       
   470 
       
   471 
       
   472 CContactViewEventWait::~CContactViewEventWait()
       
   473     {
       
   474     CTimer::Cancel();
       
   475     if (iView) iView->Close(*this);
       
   476     }
       
   477 
       
   478 
       
   479 /**
       
   480  *  Waits for an event from the database.
       
   481  *
       
   482  *  @param aView        Contact view to listen for events.
       
   483  *  @param aTimeOut     Max time to wait for an event.
       
   484  *  @param aEvent       The received event, undefined if this function returns false.
       
   485  *  @param aWaitForAny  ETrue if wait is for any event, EFalse for view ready events only
       
   486  *
       
   487  *  @return true if an event was received, false if timeout expired first.
       
   488  */
       
   489 TBool CContactViewEventWait::WaitForViewEvent(CContactViewBase* aView,
       
   490 											  TTimeIntervalSeconds aTimeOut, 
       
   491 											  TContactViewEvent& aEvent, 
       
   492 											  TBool aWaitForAny)
       
   493     {
       
   494 	iView = aView;
       
   495 	iWaitForAny = aWaitForAny;
       
   496 	iTimedOut = EFalse;
       
   497     CTimer::After(aTimeOut.Int() * 1000000);
       
   498 
       
   499 	// wait for timer to finish or desired View event
       
   500     CActiveScheduler::Start();
       
   501 
       
   502     if (!iTimedOut)
       
   503         {
       
   504         aEvent = iEvent;
       
   505         return ETrue;
       
   506         }
       
   507     else
       
   508         {
       
   509         return EFalse;
       
   510         }
       
   511     }
       
   512 
       
   513 
       
   514 void CContactViewEventWait::RunL()
       
   515     {
       
   516     // Timer expired
       
   517 	iTimedOut = ETrue;
       
   518     CActiveScheduler::Stop();
       
   519     }
       
   520 
       
   521 
       
   522 void CContactViewEventWait::HandleContactViewEvent(const CContactViewBase& aView,
       
   523 												   const TContactViewEvent& aEvent)
       
   524     {
       
   525 	__ASSERT_ALWAYS(iView == &aView, User::Invariant());
       
   526 
       
   527 	// either waiting for Any event, or Ready or Ready after Re-sort
       
   528 	if(iWaitForAny || aEvent.iEventType == TContactViewEvent::EReady || 
       
   529 			aEvent.iEventType == TContactViewEvent::ESortOrderChanged)
       
   530 		{
       
   531 		iEvent = aEvent;
       
   532 
       
   533 	    CTimer::Cancel();
       
   534 	    CActiveScheduler::Stop();
       
   535 		}
       
   536     }
       
   537 
       
   538 
       
   539 CContactViewEventWait::CContactViewEventWait()
       
   540     : CTimer(CActive::EPriorityStandard)
       
   541     {
       
   542     }
       
   543 
       
   544 
       
   545 void CContactViewEventWait::ConstructL()
       
   546     {
       
   547     CTimer::ConstructL();
       
   548     CActiveScheduler::Add(this);
       
   549 	iView = NULL;
       
   550     }
       
   551