sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // e32test\power\t_domain.cpp
sl@0: // Overview:
sl@0: // Domain manager tests
sl@0: // API Information:
sl@0: // RDmDomain, RDmDomainManager CDmDomain, CDmDomainManager
sl@0: // Details:
sl@0: // - Test a variety of domain transitions, check the expected number of
sl@0: // notifications and the first expected ordinal. Verify results are
sl@0: // as expected.
sl@0: // - Test system standby, check the expected number of notifications and 
sl@0: // the first expected ordinal. Use a timer to request a wakeup event.
sl@0: // Verify results are as expected.
sl@0: // - Test domain related simple error situations, verify results are
sl@0: // as expected.
sl@0: // - Perform platform security tests: launch a separate process with no 
sl@0: // capabilities, verify that results are as expected.
sl@0: // - Test domain transitions by connecting to two domain hierarchies 
sl@0: // simultaneously, add some test and power hierarchy members, verify
sl@0: // the expected target state, notifications and leaf nodes. Verify results.
sl@0: // - Verify that the same hierarchy can not be connected to more than once.
sl@0: // - Request a positive transition and request that the test domain use 
sl@0: // ETraverseParentsFirst. Verify results are as expected and verify 
sl@0: // domains are in the correct state.
sl@0: // - Request a negative transition and request that the test domain use 
sl@0: // ETraverseChildrenFirst. Verify results are as expected.
sl@0: // - Request a positive transition with zero acknowledgements. Verify 
sl@0: // results are as expected.
sl@0: // - Request a positive transition with error acknowledgements. Verify 
sl@0: // results are as expected.
sl@0: // - Perform a variety of negative tests and verify results are as expected.
sl@0: // - Perform various tests on domain transitions with activated observer.
sl@0: // Verify results are as expected.
sl@0: // Platforms/Drives/Compatibility:
sl@0: // All.
sl@0: // Assumptions/Requirement/Pre-requisites:
sl@0: // Failures and causes:
sl@0: // Base Port information:
sl@0: // 
sl@0: //
sl@0: 
sl@0: #include <e32test.h>
sl@0: #include <domainmember.h>
sl@0: #include <domainmanager.h>
sl@0: #include <domainobserver.h>
sl@0: #include "domainpolicytest.h"
sl@0: #include <e32debug.h>
sl@0: #include <f32file.h>
sl@0: #include <e32ldr.h>
sl@0: #include <e32ldr_private.h>
sl@0: 
sl@0: LOCAL_D RTest test(_L(" T_DOMAIN "));
sl@0: _LIT(KThreadName, "t_domain_panic_thread");
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: #define __PRINT(x) {RDebug::Print x;}
sl@0: #else
sl@0: #define __PRINT(x) 
sl@0: #endif
sl@0: 
sl@0: class CDmTestMember;
sl@0: 
sl@0: // interface for test domain memebers.
sl@0: // Any test memeber should derive from this interface 
sl@0: class MDmDomainMember
sl@0: 	{
sl@0: public:
sl@0: 	virtual TDmHierarchyId HierarchyId() = 0;
sl@0: 	virtual TDmDomainId	DomainId() = 0;
sl@0: 	virtual TDmDomainState State() = 0;
sl@0: 	virtual TInt Status() = 0;
sl@0: 	virtual TUint32 Ordinal() = 0;
sl@0: 	virtual TInt Notifications() = 0;
sl@0: 	};
sl@0: 
sl@0: class MDmTest
sl@0: 	{
sl@0: public:
sl@0: 	virtual void Perform() = 0;
sl@0: 	virtual void Release() = 0;
sl@0: 	virtual TInt TransitionNotification(MDmDomainMember& aDomainMember) = 0;
sl@0: 	virtual void TransitionRequestComplete() = 0;
sl@0: 	};
sl@0: 
sl@0: // for the test hierarchy, we generate an ordinal for each domain
sl@0: // each byte of which describes the exact location of the domain in the hierarchy
sl@0: #define ORDINAL_FROM_DOMAINID0(id) (id)
sl@0: #define ORDINAL_FROM_DOMAINID1(parent, id) ((parent << 8) | (id))
sl@0: #define ORDINAL_FROM_DOMAINID2(grandparent, parent, id) ((grandparent << 16) | (parent << 8) | id)
sl@0: #define ORDINAL_FROM_DOMAINID3(greatgrandparent, grandparent, parent, id) ((greatgrandparent << 24) | (grandparent << 16) | (parent << 8) | id)
sl@0: #define PARENT_ORDINAL(id) (id >> 8)
sl@0: 
sl@0: #define ORDINAL_LEVEL(ordinal)			\
sl@0: 	((ordinal & 0xFF00) == 0) ? 1 :			\
sl@0: 	((ordinal & 0xFF0000) == 0) ? 2 :		\
sl@0: 	((ordinal & 0xFF000000) == 0) ? 3 : 4;
sl@0: 
sl@0: 
sl@0: // get the least significant domain id character (for debugging purposes)
sl@0: TBool GetDomainChar(TDmDomainId aDomainId, TChar& aChar)
sl@0: 	{
sl@0: 	TBool found = ETrue;
sl@0: 	switch(aDomainId)
sl@0: 		{
sl@0: 		
sl@0: 		case KDmIdTestA:	aChar = 'A'; break;
sl@0: 		case KDmIdTestB:	aChar = 'B'; break;
sl@0: 		case KDmIdTestC:	aChar = 'C'; break;
sl@0: 		case KDmIdTestAA:	aChar = 'A'; break;
sl@0: 		case KDmIdTestAB:	aChar = 'B'; break;
sl@0: 		case KDmIdTestBA:	aChar = 'A'; break;
sl@0: 		case KDmIdTestCA:	aChar = 'A'; break;
sl@0: 		case KDmIdTestABA:	aChar = 'A'; break;
sl@0: 		case KDmIdTestABB:	aChar = 'B'; break;
sl@0: 		case KDmIdTestCAA:	aChar = 'A'; break;
sl@0: 		// domain char not found 
sl@0: 		case KDmIdNone:
sl@0: 		case KDmIdRoot:		
sl@0: 		default:			
sl@0: 			found = EFalse;
sl@0: 		}
sl@0: 	return found;
sl@0: 	}
sl@0: 
sl@0: // prints the 4-character domain string into the passed descriptor (for debugging purposes)
sl@0: // e.g. "CAA" for KDmIdTestCAA
sl@0: void GetDomainDesc(TUint32 aOrdinal, TDes& aDes)
sl@0: 	{
sl@0: 	if (aOrdinal == KDmIdRoot)
sl@0: 		{
sl@0: 		aDes.Append(_L("root"));
sl@0: 		return;
sl@0: 		}
sl@0: 
sl@0: 	TUint32 val =  aOrdinal;
sl@0: 
sl@0: 	for (TInt n=0; n<4; n++)
sl@0: 		{
sl@0: 		TDmDomainId domainId = (TDmDomainId) (val >> 24);
sl@0: 		TChar ch;
sl@0: 		TBool found = GetDomainChar(domainId, ch);
sl@0: 		if (found)
sl@0: 			aDes.Append(ch);
sl@0: 		val = val << 8;
sl@0: 		}
sl@0: 
sl@0: 	}
sl@0: 
sl@0: 
sl@0: class CDmTestMember : public CActive, public MDmDomainMember
sl@0: 	{
sl@0: public:	
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0: 	// from MDmDomainMember
sl@0: 	inline TDmHierarchyId HierarchyId() {return iHierarchy;};
sl@0: 	inline TDmDomainId	DomainId() {return iId;};
sl@0: 	inline TDmDomainState State() {return iState;};
sl@0: 	inline TInt Status() {return iStatus.Int();};
sl@0: 	inline TUint32 Ordinal() {return iOrdinal;};
sl@0: 	inline TInt Notifications() {return iNotifications;};
sl@0: 
sl@0: 	CDmTestMember(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest*);
sl@0: 	~CDmTestMember();
sl@0: 	void Acknowledge();
sl@0: 
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: 
sl@0: public:
sl@0: 	TDmHierarchyId iHierarchy;
sl@0: 	TDmDomainId	iId;
sl@0: 	TDmDomainState iState;
sl@0: 	TUint32		iOrdinal;
sl@0: 	MDmTest*	iTest;	
sl@0: 	TInt		iNotifications;
sl@0: 	RDmDomain	iDomain;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: 
sl@0: CDmTestMember::CDmTestMember(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest* aTest) : CActive(CActive::EPriorityStandard), 
sl@0: 	iHierarchy(aHierarchy), iId(aId), iOrdinal(aOrdinal), iTest(aTest)
sl@0: 	{
sl@0: 	TInt r;
sl@0: 
sl@0: 	if (iHierarchy == KDmHierarchyIdPower)
sl@0: 		 r = iDomain.Connect(iId);
sl@0: 	else
sl@0: 		 r = iDomain.Connect(iHierarchy, iId);
sl@0: 
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	iDomain.RequestTransitionNotification(CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 	}
sl@0: 
sl@0: CDmTestMember::~CDmTestMember()
sl@0: 	{
sl@0: 	CActive::Cancel();
sl@0: 	iDomain.Close();
sl@0: 	}
sl@0: 
sl@0: void CDmTestMember::Acknowledge()
sl@0: 	{
sl@0: 	iDomain.AcknowledgeLastState();
sl@0: 	}
sl@0: 
sl@0: void CDmTestMember::RunL()
sl@0: 	{
sl@0: 
sl@0: 	iNotifications++;
sl@0: 
sl@0: 	iState = iDomain.GetState();
sl@0: 
sl@0: 	TInt ackError = iTest->TransitionNotification(*this);
sl@0: 	if (ackError == KErrNone)
sl@0: 		iDomain.AcknowledgeLastState();
sl@0: 	else if (ackError == KErrAbort)	// don't acknowledge
sl@0: 		;
sl@0: 	else
sl@0: 		iDomain.AcknowledgeLastState(ackError);
sl@0: 
sl@0: 	
sl@0: 	// request another notification (even if we didn't acknowledge the last one)
sl@0: 	iDomain.RequestTransitionNotification(CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 	}
sl@0: 
sl@0: void CDmTestMember::DoCancel()
sl@0: 	{
sl@0: 	iDomain.CancelTransitionNotification();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // CDomainMemberAo
sl@0: class CDomainMemberAo : public CDmDomain, public MDmDomainMember
sl@0: 	{
sl@0: public:	
sl@0: 	static CDomainMemberAo* NewL(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest*);
sl@0: 	~CDomainMemberAo();
sl@0: 
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0: 
sl@0: 	// from MDmDomainMember
sl@0: 	inline TDmHierarchyId HierarchyId() {return iHierarchy;};
sl@0: 	inline TDmDomainId	DomainId() {return iId;};
sl@0: 	inline TDmDomainState State() {return iState;};
sl@0: 	inline TInt Status() {return iStatus.Int();};
sl@0: 	inline TUint32 Ordinal() {return iOrdinal;};
sl@0: 	inline TInt Notifications() {return iNotifications;};
sl@0: 
sl@0: private:
sl@0: 	CDomainMemberAo(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest*);
sl@0: 
sl@0: public:
sl@0: 	TDmHierarchyId iHierarchy;
sl@0: 	TDmDomainId	iId;
sl@0: 	TDmDomainState iState;
sl@0: 	TUint32		iOrdinal;
sl@0: 	MDmTest*	iTest;	
sl@0: 	TInt		iNotifications;
sl@0: 	};
sl@0: 
sl@0: CDomainMemberAo* CDomainMemberAo::NewL(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest* aTest)
sl@0: 	{
sl@0: 	CDomainMemberAo* self=new (ELeave) CDomainMemberAo(aHierarchy, aId, aOrdinal, aTest);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL();
sl@0: 
sl@0: 	self->RequestTransitionNotification();
sl@0: 
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: CDomainMemberAo::CDomainMemberAo(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest* aTest) : 
sl@0: 	CDmDomain(aHierarchy, aId), 
sl@0: 	iHierarchy(aHierarchy), iId(aId), iOrdinal(aOrdinal), iTest(aTest)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CDomainMemberAo::~CDomainMemberAo()
sl@0: 	{
sl@0: 	Cancel();
sl@0: 	}
sl@0: 
sl@0: void CDomainMemberAo::RunL()
sl@0: 	{
sl@0: 	iNotifications++;
sl@0: 
sl@0: 	iState = GetState();
sl@0: 
sl@0: 	TInt ackError = iTest->TransitionNotification(*this);
sl@0: 	if (ackError == KErrNone)
sl@0: 		AcknowledgeLastState(ackError);
sl@0: 	else if (ackError == KErrAbort)	// don't acknowledge
sl@0: 		;
sl@0: 	else
sl@0: 		AcknowledgeLastState(ackError); 
sl@0: 	if (ackError != KErrAbort)	
sl@0: 		AcknowledgeLastState(ackError);
sl@0: 
sl@0: 	
sl@0: 	// request another notification (even if we didn't acknowledge the last one)
sl@0: 	RequestTransitionNotification();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // CDomainManagerAo
sl@0: class CDomainManagerAo : public CDmDomainManager
sl@0: 	{
sl@0: public:	
sl@0: 	~CDomainManagerAo();
sl@0: 	static CDomainManagerAo* NewL(TDmHierarchyId aHierarchy, MDmTest& aTest);
sl@0: 
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0: 
sl@0: private:
sl@0: 	CDomainManagerAo(TDmHierarchyId aHierarchy, MDmTest& aTest);
sl@0: 
sl@0: private:
sl@0: 	MDmTest& iTest;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: CDomainManagerAo* CDomainManagerAo::NewL(TDmHierarchyId aHierarchy, MDmTest& aTest)
sl@0: 	{
sl@0: 	CDomainManagerAo* self=new (ELeave) CDomainManagerAo(aHierarchy, aTest);
sl@0: 	CleanupStack::PushL(self);
sl@0: 
sl@0: 	self->ConstructL();
sl@0: 	CleanupStack::Pop();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: CDomainManagerAo::CDomainManagerAo(TDmHierarchyId aHierarchy, MDmTest& aTest) : 
sl@0: 	CDmDomainManager(aHierarchy), iTest(aTest)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CDomainManagerAo::~CDomainManagerAo()
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: void CDomainManagerAo::RunL()
sl@0: 	{
sl@0: 	iTest.TransitionRequestComplete();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: class CDmTest1 : public CActive, public MDmTest
sl@0: 	{
sl@0: public: // from CActive
sl@0: 	void RunL();
sl@0: 
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete() {};
sl@0: 
sl@0: 	CDmTest1 (TDmDomainId aId, TDmDomainState aState) : CActive(CActive::EPriorityStandard), iDomainId(aId), iState((TPowerState) aState) {}
sl@0: 
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: private:
sl@0: 	enum { KMembersMax = 16 };
sl@0: 	CDmTestMember*		iMembers[KMembersMax]; 
sl@0: 	RDmDomainManager	iManager;
sl@0: 	TDmDomainId			iDomainId;
sl@0: 	TPowerState			iState;
sl@0: 	TBool				iAcknowledge;
sl@0: 	TInt				iMembersCount;
sl@0: 	TInt				iCount;
sl@0: 	TUint32				iOrdinal;
sl@0: 	};
sl@0: 
sl@0: void CDmTest1::Perform()
sl@0: 	{
sl@0: 	//
sl@0: 	// Test domain transitions
sl@0: 	//
sl@0: 
sl@0: 	test.Next(_L("Test 1"));
sl@0: 	test.Printf(_L("Domain id = 0x%x Target State = 0x%x\n"), iDomainId, iState);
sl@0: 	iMembers[0] = new CDmTestMember(KDmHierarchyIdPower, KDmIdRoot, 0, this);
sl@0: 	test(iMembers[0] != NULL);
sl@0: 	iMembers[1] = new CDmTestMember(KDmHierarchyIdPower, KDmIdRoot, 0, this);
sl@0: 	test(iMembers[1] != NULL);
sl@0: 	iMembers[2] = new CDmTestMember(KDmHierarchyIdPower, KDmIdApps, 1, this);
sl@0: 	test(iMembers[2] != NULL);
sl@0: 	iMembers[3] = new CDmTestMember(KDmHierarchyIdPower, KDmIdApps, 1, this);
sl@0: 	test(iMembers[3] != NULL);
sl@0: 	iMembers[4] = new CDmTestMember(KDmHierarchyIdPower, KDmIdUiApps, 1, this);
sl@0: 	test(iMembers[4] != NULL);
sl@0: 	iMembers[5] = new CDmTestMember(KDmHierarchyIdPower, KDmIdUiApps, 1, this);
sl@0: 	test(iMembers[5] != NULL);
sl@0: 	
sl@0: 	// expected number of notifications
sl@0: 	iMembersCount = (iDomainId == KDmIdRoot) ? 6 : 2;
sl@0: 	// first expected ordinal
sl@0: 	iOrdinal = (iState == EPwActive) ? 0 : 1;
sl@0: 
sl@0: 	TInt r = iManager.Connect();
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	iManager.RequestDomainTransition(iDomainId, iState, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	CActiveScheduler::Start();
sl@0: 	}
sl@0: 
sl@0: TInt CDmTest1::TransitionNotification(MDmDomainMember& aDomainMember)
sl@0: 	{
sl@0: 	++iCount;
sl@0: 	if (aDomainMember.State() == EPwActive)
sl@0: 		{
sl@0: 		if(aDomainMember.Ordinal() < iOrdinal)
sl@0: 			{
sl@0: 			// Making the test to fail in RunL function inorder to complete the cleanup from domain manager.
sl@0: 			test.Printf(_L("Making test to fail as Ordinal Mismatch Expected : %d, Returned : %d"), aDomainMember.Ordinal(), iOrdinal);
sl@0: 			iCount--;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		if(aDomainMember.Ordinal() > iOrdinal)
sl@0: 			{
sl@0: 			//Making the test to fail in RunL function inorder to complete the cleanup from domain manager.
sl@0: 			test.Printf(_L("Making test to fail as Ordinal Mismatch Expected : %d, Returned : %d"), aDomainMember.Ordinal(), iOrdinal);
sl@0: 			iCount--;
sl@0: 			}
sl@0: 		}
sl@0: 	iOrdinal = aDomainMember.Ordinal();
sl@0: 
sl@0: 	// acknowledge one from two
sl@0: 	iAcknowledge = !iAcknowledge;
sl@0: 	return iAcknowledge?KErrNone:KErrGeneral;
sl@0: 	}
sl@0: 
sl@0: void CDmTest1::RunL()
sl@0: 	{
sl@0: 	CActiveScheduler::Stop();
sl@0: 
sl@0: 	iManager.Close();
sl@0: 
sl@0: 	CDmTestMember** mp;
sl@0: 	for (mp = iMembers; *mp; ++mp)
sl@0: 		delete *mp;
sl@0: 	test(iCount == iMembersCount);
sl@0: 	}
sl@0: 
sl@0: void CDmTest1::DoCancel()
sl@0: 	{
sl@0: 	test(0);
sl@0: 	}
sl@0: 
sl@0: void CDmTest1::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: class CDmTest2Timer : public CTimer
sl@0: 	{
sl@0: public: // fomr CTimer
sl@0:    void RunL();
sl@0: public:
sl@0: 	CDmTest2Timer() : CTimer(0) 
sl@0: 		{
sl@0: 		TRAPD(r,
sl@0: 			ConstructL());
sl@0: 		test(r == KErrNone);
sl@0: 		CActiveScheduler::Add(this);
sl@0: 		}
sl@0: 	};
sl@0: 
sl@0: void CDmTest2Timer::RunL()
sl@0: 	{
sl@0: 	test.Printf(_L("Tick count after CDmTest2Timer::RunL() = %d\n"), User::NTickCount());
sl@0: 
sl@0: 	// kick the timer again in case power down hasn't happened yet
sl@0: 	TTime wakeup;
sl@0: 	wakeup.HomeTime();
sl@0: 	wakeup += TTimeIntervalSeconds(3);
sl@0: 	At(wakeup);
sl@0: 	}
sl@0: 
sl@0: class CDmTest2 : public CActive, public MDmTest
sl@0: 	{
sl@0: public: // from CActive
sl@0: 	void RunL();
sl@0: 
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete() {};
sl@0: 	CDmTest2 (TDmDomainState aState) : CActive(CActive::EPriorityStandard), iState((TPowerState) aState) {}
sl@0: 
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: private:
sl@0: 	enum { KMembersMax = 16 };
sl@0: 	CDmTestMember*		iMembers[KMembersMax]; 
sl@0: 	RDmDomainManager	iManager;
sl@0: 	TPowerState			iState;
sl@0: 	TBool				iAcknowledge;
sl@0: 	TInt				iMembersCount;
sl@0: 	TInt				iCount;
sl@0: 	TUint32				iOrdinal;
sl@0: 	CDmTest2Timer*		iTimer;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: void CDmTest2::Perform()
sl@0: 	{
sl@0: 	//
sl@0: 	// Test system standby
sl@0: 	//
sl@0: 
sl@0: 	test.Next(_L("Test 2"));
sl@0: 	test.Printf(_L("Target State = 0x%x\n"), iState);
sl@0: 	iMembers[0] = new CDmTestMember(KDmHierarchyIdPower, KDmIdRoot, 0, this);
sl@0: 	test(iMembers[0] != NULL);
sl@0: 	iMembers[1] = new CDmTestMember(KDmHierarchyIdPower, KDmIdRoot, 0, this);
sl@0: 	test(iMembers[1] != NULL);
sl@0: 	iMembers[2] = new CDmTestMember(KDmHierarchyIdPower, KDmIdApps, 1, this);
sl@0: 	test(iMembers[2] != NULL);
sl@0: 	iMembers[3] = new CDmTestMember(KDmHierarchyIdPower, KDmIdApps, 1, this);
sl@0: 	test(iMembers[3] != NULL);
sl@0: 	iMembers[4] = new CDmTestMember(KDmHierarchyIdPower, KDmIdUiApps, 1, this);
sl@0: 	test(iMembers[4] != NULL);
sl@0: 	iMembers[5] = new CDmTestMember(KDmHierarchyIdPower, KDmIdUiApps, 1, this);
sl@0: 	test(iMembers[5] != NULL);
sl@0: 	
sl@0: 	// expected number of notifications
sl@0: 	iMembersCount = 12;
sl@0: 	// first expected ordinal
sl@0: 	iOrdinal = (iState == EPwActive) ? 0 : 1;
sl@0: 
sl@0: 	TInt r = iManager.Connect();
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	// Use an absolute timer to request a wakeup event
sl@0: 	iTimer = new CDmTest2Timer();
sl@0: 	TTime wakeup;
sl@0: 	wakeup.HomeTime();
sl@0: 	wakeup += TTimeIntervalSeconds(5);
sl@0: 	test.Printf(_L("Tick count before timer = %d\n"), User::NTickCount());
sl@0: 	iTimer->At(wakeup);
sl@0: 	
sl@0: 	iManager.RequestSystemTransition(iState, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	CActiveScheduler::Start();
sl@0: 	}
sl@0: 
sl@0: TInt CDmTest2::TransitionNotification(MDmDomainMember& aDomainMember)
sl@0: 	{
sl@0: 	++iCount;
sl@0: 	if (aDomainMember.State() == EPwActive)
sl@0: 		{
sl@0: 		if(aDomainMember.Ordinal() < iOrdinal)
sl@0: 			{
sl@0: 			// Making the test to fail in RunL function inorder to complete the cleanup from domain manager.
sl@0: 			test.Printf(_L("Making test to fail as Ordinal Mismatch Expected : %d, Returned : %d, State : %d"), 
sl@0: 																		aDomainMember.Ordinal(), iOrdinal, aDomainMember.State());
sl@0: 			iCount--;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		if(aDomainMember.Ordinal() > iOrdinal)
sl@0: 			{
sl@0: 			// Making the test to fail in RunL function inorder to complete the cleanup from domain manager.
sl@0: 			test.Printf(_L("Making test to fail as Ordinal Mismatch Expected : %d, Returned : %d, State: %d"), 
sl@0: 																		aDomainMember.Ordinal(), iOrdinal, aDomainMember.State());
sl@0: 			iCount--;
sl@0: 			}
sl@0: 		}
sl@0: 	iOrdinal = aDomainMember.Ordinal();
sl@0: 
sl@0: 	// acknowledge one from two
sl@0: 	iAcknowledge = !iAcknowledge;
sl@0: 	return iAcknowledge?KErrNone:KErrAbort;
sl@0: 	}
sl@0: 
sl@0: void CDmTest2::RunL()
sl@0: 	{
sl@0: 	test.Printf(_L("Tick count after CDmTest2::RunL() = %d\n"), User::NTickCount());
sl@0: 
sl@0: 	iTimer->Cancel();	
sl@0: 	CActiveScheduler::Stop();
sl@0: 
sl@0: 	iManager.Close();
sl@0: 
sl@0: 	CDmTestMember** mp;
sl@0: 	for (mp = iMembers; *mp; ++mp)
sl@0: 		delete *mp;
sl@0: 	test(CActive::iStatus == KErrTimedOut);
sl@0: 	test(iCount == iMembersCount);
sl@0: 	}
sl@0: 
sl@0: void CDmTest2::DoCancel()
sl@0: 	{
sl@0: 	test(0);
sl@0: 	}
sl@0: 
sl@0: void CDmTest2::Release()
sl@0: 	{
sl@0: 	if (iTimer)
sl@0: 		{
sl@0: 		iTimer->Cancel();
sl@0: 		delete iTimer;
sl@0: 		}
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: class CDmTest3 : public MDmTest
sl@0: 	{
sl@0: public: 
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete() {};
sl@0: 	};
sl@0: 
sl@0: void CDmTest3::Perform()
sl@0: 	{
sl@0: 	//
sl@0: 	// Test simple error situation
sl@0: 	//
sl@0: 	RDmDomainManager manager;
sl@0: 	TInt r = manager.Connect();
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	RDmDomainManager manager1;
sl@0: 	r = manager1.Connect();
sl@0: 	test(r == KErrInUse);
sl@0: 
sl@0: 	RDmDomain domain;
sl@0: 	r = domain.Connect(KDmIdNone);
sl@0: 	test(r == KDmErrBadDomainId);
sl@0: 	CDmTestMember*		testMember;
sl@0: 	testMember = new CDmTestMember(KDmHierarchyIdPower, KDmIdApps, 1, this);
sl@0: 	test (testMember != NULL);
sl@0: 
sl@0: 	TRequestStatus status;
sl@0: 	manager.RequestDomainTransition(KDmIdApps, EPwStandby, status);
sl@0: 	test(status.Int() == KRequestPending);
sl@0: 
sl@0: 	TRequestStatus status1;
sl@0: 	manager.RequestDomainTransition(KDmIdApps, EPwActive, status1);
sl@0: 	User::WaitForRequest(status1);
sl@0: 	test(status1.Int() == KDmErrBadSequence);
sl@0: 	User::WaitForRequest(status);
sl@0: 	test(status.Int() == KErrTimedOut);
sl@0: 
sl@0: 	// Since this test doesn't start the active scheduler, a domain member's RunL() will 
sl@0: 	// not get called so we need to re-request a domain transition notification manually
sl@0: 	User::WaitForRequest(testMember->iStatus);
sl@0: 	test(testMember->iStatus.Int() == KErrNone);
sl@0: 	testMember->iDomain.RequestTransitionNotification(testMember->iStatus);
sl@0: 
sl@0: 	manager.RequestDomainTransition(KDmIdApps, EPwActive, status);
sl@0: 	test(status.Int() == KRequestPending);
sl@0: 	manager.CancelTransition();
sl@0: 	test(status.Int() == KErrCancel);
sl@0: 	manager.CancelTransition();
sl@0: 	User::WaitForRequest(status);
sl@0: 	test(status.Int() == KErrCancel);
sl@0: 
sl@0: 	testMember->iDomain.CancelTransitionNotification();
sl@0: 
sl@0: 	delete testMember;
sl@0: 	
sl@0: 	domain.Close();
sl@0: 	manager.Close();
sl@0: 	}
sl@0: 
sl@0: TInt CDmTest3::TransitionNotification(MDmDomainMember& /*aDomainMember*/)
sl@0: 	{
sl@0: 	test(0);
sl@0: 	return KErrAbort;	// don't acknowledge
sl@0: 	}
sl@0: 
sl@0: void CDmTest3::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: class CDmTest4 : public MDmTest
sl@0: 	{
sl@0: public: 
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete() {};
sl@0: private:
sl@0: 	void ExecSlave(TUint arg);
sl@0: 	};
sl@0: 
sl@0: _LIT(KSecuritySlavePath, "t_domain_slave.exe");
sl@0: 
sl@0: void CDmTest4::ExecSlave(TUint aArg)
sl@0: 	{
sl@0: 	RProcess proc;
sl@0: 	TInt r = proc.Create(KSecuritySlavePath, TPtrC((TUint16*) &aArg, sizeof(aArg)/sizeof(TUint16)));
sl@0: 	test(r == KErrNone);
sl@0: 	TRequestStatus status;
sl@0: 	proc.Logon(status);
sl@0: 	proc.Resume();
sl@0: 	User::WaitForRequest(status);
sl@0: 
sl@0:     RDebug::Printf("CDmTest4::ExecSlave(%d) ExitType %d", aArg, proc.ExitType() );
sl@0:     RDebug::Printf("CDmTest4::ExecSlave(%d) ExitReason %d", aArg, proc.ExitReason() );
sl@0: 	test(proc.ExitType() == EExitKill);
sl@0: //	test(proc.ExitReason() == KErrPermissionDenied);
sl@0: 
sl@0: 	CLOSE_AND_WAIT(proc);
sl@0: 	}
sl@0: 
sl@0: //! @SYMTestCaseID PBASE-T_DOMAIN-4
sl@0: //! @SYMTestType CT
sl@0: //! @SYMTestCaseDesc Dmain manager security tests
sl@0: //! @SYMREQ 3722
sl@0: //! @SYMTestActions Launches a separate process with no capabilities
sl@0: //! @SYMTestExpectedResults  DM APIs should fail with KErrPermissionDenied
sl@0: //! @SYMTestPriority High
sl@0: //! @SYMTestStatus Defined
sl@0: void CDmTest4::Perform()
sl@0: 	{
sl@0: 	//
sl@0: 	// Security tests
sl@0: 	//
sl@0: 
sl@0: 	ExecSlave(0);
sl@0: 
sl@0:     ExecSlave(1);
sl@0: 
sl@0: 	}
sl@0: 
sl@0: TInt CDmTest4::TransitionNotification(MDmDomainMember& /*aDomainMember*/)
sl@0: 	{
sl@0: 	test(0);
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 
sl@0: void CDmTest4::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: // Test hierarchy tests
sl@0: class CDmTestStartupMember : public CDmTestMember
sl@0: 	{
sl@0: public:
sl@0: 	CDmTestStartupMember(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest*);
sl@0: 
sl@0: public:
sl@0: private:
sl@0: 	};
sl@0: 
sl@0: CDmTestStartupMember::CDmTestStartupMember(TDmHierarchyId aHierarchy, TDmDomainId aId, TUint32 aOrdinal, MDmTest* aTest) 
sl@0: 	: CDmTestMember(aHierarchy, aId, aOrdinal, aTest)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: // Simultaneously testing of test domain defined in DomainPolicy99.dll
sl@0: // and the power domain defined in DomainPolicy.dll
sl@0: class CDmTest5 : public CActive, public MDmTest
sl@0: 	{
sl@0: public: 
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete();
sl@0: 	CDmTest5(TDmDomainId aPowerId, TDmDomainId aTestId, TDmDomainState aPowerState, TDmDomainState aTestState) : 
sl@0: 		CActive(CActive::EPriorityStandard), 
sl@0: 		iPowerDomainId(aPowerId), iTestDomainId(aTestId), iPowerState(aPowerState), iTestState(aTestState) {}
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: private:
sl@0: 	enum { KMembersMax = 16 };
sl@0: 	enum TAckMode{ KAckAlways, KAckNever, KAckError, KAckOddDomainsOnly };
sl@0: 
sl@0: 	CDmTestMember*		iTestMembers[KMembersMax]; 
sl@0: 	CDomainMemberAo*	iPowerMembers[KMembersMax]; 
sl@0: 
sl@0: 	RDmDomainManager	iTestDomainManager;
sl@0: 	
sl@0: 	TDmDomainId			iPowerDomainId;
sl@0: 	TDmDomainId			iTestDomainId;
sl@0: 
sl@0: 	TDmDomainState		iPowerState;
sl@0: 	TDmDomainState		iTestState;
sl@0: 
sl@0: 	// level number for iTestDomainId. E.g 1 for KDmIdRoot, 2 for KDmIdTestA, etc.
sl@0: 	TInt				iTestDomainLevel;	
sl@0: 
sl@0: 	TDmTraverseDirection iTraverseDirection;
sl@0: 
sl@0: 	TAckMode			iAckMode;
sl@0: 
sl@0: public:
sl@0: 	TInt				iTestNotifications;
sl@0: 	TInt				iPowerNotifications;
sl@0: 	TInt				iTestNotificationsExpected;
sl@0: 	TInt				iPowerNotificationsExpected;
sl@0: 
sl@0: 	TInt				iTransitionsCompleted;
sl@0: 	TInt				iTransitionsExpected;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: 
sl@0: //! @SYMTestCaseID PBASE-T_DOMAIN-5
sl@0: //! @SYMTestType CT
sl@0: //! @SYMTestCaseDesc Connects to two domain hierarchies simulteneously and perform various tests
sl@0: //! @SYMREQ 3704,3705,3706,3707,3708,3709,3710,3711,3720,3721,3724,3725,3726,3727
sl@0: //! @SYMTestActions Open two hiearchies simultaneously and perform various actions.
sl@0: //! @SYMTestExpectedResults  All tests should pass
sl@0: //! @SYMTestPriority High
sl@0: //! @SYMTestStatus Defined
sl@0: void CDmTest5::Perform()
sl@0: 	{
sl@0: 
sl@0:  	__UHEAP_MARK;
sl@0: 
sl@0: 	//
sl@0: 	// Test domain transitions
sl@0: 	//
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	TInt r = RDmDomainManager::AddDomainHierarchy(KDmHierarchyIdTest);
sl@0: 
sl@0:     RDebug::Printf("RDmDomainManager::AddDomainHierarchy returns %d", r );
sl@0: 
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	CDomainManagerAo* powerDomainManager = NULL;
sl@0: 	TRAP(r, powerDomainManager = CDomainManagerAo::NewL(KDmHierarchyIdPower, *this));
sl@0: 	test (powerDomainManager != NULL);
sl@0: 
sl@0: 	r = CDomainManagerAo::AddDomainHierarchy(KDmHierarchyIdPower);
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	//	Test 5a - connect to two domain hierarchies simultaneously
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5a - connect to two domain hierarchies simultaneously"));
sl@0: 
sl@0: 	test.Printf(_L("Domain id = 0x%x, Target State = 0x%x\n"), iTestDomainId, iTestState);
sl@0: 
sl@0: 	TInt testMemberCount = 0;
sl@0: 
sl@0: 	// Add some test hierarchy members - these use the RDmDomain API
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdRoot, ORDINAL_FROM_DOMAINID0(KDmIdRoot), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdRoot, ORDINAL_FROM_DOMAINID0(KDmIdRoot), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 1
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestA, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestB, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestB), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestC, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestC), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row2
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestAA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestAB, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAB), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestBA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestB, KDmIdTestBA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestCA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestC, KDmIdTestCA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 3
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestABA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestABB, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABB), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	iTestMembers[testMemberCount] = new CDmTestMember(KDmHierarchyIdTest, KDmIdTestCAA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestC, KDmIdTestCA, KDmIdTestCAA), this);
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 
sl@0: 	// add some power hierarchy members - these use the CDmDomain AO API
sl@0: 	TInt powerMemberCount = 0;
sl@0: 	TRAP(r, iPowerMembers[powerMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdPower, KDmIdRoot, KDmIdRoot, this));
sl@0: 	test(iTestMembers[powerMemberCount++] != NULL);
sl@0: 	TRAP(r, iPowerMembers[powerMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdPower, KDmIdApps, KDmIdApps, this));
sl@0: 	test(iTestMembers[powerMemberCount++] != NULL);
sl@0: 	TRAP(r, iPowerMembers[powerMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdPower, KDmIdUiApps, KDmIdUiApps, this));
sl@0: 	test(iTestMembers[powerMemberCount++] != NULL);
sl@0: 
sl@0: 
sl@0: 	RArray<const TTransitionFailure> testFailures;
sl@0: 	TInt testFailureCount;
sl@0: 	RArray<const TTransitionFailure> powerFailures;
sl@0: 	TInt powerFailureCount;
sl@0: 
sl@0: 
sl@0: 
sl@0: 	// calculate the expected number of notifications
sl@0: 	TInt expectedTestNotifications = 0;
sl@0: 	TInt leafNodes = 0;
sl@0: 	
sl@0: 
sl@0: 	// work out the domain level, the number of leaf nodes and the expected number of 
sl@0: 	// notifications for the domain that is being transitioned
sl@0: 	switch(iTestDomainId)
sl@0: 		{
sl@0: 		case KDmIdRoot		:	iTestDomainLevel = 1; leafNodes = 5; expectedTestNotifications = testMemberCount; break;
sl@0: 		case KDmIdTestA		:	iTestDomainLevel = 2; leafNodes = 3; expectedTestNotifications = 5; break;
sl@0: 		case KDmIdTestB		:	iTestDomainLevel = 2; leafNodes = 1; expectedTestNotifications = 2; break;
sl@0: 		case KDmIdTestC		:	iTestDomainLevel = 2; leafNodes = 1; expectedTestNotifications = 3; break;
sl@0: 
sl@0: 		case KDmIdTestAA	:	iTestDomainLevel = 3; leafNodes = 1; expectedTestNotifications = 1; break;
sl@0: 		case KDmIdTestAB	:	iTestDomainLevel = 3; leafNodes = 2; expectedTestNotifications = 3; break;
sl@0: 		case KDmIdTestBA	:	iTestDomainLevel = 3; leafNodes = 1; expectedTestNotifications = 1; break;
sl@0: 		case KDmIdTestCA	:	iTestDomainLevel = 3; leafNodes = 1; expectedTestNotifications = 2; break;
sl@0: 
sl@0: 		case KDmIdTestABA	:	iTestDomainLevel = 4; leafNodes = 1; expectedTestNotifications = 1; break;
sl@0: 		case KDmIdTestABB	:	iTestDomainLevel = 4; leafNodes = 1; expectedTestNotifications = 1; break;
sl@0: 		case KDmIdTestCAA	:	iTestDomainLevel = 4; leafNodes = 1; expectedTestNotifications = 1; break;
sl@0: 		default:
sl@0: 			test(0);
sl@0: 		}
sl@0: 	test.Printf(_L("Test Domain id = 0x%x, Level = %d, Target State = 0x%x, expected notifications = %d, leafNodes = %d\n"), 
sl@0: 		iTestDomainId, iTestDomainLevel, iTestState, expectedTestNotifications, leafNodes);
sl@0: 
sl@0: 	TInt expectedPowerNotifications = 0;
sl@0: 	switch(iPowerDomainId)
sl@0: 		{
sl@0: 		case KDmIdRoot		:	expectedPowerNotifications = powerMemberCount; break;
sl@0: 		case KDmIdApps		:	expectedPowerNotifications = 1; break;
sl@0: 		case KDmIdUiApps	:	expectedPowerNotifications = 1; break;
sl@0: 		default:
sl@0: 			test(0);
sl@0: 		}
sl@0: 
sl@0: 
sl@0: 
sl@0: 	// connect to the test hierarchy
sl@0: 	r = iTestDomainManager.Connect(KDmHierarchyIdTest);
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	// verify that we can't connect to the same hierarchy more than once
sl@0: 	RDmDomainManager	domainManager;
sl@0: 	r = domainManager.Connect(KDmHierarchyIdTest);
sl@0: 	test(r == KErrInUse);
sl@0: 
sl@0: 
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 5b - request a positive transition
sl@0: 	// issue a positive  transition (i.e. transition state increases)
sl@0: 	// and request that the test domain use ETraverseParentsFirst
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5b - request a positive transition"));
sl@0: 	iAckMode = KAckAlways;
sl@0: 
sl@0: 	iTransitionsCompleted = iTestNotifications = iPowerNotifications = 0;
sl@0: 	iPowerNotificationsExpected = 0;
sl@0: 	iTestNotificationsExpected = expectedTestNotifications;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	// DON'T request any domain transition on the power hierarchy
sl@0: 	// powerDomainManager->RequestDomainTransition(iPowerDomainId, EPwActive);
sl@0: 	// request a domain transition on the test hierarchy
sl@0: 	iTraverseDirection = ETraverseParentsFirst;
sl@0: 	if (iTestDomainId == KDmIdRoot)
sl@0: 		iTestDomainManager.RequestSystemTransition(iTestState, ETraverseDefault, CActive::iStatus);
sl@0: 	else
sl@0: 		iTestDomainManager.RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(powerDomainManager->iStatus == KErrNone);
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test(iPowerNotifications == iPowerNotificationsExpected);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 5c- verify domains are in correct state
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5c- verify domains are in correct state"));
sl@0: 	RDmDomain domainMember;
sl@0: 	r = domainMember.Connect(KDmHierarchyIdTest, iTestDomainId);
sl@0: 	test (r == KErrNone);
sl@0: 	TDmDomainState state = domainMember.GetState();
sl@0: 	domainMember.Close();
sl@0: 	test (state == iTestState);
sl@0: 
sl@0: 	// if the transition request is not on the root, verify that that 
sl@0: 	// the root domain and the transition domain are in different states
sl@0: 	if (iTestDomainId != KDmIdRoot && iTestState != EStartupCriticalStatic)
sl@0: 		{
sl@0: 		r = domainMember.Connect(KDmHierarchyIdTest, KDmIdRoot);
sl@0: 		test (r == KErrNone);
sl@0: 		TDmDomainState state = domainMember.GetState();
sl@0: 		domainMember.Close();
sl@0: 		test (state != iTestState);
sl@0: 		}
sl@0: 
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 5d- request a negative transition
sl@0: 	// issue a negative transition (i.e. transition state decreases)
sl@0: 	// and request that the test domain use ETraverseChildrenFirst
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5d- request a negative transition"));
sl@0: 	iAckMode = KAckAlways;
sl@0: 	iTestState--;	// EStartupCriticalStatic;
sl@0: 	iPowerState--;	// EPwStandby
sl@0: 
sl@0: 	iTransitionsCompleted = iTestNotifications = iPowerNotifications = 0;
sl@0: 	iPowerNotificationsExpected = expectedPowerNotifications;
sl@0: 	iTestNotificationsExpected = expectedTestNotifications;
sl@0: 	iTransitionsExpected = 2;
sl@0: 
sl@0: 	// DO request a domain transition on the power hierarchy
sl@0: 	powerDomainManager->RequestDomainTransition(iPowerDomainId, iPowerState, ETraverseDefault);
sl@0: 
sl@0: 	// request a domain transition on the test hierarchy
sl@0: 	iTraverseDirection = ETraverseChildrenFirst;
sl@0: 	iTestDomainManager.RequestDomainTransition(iTestDomainId, iTestState, iTraverseDirection, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	// wait for all test & power transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(powerDomainManager->iStatus == KErrNone);
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test(iPowerNotifications == iPowerNotificationsExpected);
sl@0: 	
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 5e- request a positive transition, with zero acknowledgements
sl@0: 	// issue a positive transition with no members acknowledging the transition
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5e- request a positive transition, with zero acknowledgements"));
sl@0: 	iAckMode = KAckNever;
sl@0: 	iTestState++;		// EStartupCriticalDynamic;
sl@0: 	iPowerState++;		// EPwActive
sl@0: 
sl@0: 	// power hierarchy should continue on failure, so we all power domains should transition
sl@0: 	// test hierarchy should stop on failure, so should get notifications from all leaf nodes
sl@0: 	iTransitionsCompleted = iTestNotifications = iPowerNotifications = 0;
sl@0: 	iPowerNotificationsExpected = expectedPowerNotifications;
sl@0: 	iTestNotificationsExpected = leafNodes;	// 5 leaf nodes for root domain
sl@0: 	iTransitionsExpected = 2;
sl@0: 
sl@0: 	// DO request a domain transition on the power hierarchy
sl@0: 	powerDomainManager->RequestDomainTransition(iPowerDomainId, iPowerState, ETraverseDefault);
sl@0: 
sl@0: 	// request a domain transition on the test hierarchy
sl@0: 	iTraverseDirection = ETraverseChildrenFirst;
sl@0: 	iTestDomainManager.RequestDomainTransition(iTestDomainId, iTestState, iTraverseDirection, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	// wait for all test & power transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(powerDomainManager->iStatus == KErrTimedOut);
sl@0: 	test(iStatus == KErrTimedOut);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test(iPowerNotifications == iPowerNotificationsExpected);
sl@0: 	
sl@0: 	// get the failures on the test hierarchy
sl@0: 	testFailureCount = iTestDomainManager.GetTransitionFailureCount();
sl@0: 	test (testFailureCount == 1);
sl@0: 
sl@0: 	r = iTestDomainManager.GetTransitionFailures(testFailures);
sl@0: 	test(r == KErrNone);
sl@0: 	test(testFailureCount == testFailures.Count());
sl@0: 
sl@0: 	test.Printf(_L("Test failures = %d\n"), testFailureCount);
sl@0: 	TInt i;
sl@0: 	for (i=0; i<testFailureCount; i++)
sl@0: 		{
sl@0: 		test.Printf(_L("%d: iDomainId %d, iError %d\n"), 
sl@0: 			i, testFailures[i].iDomainId, testFailures[i].iError);
sl@0: 		test(testFailures[i].iError == KErrTimedOut);
sl@0: 		}
sl@0: 
sl@0: 	// get the failures on the power hierarchy
sl@0: 	powerFailureCount = powerDomainManager->GetTransitionFailureCount();
sl@0: 	test (powerFailureCount == expectedPowerNotifications);
sl@0: 
sl@0: 	r = powerDomainManager->GetTransitionFailures(powerFailures);
sl@0: 	test(r == KErrNone);
sl@0: 	test(powerFailureCount == powerFailures.Count());
sl@0: 
sl@0: 	test.Printf(_L("Power failures = %d\n"), powerFailureCount);
sl@0: 	for (i=0; i<powerFailureCount; i++)
sl@0: 		{
sl@0: 		test.Printf(_L("%d: iDomainId %d, iError %d\n"), 
sl@0: 			i, powerFailures[i].iDomainId, powerFailures[i].iError);
sl@0: 		test(powerFailures[i].iError == KErrTimedOut);
sl@0: 		}
sl@0: 
sl@0: 	
sl@0: 	//*************************************************
sl@0: 	// Test 5f- request a positive transition, with error acknowledgements
sl@0: 	// issue a positive transition with all members nack'ing the transition
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 5f- request a positive transition, with error acknowledgements"));
sl@0: 	iAckMode = KAckError;
sl@0: 	iTestState++;		
sl@0: 	iPowerState++;		
sl@0: 
sl@0: 	// power hierarchy should continue on failure, so all power domains should transition
sl@0: 	// test hierarchy should stop on failure, so should get notifications from 
sl@0: 	// anything from 1 to all the leaf nodes
sl@0: 	iTransitionsCompleted = iTestNotifications = iPowerNotifications = 0;
sl@0: 	iPowerNotificationsExpected = expectedPowerNotifications;
sl@0: 	iTestNotificationsExpected = leafNodes;	// 5 leaf nodes for root domain
sl@0: 	iTransitionsExpected = 2;
sl@0: 
sl@0: 	// DO request a domain transition on the power hierarchy
sl@0: 	powerDomainManager->RequestDomainTransition(iPowerDomainId, iPowerState, ETraverseDefault);
sl@0: 
sl@0: 	// request a domain transition on the test hierarchy
sl@0: 	iTraverseDirection = ETraverseChildrenFirst;
sl@0: 	iTestDomainManager.RequestDomainTransition(iTestDomainId, iTestState, iTraverseDirection, CActive::iStatus);
sl@0: 	CActive::SetActive();
sl@0: 
sl@0: 	// wait for all test & power transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(powerDomainManager->iStatus == KErrGeneral);
sl@0: 	test(iStatus == KErrGeneral);
sl@0: 	test(iTestNotifications <= iTestNotificationsExpected);
sl@0: 	test(iPowerNotifications == iPowerNotificationsExpected);
sl@0: 	
sl@0: 	// get the failures on the test hierarchy
sl@0: 	testFailureCount = iTestDomainManager.GetTransitionFailureCount();
sl@0: 	test (testFailureCount == 1);
sl@0: 
sl@0: 	r = iTestDomainManager.GetTransitionFailures(testFailures);
sl@0: 	test(r == KErrNone);
sl@0: 	test(testFailureCount == testFailures.Count());
sl@0: 
sl@0: 	test.Printf(_L("Test failures = %d\n"), testFailureCount);
sl@0: 	for (i=0; i<testFailureCount; i++)
sl@0: 		{
sl@0: 		test.Printf(_L("%d: iDomainId %d, iError %d\n"), 
sl@0: 			i, testFailures[i].iDomainId, testFailures[i].iError);
sl@0: 		test(testFailures[i].iError == KErrGeneral);
sl@0: 		}
sl@0: 
sl@0: 	// get the failures on the power hierarchy
sl@0: 	powerFailureCount = powerDomainManager->GetTransitionFailureCount();
sl@0: 	test (powerFailureCount == expectedPowerNotifications);
sl@0: 
sl@0: 	r = powerDomainManager->GetTransitionFailures(powerFailures);
sl@0: 	test(r == KErrNone);
sl@0: 	test(powerFailureCount == powerFailures.Count());
sl@0: 
sl@0: 	test.Printf(_L("Power failures = %d\n"), powerFailureCount);
sl@0: 	for (i=0; i<powerFailureCount; i++)
sl@0: 		{
sl@0: 		test.Printf(_L("%d: iDomainId %d, iError %d\n"), 
sl@0: 			i, powerFailures[i].iDomainId, powerFailures[i].iError);
sl@0: 		test(powerFailures[i].iError == KErrGeneral);
sl@0: 		}
sl@0: 
sl@0: 	
sl@0: 	// cleanup
sl@0: 
sl@0: 	testFailures.Reset();
sl@0: 	powerFailures.Reset();
sl@0: 
sl@0: 	iTestDomainManager.Close();
sl@0: 	delete powerDomainManager;
sl@0: 	powerDomainManager = NULL;
sl@0: 
sl@0: 	CDmTestMember** mt;
sl@0: 	for (mt = iTestMembers; *mt; ++mt)
sl@0: 		delete *mt;
sl@0: 
sl@0: 	CDomainMemberAo** mp;
sl@0: 	for (mp = iPowerMembers; *mp; ++mp)
sl@0: 		delete *mp;
sl@0: 
sl@0: 
sl@0: 	// restore the domain hierarchies to their initial state so as not to 
sl@0: 	// upset any subsequent tests which rely on this
sl@0: 	{
sl@0: 	RDmDomainManager manager;
sl@0: 	TInt r = manager.Connect();
sl@0: 	test (r == KErrNone);
sl@0: 	TRequestStatus status;
sl@0: 	manager.RequestDomainTransition(KDmIdRoot, EPwActive, status);
sl@0: 	test(status.Int() == KRequestPending);
sl@0: 	User::WaitForRequest(status);
sl@0: 	test(status.Int() == KErrNone);
sl@0: 	manager.Close();
sl@0: 	
sl@0: 	r = manager.Connect(KDmHierarchyIdTest);
sl@0: 	test (r == KErrNone);
sl@0: 	manager.RequestDomainTransition(KDmIdRoot, EStartupCriticalStatic, ETraverseDefault, status);
sl@0: 	test(status.Int() == KRequestPending);
sl@0: 	User::WaitForRequest(status);
sl@0: 	test(status.Int() == KErrNone);
sl@0: 	manager.Close();
sl@0: 	}
sl@0: 
sl@0:  	__UHEAP_MARKEND;
sl@0: 	}
sl@0: 
sl@0: // This handles a transition notification from either a power domain member or 
sl@0: // a test domain member.
sl@0: // Verifies that the domain state is as expected.
sl@0: // Updates the number of notifications for each hierarchy and verifies that all parent 
sl@0: // domains have transitioned already (for parent-to-child transitions) or that all child 
sl@0: // domains have been transitioned already (for child-to-parent transitions).
sl@0: 
sl@0: TInt CDmTest5::TransitionNotification(MDmDomainMember& aDomainMember)
sl@0: 	{
sl@0: 	if (aDomainMember.HierarchyId() == KDmHierarchyIdPower)
sl@0: 		iPowerNotifications++;
sl@0: 	else
sl@0: 		iTestNotifications++;
sl@0: 
sl@0: 	if (aDomainMember.HierarchyId() == KDmHierarchyIdPower)
sl@0: 		{
sl@0: 		__PRINT((_L("CDmTest5::TransitionNotification(), Hierarchy = %d, iOrdinal = 0x%08X, state = 0x%x, status = %d\n"), 
sl@0: 			aDomainMember.HierarchyId(), aDomainMember.Ordinal(), aDomainMember.State(), aDomainMember.Status()));
sl@0: 		test(aDomainMember.State() == iPowerState);
sl@0: 		}
sl@0: 	else if (aDomainMember.HierarchyId() == KDmHierarchyIdTest)
sl@0: 		{
sl@0: 		TBuf16<4> buf;
sl@0: 		GetDomainDesc(aDomainMember.Ordinal(), buf);
sl@0: 
sl@0: 		__PRINT((_L("CDmTest5::TransitionNotification(), Hierarchy = %d, domain = %S, iOrdinal = 0x%08X, state = 0x%x, status = %d\n"), 
sl@0: 			aDomainMember.HierarchyId(), &buf, aDomainMember.Ordinal(), aDomainMember.State(), aDomainMember.Status()));
sl@0: 		test(aDomainMember.State() == iTestState);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		test(0);
sl@0: 		}
sl@0: 
sl@0: 	// if we're going from parent to child, 
sl@0: 	// check that each parent domain has received a notification already
sl@0: 	// if not, check that each child domain has received a notification already
sl@0: 
sl@0: 	CDmTestMember** mp;
sl@0: 
sl@0: 	if (aDomainMember.HierarchyId() == KDmHierarchyIdTest && iAckMode == KAckAlways)
sl@0: 		{
sl@0: 
sl@0: 		if (iTraverseDirection == ETraverseParentsFirst)
sl@0: 			{
sl@0: 			TUint ordThis = aDomainMember.Ordinal();
sl@0: 			TUint ordParent = PARENT_ORDINAL(ordThis);
sl@0: 
sl@0: 			TInt levelParent = ORDINAL_LEVEL(ordParent);
sl@0: 
sl@0: 			TBuf16<4> buf;
sl@0: 			GetDomainDesc(ordParent, buf);
sl@0: 			if (levelParent >= iTestDomainLevel)
sl@0: 				{
sl@0: 				__PRINT((_L("Searching for parent domain = %S, ordinal = %08X \n"), &buf, ordParent));
sl@0: 				for (mp = iTestMembers; *mp; ++mp)
sl@0: 					{
sl@0: 					if ((*mp)->Ordinal() == ordParent)
sl@0: 						{
sl@0: 						TBuf16<4> buf;
sl@0: 						GetDomainDesc((*mp)->Ordinal(), buf);
sl@0: 						__PRINT((_L("Found parent (%S). notification = %d\n"), &buf, (*mp)->Notifications()));
sl@0: 						test ((*mp)->Notifications() == aDomainMember.Notifications());
sl@0: 						break;
sl@0: 						}
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			__PRINT((_L("Searching for children\n")));
sl@0: 			for (mp = iTestMembers; *mp; ++mp)
sl@0: 				{
sl@0: 
sl@0: 				TUint ordParent = PARENT_ORDINAL((*mp)->Ordinal());
sl@0: 				if (ordParent == aDomainMember.Ordinal())
sl@0: 					{
sl@0: 					TBuf16<4> buf;
sl@0: 					GetDomainDesc((*mp)->Ordinal(), buf);
sl@0: 					__PRINT((_L("Found child (%S). notification = %d\n"), &buf, (*mp)->Notifications()));
sl@0: 					test ((*mp)->Notifications() == aDomainMember.Notifications());
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	TInt ackError;
sl@0: 	switch (iAckMode)
sl@0: 		{
sl@0: 		case KAckNever:
sl@0: 			ackError = KErrAbort;
sl@0: 			break;
sl@0: 		case KAckError:		// return an error to the DM
sl@0: 			ackError = KErrGeneral;
sl@0: 			break;
sl@0: 		case KAckOddDomainsOnly:
sl@0: 			ackError = (aDomainMember.DomainId() & 1)?KErrNone:KErrAbort;
sl@0: 			break;
sl@0: 		case KAckAlways:
sl@0: 		default:
sl@0: 			ackError = KErrNone;
sl@0: 			break;
sl@0: 		}
sl@0: 	return ackError;
sl@0: 	}
sl@0: 
sl@0: void CDmTest5::RunL()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	__PRINT((_L("CDmTest5::RunL(), error = %d, iTestNotifications %d, iPowerNotifications %d\n"), 
sl@0: 		iStatus.Int(), iTestNotifications , iPowerNotifications));
sl@0: 
sl@0: 	if (iTransitionsCompleted == iTransitionsExpected)
sl@0: 		CActiveScheduler::Stop();
sl@0: 	}
sl@0: 
sl@0: void CDmTest5::TransitionRequestComplete()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	__PRINT((_L("CDmTest5::TransitionRequestComplete(), error = %d, iTestNotifications %d, iPowerNotifications %d\n"), 
sl@0: 		iStatus.Int(), iTestNotifications , iPowerNotifications));
sl@0: 	
sl@0: 	if (iTransitionsCompleted == iTransitionsExpected)
sl@0: 		CActiveScheduler::Stop();
sl@0: 	}
sl@0: 
sl@0: void CDmTest5::DoCancel()
sl@0: 	{
sl@0: 	test(0);
sl@0: 	}
sl@0: 
sl@0: void CDmTest5::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: const TInt KMembersMax = 16;
sl@0: 
sl@0: // Negative testing 
sl@0: class CDmTest6 : public CActive, public MDmTest
sl@0: 	{
sl@0: public:
sl@0: 	enum 
sl@0: 	{
sl@0: 	ENegTestTransitionNoConnect,
sl@0: 	ENegTestGetStateNoConnect,
sl@0: 	ENegTestTransitionInvalidMode
sl@0: 	};
sl@0: 
sl@0: 	class TData 
sl@0: 		{
sl@0: 	public:
sl@0: 		inline TData(TInt aTest) : iTest(aTest){};
sl@0: 		TInt iTest;
sl@0: 		};
sl@0: 
sl@0: public: 
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0:  
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete();
sl@0: 
sl@0: 
sl@0: 	CDmTest6() : CActive(CActive::EPriorityStandard) {}
sl@0: 
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: private:
sl@0: 	static TInt PanicThreadFunc(TAny* aData);
sl@0: 	void PanicTest(TInt aTestNumber);
sl@0: 
sl@0: 
sl@0: 	CDomainMemberAo*	iTestMembers[KMembersMax]; 
sl@0: 	CDomainManagerAo*	iTestDomainManager;
sl@0: 	
sl@0: 	TDmDomainId			iTestDomainId;
sl@0: 	TDmDomainState		iTestState;
sl@0: 
sl@0: public:
sl@0: 	TInt				iTestNotifications;
sl@0: 	TInt				iTestNotificationsExpected;
sl@0: 
sl@0: 	TInt				iTransitionsCompleted;
sl@0: 	TInt				iTransitionsExpected;
sl@0: 	};
sl@0: 
sl@0: TInt CDmTest6::PanicThreadFunc(TAny* aData)
sl@0: 	{
sl@0: 	const TData* data = (const TData*)aData;
sl@0: 	switch (data->iTest)
sl@0: 		{
sl@0: 		case ENegTestTransitionNoConnect:
sl@0: 			{
sl@0: 			// request a transition notification without connecting first (should panic)
sl@0: 			RDmDomain domainMember;
sl@0: 			TRequestStatus status;
sl@0: 			User::SetJustInTime(EFalse);
sl@0: 			domainMember.RequestTransitionNotification(status);
sl@0: 			}
sl@0: 			break;
sl@0: 		case ENegTestGetStateNoConnect:
sl@0: 			{
sl@0: 			// Get the domain state without connecting (should panic)
sl@0: 			RDmDomain domainMember;
sl@0: 			User::SetJustInTime(EFalse);
sl@0: 			domainMember.GetState();
sl@0: 			}
sl@0: 			break;
sl@0: 		case ENegTestTransitionInvalidMode:
sl@0: 			{
sl@0: 			RDmDomainManager manager;
sl@0: 			TRequestStatus status;
sl@0: 			TInt r = manager.Connect(KDmHierarchyIdTest);
sl@0: 			test(r == KErrNone);
sl@0: 
sl@0: 			User::SetJustInTime(EFalse);
sl@0: 			manager.RequestDomainTransition(KDmIdRoot, 0, TDmTraverseDirection(-1), status);
sl@0: 			}
sl@0: 			break;
sl@0: 		default:
sl@0: 			break;
sl@0: 		}
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 
sl@0: void CDmTest6::PanicTest(TInt aTestNumber)
sl@0: 	{
sl@0: 	test.Printf(_L("panic test number %d\n"), aTestNumber);
sl@0: 
sl@0: 	TBool jit = User::JustInTime();
sl@0: 
sl@0: 	TData data(aTestNumber);
sl@0: 
sl@0: 	TInt KHeapSize=0x2000;
sl@0: 
sl@0: 	RThread thread;
sl@0: 	TInt ret = thread.Create(KThreadName, PanicThreadFunc, KDefaultStackSize, KHeapSize, KHeapSize, &data);
sl@0: 	test(KErrNone == ret);
sl@0: 	TRequestStatus stat;
sl@0: 	thread.Logon(stat);
sl@0: 	thread.Resume();
sl@0: 	User::WaitForRequest(stat);
sl@0: 
sl@0: 	User::SetJustInTime(jit);
sl@0: 
sl@0: 	// The thread must panic
sl@0: 	test(thread.ExitType() == EExitPanic);
sl@0: 	TInt exitReason = thread.ExitReason();
sl@0: 	test.Printf(_L("panic test exit reason = %d\n"), exitReason);
sl@0: 
sl@0: 	switch(aTestNumber)
sl@0: 		{
sl@0: 		case ENegTestTransitionNoConnect:
sl@0: 			test (exitReason == EBadHandle);
sl@0: 			break;
sl@0: 		case ENegTestGetStateNoConnect:
sl@0: 			test (exitReason == EBadHandle);
sl@0: 			break;
sl@0: 		case ENegTestTransitionInvalidMode:
sl@0: 			break;
sl@0: 		default:
sl@0: 			break;
sl@0: 		}
sl@0: 
sl@0: 	CLOSE_AND_WAIT(thread);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: //! @SYMTestCaseID PBASE-T_DOMAIN-6
sl@0: //! @SYMTestType CT
sl@0: //! @SYMTestCaseDesc Negative testing
sl@0: //! @SYMPREQ 810
sl@0: //! @SYMTestActions Various negative tests
sl@0: //! @SYMTestExpectedResults  All tests should pass
sl@0: //! @SYMTestPriority High
sl@0: //! @SYMTestStatus Defined
sl@0: void CDmTest6::Perform()
sl@0: 	{
sl@0: 
sl@0:  	__UHEAP_MARK;
sl@0: 
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	CDomainManagerAo* iTestDomainManager = NULL;
sl@0: 	TRAP_IGNORE(iTestDomainManager = CDomainManagerAo::NewL(KDmHierarchyIdTest, *this));
sl@0: 	test (iTestDomainManager != NULL);
sl@0: 
sl@0: 	TInt r = CDomainManagerAo::AddDomainHierarchy(KDmHierarchyIdTest);
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6a - Connect to the same hierarchy twice
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6a - Connect to the same hierarchy twice"));
sl@0: 
sl@0: 	// verify that we can't connect to the same hierarchy more than once
sl@0: 	CDomainManagerAo* testDomainManager = NULL;
sl@0: 	TRAP(r, testDomainManager = CDomainManagerAo::NewL(KDmHierarchyIdTest, *this));
sl@0: 	test(r == KErrInUse);
sl@0: 	test (testDomainManager == NULL);
sl@0: 
sl@0: 
sl@0: 	TInt testMemberCount = 0;
sl@0: 
sl@0: 	// Add some test hierarchy members
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdRoot, ORDINAL_FROM_DOMAINID0(KDmIdRoot), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdRoot, ORDINAL_FROM_DOMAINID0(KDmIdRoot), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 1
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestA, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestB, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestC, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestC), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row2
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestAA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestAB, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestBA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestB, KDmIdTestBA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestCA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestC, KDmIdTestCA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 3
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestABA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestABB, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestCAA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestC, KDmIdTestCA, KDmIdTestCAA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6b change to current state
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6b change to current state"));
sl@0: 	iTestState =  EStartupCriticalStatic;
sl@0: 	iTestDomainId = KDmIdRoot;
sl@0: 
sl@0: 	iTransitionsCompleted = iTestNotifications = 0;
sl@0: 	iTestNotificationsExpected = testMemberCount;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	// request a domain transition
sl@0: 	iTestDomainManager->RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault);
sl@0: 
sl@0: 	// wait for test transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	
sl@0: 
sl@0: 	// cancel a member notification request 
sl@0: 	//*************************************************
sl@0: 	// Test 6c cancel a member notification request
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6c cancel a member notification request"));
sl@0: 	RDmDomain domainMember;
sl@0: 	TRequestStatus status;
sl@0: 	domainMember.Connect(KDmHierarchyIdTest, iTestDomainId);
sl@0: 	domainMember.RequestTransitionNotification(status);
sl@0: 	domainMember.CancelTransitionNotification();
sl@0: 	User::WaitForRequest(status);
sl@0: 	domainMember.Close();
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6d cancel a member notification request without having first requested a notification
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6d cancel a member notification request without having first requested a notification"));
sl@0: 	domainMember.Connect(KDmHierarchyIdTest, iTestDomainId);
sl@0: 	domainMember.CancelTransitionNotification();
sl@0: 	domainMember.Close();
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6e domain controller adds invalid hierarchy
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6e domain controller connects to invalid hierarchy"));
sl@0: 	r = RDmDomainManager::AddDomainHierarchy(TDmHierarchyId(-1));
sl@0: 	test(r == KErrBadHierarchyId);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6f domain member connects to invalid hierarchy
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6f domain member connects to invalid hierarchy"));
sl@0: 	r = domainMember.Connect(TDmHierarchyId(-1), TDmDomainId(KDmIdRoot));
sl@0: 	test (r == KErrBadHierarchyId);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6g domain member connects to valid hierarchy but invalid domain
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6g domain member connects to valid hierarchy but invalid domain"));
sl@0: 	r = domainMember.Connect(KDmHierarchyIdTest, TDmDomainId(-1));
sl@0: 	test (r == KDmErrBadDomainId);
sl@0: 
sl@0: 	delete iTestDomainManager;
sl@0: 	iTestDomainManager = NULL;
sl@0: 
sl@0: 	// Panic tests
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6h request a transition notification without connecting first
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6h request a transition notification without connecting first"));
sl@0: 	PanicTest(ENegTestTransitionNoConnect);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6i Get the domain state without connecting
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6i Get the domain state without connecting"));
sl@0: 	PanicTest(ENegTestGetStateNoConnect);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 6j request a transition notification with an invalid transition mode
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 6j request a transition notification with an invalid transition mode"));
sl@0: 	PanicTest(ENegTestTransitionInvalidMode);
sl@0: 
sl@0: 
sl@0: 	// cleanup
sl@0: 
sl@0: 	CDomainMemberAo** mt;
sl@0: 	for (mt = iTestMembers; *mt; ++mt)
sl@0: 		delete *mt;
sl@0: 
sl@0:  	__UHEAP_MARKEND;
sl@0: 	}
sl@0: 
sl@0: // This handles a transition notification from a test domain member.
sl@0: TInt CDmTest6::TransitionNotification(MDmDomainMember& aDomainMember)
sl@0: 	{
sl@0: 	TInt status = aDomainMember.Status();
sl@0: 		
sl@0: 	iTestNotifications++;
sl@0: 
sl@0: 	test (aDomainMember.HierarchyId() == KDmHierarchyIdTest);
sl@0: 
sl@0: 	TBuf16<4> buf;
sl@0: 	GetDomainDesc(aDomainMember.Ordinal(), buf);
sl@0: 
sl@0: 	test.Printf(_L("CDmTest6::TransitionNotification(), Hierarchy = %d, domain = %S, iOrdinal = 0x%08X, state = 0x%x, status = %d\n"), 
sl@0: 		aDomainMember.HierarchyId(), &buf, aDomainMember.Ordinal(), aDomainMember.State(), status);
sl@0: 
sl@0: 
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 
sl@0: void CDmTest6::RunL()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	TInt error = iStatus.Int();
sl@0: 
sl@0: 	test.Printf(_L("CDmTest6::RunL(), error = %d, iTestNotifications %d\n"), 
sl@0: 		error, iTestNotifications);
sl@0: 
sl@0: 	if (iTransitionsCompleted == iTransitionsExpected)
sl@0: 		CActiveScheduler::Stop();
sl@0: 	}
sl@0: 
sl@0: void CDmTest6::TransitionRequestComplete()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	TInt error = iStatus.Int();
sl@0: 	
sl@0: 	test.Printf(_L("CDmTest6::TransitionRequestComplete(), error = %d, iTestNotifications %d\n"), 
sl@0: 		error, iTestNotifications);
sl@0: 	
sl@0: 	if (iTransitionsCompleted == iTransitionsExpected)
sl@0: 		CActiveScheduler::Stop();
sl@0: 	}
sl@0: 
sl@0: void CDmTest6::DoCancel()
sl@0: 	{
sl@0: 	test(0);
sl@0: 	}
sl@0: 
sl@0: void CDmTest6::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: // Transition progress Observer testing
sl@0: class CDmTest7 : public CActive, public MDmTest, public MHierarchyObserver
sl@0: 	{
sl@0: public: 
sl@0: 	// from CActive
sl@0: 	void RunL();
sl@0:  
sl@0: 	// from MDmTest
sl@0: 	void Perform();
sl@0: 	void Release();
sl@0: 	TInt TransitionNotification(MDmDomainMember& aDomainMember);
sl@0: 	void TransitionRequestComplete();
sl@0: 
sl@0: 	// from MHierarchyObserver
sl@0: 	virtual void TransProgEvent(TDmDomainId aDomainId, TDmDomainState aState);
sl@0: 	virtual void TransFailEvent(TDmDomainId aDomainId, TDmDomainState aState, TInt aError);
sl@0: 	virtual void TransReqEvent(TDmDomainId aDomainId, TDmDomainState aState);
sl@0: 
sl@0: 
sl@0: 
sl@0: 	CDmTest7(TDmDomainId aDomainId) : CActive(CActive::EPriorityStandard), iObservedDomainId(aDomainId) {}
sl@0: 
sl@0: protected:
sl@0: 	// from CActive
sl@0: 	virtual void DoCancel();
sl@0: 
sl@0: private:
sl@0: 	void TestForCompletion();
sl@0: 
sl@0: 
sl@0: private:
sl@0: 
sl@0: 	enum { KMembersMax = 16 };
sl@0: 
sl@0: 	CDomainMemberAo*	iTestMembers[KMembersMax]; 
sl@0: 	CDomainManagerAo*	iTestDomainManager;
sl@0: 	
sl@0: 	TDmDomainId			iTestDomainId;
sl@0: 	TDmDomainState		iTestState;
sl@0: 	TDmDomainId			iObservedDomainId;
sl@0: 
sl@0: public:
sl@0: 	TInt				iTestNotifications;
sl@0: 	TInt				iTestNotificationsExpected;
sl@0: 
sl@0: 	TInt				iTransitionsCompleted;
sl@0: 	TInt				iTransitionsExpected;
sl@0: 
sl@0: 	TInt				iTransProgEvents;
sl@0: 	TInt				iTransFailEvents;
sl@0: 	TInt				iTransReqEvents;
sl@0: 
sl@0: 	TInt				iTransProgEventsExpected;
sl@0: 	TInt				iTransFailEventsExpected;
sl@0: 	TInt				iTransReqEventsExpected;
sl@0: 	};
sl@0: 
sl@0: //! @SYMTestCaseID PBASE-T_DOMAIN-7
sl@0: //! @SYMTestType CT
sl@0: //! @SYMTestCaseDesc Transition progress Observer testing
sl@0: //! @SYMREQ REQ3723
sl@0: //! @SYMTestActions Various negative tests
sl@0: //! @SYMTestExpectedResults  All tests should pass
sl@0: //! @SYMTestPriority High
sl@0: //! @SYMTestStatus Defined
sl@0: void CDmTest7::Perform()
sl@0: 	{
sl@0: 
sl@0:  	__UHEAP_MARK;
sl@0: 
sl@0: 	//
sl@0: 	// Test domain transitions with activated observer
sl@0: 	//
sl@0: 	CActiveScheduler::Add(this);
sl@0: 
sl@0: 	TInt r = RDmDomainManager::AddDomainHierarchy(KDmHierarchyIdTest);
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	CDomainManagerAo* iTestDomainManager = NULL;
sl@0: 	TRAP_IGNORE(iTestDomainManager = CDomainManagerAo::NewL(KDmHierarchyIdTest, *this));
sl@0: 	test (iTestDomainManager != NULL);
sl@0: 
sl@0: 	r = CDomainManagerAo::AddDomainHierarchy(KDmHierarchyIdTest);
sl@0: 	test(r == KErrNone);
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 7a - Testing observer notifications
sl@0: 	//*************************************************
sl@0: 	
sl@0: 	test.Next(_L("Test 7a - Testing observer notifications"));
sl@0: 
sl@0: 	TInt testMemberCount = 0;
sl@0: 
sl@0: 	// Add some test hierarchy members
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdRoot, ORDINAL_FROM_DOMAINID0(KDmIdRoot), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 1
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestA, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestB, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestC, ORDINAL_FROM_DOMAINID1(KDmIdRoot, KDmIdTestC), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row2
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestAA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestAB, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestA, KDmIdTestAB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestBA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestB, KDmIdTestBA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestCA, ORDINAL_FROM_DOMAINID2(KDmIdRoot, KDmIdTestC, KDmIdTestCA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	
sl@0: 	// row 3
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestABA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestABB, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestA, KDmIdTestAB, KDmIdTestABB), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 	TRAP(r, iTestMembers[testMemberCount] = CDomainMemberAo::NewL(KDmHierarchyIdTest, KDmIdTestCAA, ORDINAL_FROM_DOMAINID3(KDmIdRoot, KDmIdTestC, KDmIdTestCA, KDmIdTestCAA), this));
sl@0: 	test(iTestMembers[testMemberCount++] != NULL);
sl@0: 
sl@0: 	// create an observer
sl@0: 	CHierarchyObserver* observer = NULL;
sl@0: 	TRAP(r, observer = CHierarchyObserver::NewL(*this, KDmHierarchyIdTest));
sl@0: 	test (r == KErrNone);
sl@0: 	test(observer != NULL);
sl@0: 	observer->StartObserver(iObservedDomainId, EDmNotifyAll);
sl@0: 	
sl@0: 	// request a state change
sl@0: 	iTestState =  EStartupCriticalDynamic;
sl@0: 	iTestDomainId = KDmIdRoot;
sl@0: 	iTransitionsCompleted = iTestNotifications = 0;
sl@0: 	iTestNotificationsExpected = testMemberCount;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	iTransProgEvents = iTransFailEvents = iTransReqEvents = 0;
sl@0: 	
sl@0: 	iTransReqEventsExpected = iTransProgEventsExpected = observer->ObserverDomainCount();
sl@0: 	iTransFailEventsExpected = 0;
sl@0: 
sl@0: 
sl@0: 	iTestDomainManager->RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault);
sl@0: 
sl@0: 	// wait for test transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test (iTransProgEvents == iTransProgEventsExpected);
sl@0: 	test (iTransFailEvents == iTransFailEventsExpected);
sl@0: 	test (iTransReqEvents == iTransReqEventsExpected);
sl@0: 
sl@0: 
sl@0: 	// cleanup
sl@0: 	delete observer; 
sl@0: 	observer = NULL;
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 7b - start & stop the observer
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 7b - start & stop the observer"));
sl@0: 
sl@0: 	// create an observer, start it stop and then start it again
sl@0: 	TRAP(r, observer = CHierarchyObserver::NewL(*this, KDmHierarchyIdTest));
sl@0: 	test (r == KErrNone);
sl@0: 	test(observer != NULL);
sl@0: 	observer->StartObserver(iObservedDomainId, EDmNotifyAll);
sl@0: 	observer->StopObserver();
sl@0: 	observer->StartObserver(iObservedDomainId, EDmNotifyAll);
sl@0: 
sl@0: 	// request a state change
sl@0: 	iTestState++;
sl@0: 	iTestDomainId = KDmIdRoot;
sl@0: 	iTransitionsCompleted = iTestNotifications = 0;
sl@0: 	iTestNotificationsExpected = testMemberCount;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	iTransProgEvents = iTransFailEvents = iTransReqEvents = 0;
sl@0: 	
sl@0: 	iTransProgEventsExpected = iTransReqEventsExpected = observer->ObserverDomainCount();
sl@0: 	iTransFailEventsExpected = 0;
sl@0: 
sl@0: 	iTestDomainManager->RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault);
sl@0: 
sl@0: 	// wait for test transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test (iTransProgEvents == iTransProgEventsExpected);
sl@0: 	test (iTransFailEvents == iTransFailEventsExpected);
sl@0: 	test (iTransReqEvents == iTransReqEventsExpected);
sl@0: 
sl@0: 	// stop the observer & request another state change
sl@0: 	observer->StopObserver();
sl@0: 	iTestState++;
sl@0: 	iTestDomainId = KDmIdRoot;
sl@0: 	iTransitionsCompleted = iTestNotifications = 0;
sl@0: 	iTestNotificationsExpected = testMemberCount;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	iTransProgEvents = iTransFailEvents = iTransReqEvents = 0;
sl@0: 	
sl@0: 	iTransProgEventsExpected = 0;
sl@0: 	iTransFailEventsExpected = 0;
sl@0: 	iTransReqEventsExpected = 0;
sl@0: 
sl@0: 	iTestDomainManager->RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault);
sl@0: 	// wait for test transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test (iTransProgEvents == iTransProgEventsExpected);
sl@0: 	test (iTransFailEvents == iTransFailEventsExpected);
sl@0: 	test (iTransReqEvents == iTransReqEventsExpected);
sl@0: 
sl@0: 	// Start the observer again on a different domain and only ask for transition requests
sl@0: 	// Then request another state change
sl@0: 	observer->StartObserver((iObservedDomainId == KDmIdRoot)?KDmIdTestCA:KDmIdRoot, EDmNotifyTransRequest);
sl@0: 	iTestState++;
sl@0: 	iTestDomainId = KDmIdRoot;
sl@0: 	iTransitionsCompleted = iTestNotifications = 0;
sl@0: 	iTestNotificationsExpected = testMemberCount;
sl@0: 	iTransitionsExpected = 1;
sl@0: 
sl@0: 	iTransProgEvents = iTransFailEvents = iTransReqEvents = 0;
sl@0: 	
sl@0: 	iTransReqEventsExpected = observer->ObserverDomainCount();
sl@0: 	iTransProgEventsExpected = 0;
sl@0: 	iTransFailEventsExpected = 0;
sl@0: 
sl@0: 
sl@0: 	iTestDomainManager->RequestDomainTransition(iTestDomainId, iTestState, ETraverseDefault);
sl@0: 	// wait for test transitions to complete
sl@0: 	CActiveScheduler::Start();
sl@0: 	test(iStatus == KErrNone);
sl@0: 	test(iTestNotifications == iTestNotificationsExpected);
sl@0: 	test (iTransProgEvents == iTransProgEventsExpected);
sl@0: 	test (iTransFailEvents == iTransFailEventsExpected);
sl@0: 	test (iTransReqEvents == iTransReqEventsExpected);
sl@0: 
sl@0: 	delete observer; 
sl@0: 	observer = NULL;
sl@0: 
sl@0: 	//*************************************************
sl@0: 	// Test 7c - invalid arguments testing for observer
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 7c - Invalid arguments testing for observer"));
sl@0: 	
sl@0: 	const TDmHierarchyId	KDmHierarchyIdInvalid = 110;
sl@0: 	
sl@0: 	test.Printf(_L("Test 7c.1 - create observer with invalid hierarchy Id\n"));
sl@0: 	
sl@0: 	// create an observer
sl@0: 	TRAP(r, observer = CHierarchyObserver::NewL(*this, KDmHierarchyIdInvalid));
sl@0: 	test (r == KErrBadHierarchyId);
sl@0: 	
sl@0: 	
sl@0: 	test.Printf(_L("Test 7c.2 - Starting the observer with wrong domain Id\n"));
sl@0: 	TRAP(r, observer = CHierarchyObserver::NewL(*this, KDmHierarchyIdTest));
sl@0: 	test (r == KErrNone);
sl@0: 	test(observer != NULL);
sl@0: 
sl@0: 	//Wrong domain Id
sl@0: 	const TDmDomainId	KDmIdInvalid	= 0x0f;
sl@0: 	r= observer->StartObserver(KDmIdInvalid, EDmNotifyAll);
sl@0: 	test(r==KDmErrBadDomainId);
sl@0: 
sl@0: 	test.Printf(_L("Test 7c.3 - Trying to create second observer on the same hierarchy\n"));
sl@0: 	TRAP(r, CHierarchyObserver::NewL(*this, KDmHierarchyIdTest));
sl@0: 	test (r == KDmErrBadSequence);
sl@0: 
sl@0: 	
sl@0: 	
sl@0: 	//*************************************************
sl@0: 	// Test 7d - Wrong sequence of API calls for observer
sl@0: 	//*************************************************
sl@0: 	test.Next(_L("Test 7d - Observer wrong sequence of calls"));
sl@0: 	
sl@0: 	test.Printf(_L("Test 7d.1 - Stopping Observer before starting it\n"));
sl@0: 	r = observer->StopObserver();
sl@0: 	test(r==KDmErrBadSequence);
sl@0: 	
sl@0: 	test.Printf(_L("Test 7d.2 - Starting Observer twice\n"));
sl@0: 	r= observer->StartObserver(KDmIdRoot, EDmNotifyAll);
sl@0: 	test(r==KErrNone);
sl@0: 
sl@0: 	r= observer->StartObserver(KDmIdRoot, EDmNotifyAll);
sl@0: 	test(r==KDmErrBadSequence);
sl@0: 
sl@0: 	
sl@0: 	delete observer;
sl@0: 
sl@0: 	/***************************************/
sl@0: 
sl@0: 	delete iTestDomainManager;
sl@0: 	iTestDomainManager = NULL;
sl@0: 
sl@0: 	CDomainMemberAo** mt;
sl@0: 	for (mt = iTestMembers; *mt; ++mt)
sl@0: 		delete *mt;
sl@0: 
sl@0: 
sl@0: 	// restore the domain hierarchies to their initial state so as not to 
sl@0: 	// upset any subsequent tests which rely on this
sl@0: 	{
sl@0: 	RDmDomainManager manager;
sl@0: 	TRequestStatus status;
sl@0: 	TInt r = manager.Connect(KDmHierarchyIdTest);
sl@0: 	test (r == KErrNone);
sl@0: 	manager.RequestDomainTransition(KDmIdRoot, EStartupCriticalStatic, ETraverseDefault, status);
sl@0: 	test(status.Int() == KRequestPending);
sl@0: 	User::WaitForRequest(status);
sl@0: 	test(status.Int() == KErrNone);
sl@0: 	manager.Close();
sl@0: 	}
sl@0: 
sl@0:  	__UHEAP_MARKEND;
sl@0: 	}
sl@0: 
sl@0: // This handles a transition notification from a test domain member.
sl@0: TInt CDmTest7::TransitionNotification(MDmDomainMember& aDomainMember)
sl@0: 	{
sl@0: 		
sl@0: 	iTestNotifications++;
sl@0: 
sl@0: 	test (aDomainMember.HierarchyId() == KDmHierarchyIdTest);
sl@0: 
sl@0: 	TBuf16<4> buf;
sl@0: 	GetDomainDesc(aDomainMember.Ordinal(), buf);
sl@0: 
sl@0: 	__PRINT((_L("CDmTest7::TransitionNotification(), Hierarchy = %d, domain = %S, iOrdinal = 0x%08X, state = 0x%x, status = %d\n"), 
sl@0: 		aDomainMember.HierarchyId(), &buf, aDomainMember.Ordinal(), aDomainMember.State(), aDomainMember.Status()));
sl@0: 
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 
sl@0: void CDmTest7::RunL()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	__PRINT((_L("CDmTest7::RunL(), error = %d, iTestNotifications %d\n"), 
sl@0: 		iStatus.Int(), iTestNotifications));
sl@0: 
sl@0: 	TestForCompletion();
sl@0: 	}
sl@0: 
sl@0: void CDmTest7::TransitionRequestComplete()
sl@0: 	{
sl@0: 	iTransitionsCompleted++;
sl@0: 
sl@0: 	__PRINT((_L("CDmTest7::TransitionRequestComplete(), error = %d, iTestNotifications %d\n"), 
sl@0: 		iStatus.Int(), iTestNotifications));
sl@0: 	
sl@0: 	TestForCompletion();
sl@0: 	}
sl@0: 
sl@0: void CDmTest7::DoCancel()
sl@0: 	{
sl@0: 	test(0);
sl@0: 	}
sl@0: 
sl@0: void CDmTest7::Release()
sl@0: 	{
sl@0: 	delete this;
sl@0: 	}
sl@0: 
sl@0: void CDmTest7::TestForCompletion()
sl@0: 	{
sl@0: 
sl@0: 	if (iTransitionsCompleted == iTransitionsExpected &&
sl@0: 		iTransProgEvents == iTransProgEventsExpected && 
sl@0: 		iTransFailEvents == iTransFailEventsExpected &&
sl@0: 		iTransReqEvents == iTransReqEventsExpected)
sl@0: 		{
sl@0: 		CActiveScheduler::Stop();
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: void CDmTest7::TransProgEvent(TDmDomainId aDomainId, TDmDomainState aState)
sl@0: #else
sl@0: void CDmTest7::TransProgEvent(TDmDomainId /*aDomainId*/, TDmDomainState /*aState*/)
sl@0: #endif
sl@0: 	{
sl@0: 	iTransProgEvents++;
sl@0: 	__PRINT((_L("CDmTest7::TransProgEvent(), aDomainId = %d, aState %d, iTransProgEvents %d\n"), 
sl@0: 		aDomainId, aState, iTransProgEvents));
sl@0: 	TestForCompletion();
sl@0: 	}
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: void CDmTest7::TransFailEvent(TDmDomainId aDomainId, TDmDomainState aState, TInt aError)
sl@0: #else
sl@0: void CDmTest7::TransFailEvent(TDmDomainId /*aDomainId*/, TDmDomainState /*aState*/, TInt /*aError*/)
sl@0: #endif
sl@0: 
sl@0: 	{
sl@0: 	iTransFailEvents++;
sl@0: 	__PRINT((_L("CDmTest7::TransFailEvent(), aDomainId = %d, aState %d aError %d, iTransFailEvents %d\n"), 
sl@0: 		aDomainId, aState, iTransFailEvents, aError));
sl@0: 	TestForCompletion();
sl@0: 	}
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: void CDmTest7::TransReqEvent(TDmDomainId aDomainId, TDmDomainState aState)
sl@0: #else
sl@0: void CDmTest7::TransReqEvent(TDmDomainId /*aDomainId*/, TDmDomainState /*aState*/)
sl@0: #endif
sl@0: 	{
sl@0: 	iTransReqEvents++;
sl@0: 	__PRINT((_L("CDmTest7::TransReqEvent(), aDomainId = %d, aState %d, iTransReqEvents %d\n"), 
sl@0: 		aDomainId, aState, iTransReqEvents));
sl@0: 	TestForCompletion();
sl@0: 	}
sl@0: 
sl@0: GLDEF_C TInt E32Main()
sl@0: 	{
sl@0: 	CTrapCleanup* trapHandler=CTrapCleanup::New();
sl@0: 	test(trapHandler!=NULL);
sl@0: 
sl@0: 	CActiveScheduler* scheduler = new CActiveScheduler();
sl@0: 	test(scheduler != NULL);
sl@0: 	CActiveScheduler::Install(scheduler);
sl@0: 
sl@0: 	// Turn off evil lazy dll unloading
sl@0: 	RLoader l;
sl@0: 	test(l.Connect()==KErrNone);
sl@0: 	test(l.CancelLazyDllUnload()==KErrNone);
sl@0: 	l.Close();
sl@0: 
sl@0: 	//
sl@0: 	// Perform the number of iterations specifed by the command line argument.
sl@0: 	//
sl@0: 	// If no arguments - perform two iterations
sl@0: 	//
sl@0: //  TInt iter = 2;
sl@0:     TInt iter = 1;
sl@0: 
sl@0: 	TInt len = User::CommandLineLength();
sl@0: 	if (len)
sl@0: 		{
sl@0: 		// Copy the command line in a buffer
sl@0: 		HBufC* hb = HBufC::NewMax(len);
sl@0: 		test(hb != NULL);
sl@0: 		TPtr cmd((TUint16*) hb->Ptr(), len);
sl@0: 		User::CommandLine(cmd);
sl@0: 		// Extract the number of iterations
sl@0: 		TLex l(cmd);
sl@0: 		TInt i;
sl@0: 		TInt r = l.Val(i);
sl@0: 		if (r == KErrNone)
sl@0: 			iter = i;
sl@0: 		else
sl@0: 			// strange command - silently ignore
sl@0: 			{} 
sl@0: 		delete hb;
sl@0: 		}
sl@0: 
sl@0: 	test.Title();
sl@0: 	test.Start(_L("Testing"));
sl@0: 
sl@0: 	test.Printf(_L("Go for %d iterations\n"), iter);
sl@0: 
sl@0: 	// Remember the number of open handles. Just for a sanity check ....
sl@0: 	TInt start_thc, start_phc;
sl@0: 	RThread().HandleCount(start_phc, start_thc);
sl@0: 
sl@0: 	while (iter--)
sl@0: 		{
sl@0: 		MDmTest* tests[] = 
sl@0: 			{
sl@0: 
sl@0: 			new CDmTest1(KDmIdRoot, EPwStandby),
sl@0: 			new CDmTest1(KDmIdRoot, EPwOff),
sl@0: 			new CDmTest1(KDmIdRoot, EPwActive),
sl@0: 			new CDmTest1(KDmIdApps, EPwStandby),
sl@0: 			new CDmTest1(KDmIdApps, EPwOff),
sl@0: 			new CDmTest1(KDmIdApps, EPwActive),
sl@0: 			new CDmTest1(KDmIdUiApps, EPwStandby),
sl@0: 			new CDmTest1(KDmIdUiApps, EPwOff),
sl@0: 			new CDmTest1(KDmIdUiApps, EPwActive),
sl@0: 			new CDmTest2(EPwStandby),
sl@0: 			new CDmTest3(),
sl@0: 	
sl@0: 			// platform security tests
sl@0: 			new CDmTest4(),
sl@0: 
sl@0: 			// PREQ810 tests :
sl@0: 			// note that we use a fictitious power state to prevent any 
sl@0: 			new CDmTest5(KDmIdRoot, KDmIdRoot, EPwActive+10, EStartupCriticalDynamic),
sl@0: 			new CDmTest5(KDmIdUiApps, KDmIdTestAB, EPwActive+10, EStartupCriticalDynamic),
sl@0: 
sl@0:         // negative tests
sl@0: 			new CDmTest6(),
sl@0: 
sl@0: 
sl@0: 			// observer tests
sl@0:      		new CDmTest7(KDmIdTestA),
sl@0: 			new CDmTest7(KDmIdRoot),
sl@0: 			
sl@0: 			};
sl@0: 
sl@0: 		for (unsigned int i = 0; i < sizeof(tests)/sizeof(*tests); ++i)
sl@0: 			{
sl@0: 			test(tests[i] != NULL);
sl@0: 			tests[i]->Perform();
sl@0: 			tests[i]->Release();
sl@0: 			}
sl@0: 
sl@0: 		}
sl@0: 
sl@0: 	test.End();
sl@0: 
sl@0: 	// Sanity check for open handles and for pending requests ...
sl@0: 	TInt end_thc, end_phc;
sl@0: 	RThread().HandleCount(end_phc, end_thc);
sl@0: 	test(start_thc == end_thc);
sl@0: 	test(start_phc == end_phc);
sl@0: 	test(RThread().RequestCount() >= 0);
sl@0: 
sl@0: 	delete scheduler;
sl@0: 	delete trapHandler;
sl@0: 
sl@0: 	return KErrNone;
sl@0: 	}