Revision: 201018
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 03 May 2010 13:56:28 +0300
changeset 15 c1e808730d6c
parent 13 efebd1779a59
child 16 eedf2dcd43c6
child 18 72dc595b34a8
child 26 c36d67f77f75
Revision: 201018 Kit: 201018
devsound/a3fdevsound/bwins/mmfdevsoundadaptor.def
devsound/a3fdevsound/eabi/mmfdevsoundadaptor.def
devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp
devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.h
devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.cpp
devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.h
devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp
devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.h
devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp
devsound/a3fdevsound/src/devsoundadaptor/cdevrecordcontrol.cpp
devsound/a3fdevsound/src/devsoundadaptor/cdevtonecontrol.cpp
devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.cpp
devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.h
devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.cpp
devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.h
devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.cpp
devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.h
devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundcallbackhandler.cpp
devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundproxy.cpp
devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp
devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.h
devsoundextensions/effectspresets/StereoWideningUtility/group/bld.inf
devsoundextensions/effectspresets/rom/EffectsPresets.iby
imagingandcamerafws/camerafw/Include/ecamimageprocessing.h
imagingandcamerafws/imagingfws/GifScaler/src/NQColorQuantizer.cpp
imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/scripts/TSU_ICL_COD_03.script
imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.cpp
imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.h
imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestSuite.cpp
mdfdevvideoextensions/nga_mdf_postprocessor/data/nga_mdf_postprocessor_stub.pkg
mdfdevvideoextensions/nga_mdf_postprocessor/data/nga_mdf_postprocessor_stub.sis
mdfdevvideoextensions/nga_mdf_postprocessor/inc/NGAPostProcHwDevice.h
mdfdevvideoextensions/nga_mdf_postprocessor/src/NGAPostProcHwDevice.cpp
mm_pub/drm_audio_player_api/tsrc/data/mmc/drm/test3gp.dcf
mm_pub/drm_audio_player_api/tsrc/data/mmc/drm/testmp3.dcf
mmlibs/mmfw/MMPFiles/client/MediaClientVideo.mmp
mmlibs/mmfw/MMPFiles/client/mediaclientvideodisplay.mmp
mmlibs/mmfw/Recogniser/src/constants.h
mmlibs/mmfw/Recogniser/src/mpeg4parser.cpp
mmlibs/mmfw/src/Client/Video/VideoPlayerBody.h
mmlibs/mmfw/src/Client/Video/mediaclientextdisplayhandler.cpp
mmlibs/mmfw/src/Client/Video/mediaclientpolicyserverclient.cpp
mmlibs/mmfw/src/Client/Video/mediaclientpolicyserverclient.h
mmlibs/mmfw/src/Client/Video/mediaclientpolicyserversession.cpp
mmlibs/mmfw/src/Client/Video/mediaclientpolicyserversession.h
mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp
mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.h
mmlibs/mmfw/src/Client/Video/mediaclientvideotrace.h
mmlibs/mmfw/src/Client/Video/mediaclientwseventobserver.cpp
mmlibs/mmfw/src/Client/Video/mediaclientwseventobserver.h
mmlibs/mmfw/src/Client/Video/mmfclientvideoplayerbody.cpp
mmlibs/mmfw/src/Plugin/Codec/audio/GSM610/101F504A.rss
mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmffile.cpp
mmlibs/mmfw/src/server/BaseClasses/Mmfformat.cpp
mmlibs/mmfw/tsrc/mmfintegrationtest/vclntavi/src/testvideoplayer2.cpp
mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.cpp
mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.h
mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/testsetvol.h
mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/src/TSU_MMF_DEVSOUND_STEP.cpp
mmlibs/mmfw/tsrc/mmfunittest/MmpFiles/TSU_MMF_VCLNT_01.mmp
mmlibs/mmfw/tsrc/mmfunittest/group/BLD.INF
mmplugins/imagingplugins/codecs/GifCodec/GIFcodec.cpp
mmplugins/imagingplugins/codecs/JPEGCodec/JPEGCodec.cpp
mmplugins/imagingplugins/codecs/JPEGCodec/JPGQUANT.CPP
mmplugins/imagingplugins/codecs/PNGCodec/PngScanlineDecoder.cpp
mmplugins/imagingplugins/codecs/TIFFCodec/TIFFCodec.cpp
mmplugins/imagingplugins/codecs/TIFFCodec/TIFFFax.cpp
mmplugins/lib3gp/impl/inc/mp4file.h
mmplugins/lib3gp/impl/src/file.cpp
mmplugins/lib3gp/impl/src/mp4compose.cpp
mmplugins/lib3gp/impl/src/mp4parse.cpp
mmplugins/lib3gp/wrapper/src/c3gpparse.cpp
mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggPlayController/oggdecode.h
mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggRecordController/OggEncode.h
mmplugins/mmfwplugins/src/Plugin/Format/MmfWAVFormat/mmfwavformat.cpp
mmtestenv/mmtestfw/MMPFiles/TestFrameworkClient.mmp
mmtestenv/mmtestfw/Source/TestFrameworkClient/Log.cpp
mmtestenv/mmtestfw/Source/TestFrameworkClient/TestStep.cpp
mmtestenv/mmtestfw/Source/TestFrameworkClient/testfwclientsession.cpp
mmtestenv/mmtestfw/bwins/TESTFRAMEWORKCLIENTU.DEF
mmtestenv/mmtestfw/eabi/TestFrameworkClientU.DEF
mmtestenv/mmtestfw/include/TestFramework.h
mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth10.mmp
mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth11.mmp
mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth12.mmp
mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth13.mmp
mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth10U.DEF
mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth11U.DEF
mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth12U.DEF
omxil/omxilcomponentcommon/bwins/omxilcomponentcommon.def
omxil/omxilcomponentcommon/eabi/omxilcomponentcommon.def
omxil/omxilcomponentcommon/src/common/omxilcallbackmanager.h
omxil/omxilcore/src/omxilcoreclient/omxilcoreclientsession.cpp
--- a/devsound/a3fdevsound/bwins/mmfdevsoundadaptor.def	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/bwins/mmfdevsoundadaptor.def	Mon May 03 13:56:28 2010 +0300
@@ -55,4 +55,5 @@
 	?Resume@CMMFDevSoundAdaptation@@QAEHXZ @ 54 NONAME ; int CMMFDevSoundAdaptation::Resume(void)
 	?BufferErrorEvent@CMMFDevSoundAdaptation@@QAEXXZ @ 55 NONAME ; void CMMFDevSoundAdaptation::BufferErrorEvent(void)
 	?ProcessingError@CMMFDevSoundAdaptation@@QAEHAAH@Z @ 56 NONAME ; int CMMFDevSoundAdaptation::ProcessingError(int &)
+	?RollbackAdaptorActiveStateToBeforeCommit@CMMFDevSoundAdaptation@@QAEXXZ @ 57 NONAME ; void CMMFDevSoundAdaptation::RollbackAdaptorActiveStateToBeforeCommit(void)
 
--- a/devsound/a3fdevsound/eabi/mmfdevsoundadaptor.def	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/eabi/mmfdevsoundadaptor.def	Mon May 03 13:56:28 2010 +0300
@@ -62,4 +62,5 @@
 	_ZN22CMMFDevSoundAdaptation6ResumeEv @ 61 NONAME
 	_ZN22CMMFDevSoundAdaptation16BufferErrorEventEv @ 62 NONAME
 	_ZN22CMMFDevSoundAdaptation15ProcessingErrorERi @ 63 NONAME
+	_ZN22CMMFDevSoundAdaptation40RollbackAdaptorActiveStateToBeforeCommitEv @ 64 NONAME
 
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp	Mon May 03 13:56:28 2010 +0300
@@ -349,7 +349,8 @@
 
 	if(iActiveState != EDevSoundAdaptorCreated_Uninitialised &&
 		iActiveState != EDevSoundAdaptorInitialised_Initialised && 
-		iActiveState != EDevSoundAdaptorInitialised_Idle)
+		iActiveState != EDevSoundAdaptorInitialised_Idle &&
+		iActiveState != EDevSoundAdaptorUnitialised_Uninitialised )
 		{
 		DP0_RET(KErrNotReady, "%d");
 		}
@@ -366,8 +367,11 @@
 			err = iAudioStream->Unload();
 			if(err == KErrNone)
 				{
+				err = CommitAudioContext();
+				}
+			if(err == KErrNone)
+				{
 				iActiveState = EDevSoundAdaptorUnloading;
-				err = iAudioContext->Commit();
 				}
 			}
 		else
@@ -377,6 +381,15 @@
 		DP0_RET(err, "%d");
 		}
 
+	// Redo partial initialization after pre-emption clash event in
+	// EDevSoundAdaptorRemovingProcessingUnits state
+	if (iActiveState == EDevSoundAdaptorUnitialised_Uninitialised &&
+			iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
+		{
+		err = iCurrentAudioControl->RemoveProcessingUnits();
+		DP0_RET(err, "%d");
+		}
+
 	// Delete pUnits if already created
 	if (iAudioSource)
 		{
@@ -486,6 +499,15 @@
 		{
 		DP0_RET(KErrNotReady, "%d");
 		}
+
+	// Redo partial cancelling of initialization after pre-emption clash event in
+	// EDevSoundAdaptorRemovingProcessingUnits state.
+	if (iActiveState == EDevSoundAdaptorUnitialised_Uninitialised &&
+			iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
+		{
+		err = iCurrentAudioControl->RemoveProcessingUnits();
+		DP0_RET(err, "%d");
+		}
 			
 	err = iCurrentAudioControl->Uninitialize();
 	
@@ -574,6 +596,40 @@
 	DP0_RET(iActiveState, "%d");
 	}
 
+// -----------------------------------------------------------------------------
+// CDevAudio::ActiveState
+// -----------------------------------------------------------------------------
+//
+TDevSoundAdaptorState CDevAudio::PreviousState() const
+	{
+	DP_CONTEXT(CDevAudio::PreviousState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP0_RET(iPreviousState, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetActiveState
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::SetActiveState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::SetActiveState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iActiveState = aAdaptorState;
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetPreviousState
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::SetPreviousState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::SetPreviousState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iPreviousState = aAdaptorState;
+	DP_OUT();
+	}
 
 // -----------------------------------------------------------------------------
 // CDevAudio::SetDevSoundVolume
@@ -911,6 +967,34 @@
 	DP_OUT();
 	}
 
+TInt CDevAudio::CommitAudioContext()
+	{
+	DP_CONTEXT(CDevAudio::CommitAudioContext *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	//If we are in mid state then Panic as DevSound server-side session (CMMFDevSoundSession) is not blocking properly
+	__ASSERT_DEBUG(!IsMidState(iActiveState), Panic(EValidStateBeforeCommit));
+
+	TInt err = KErrNone;
+	iPreviousState = iActiveState;
+	err = iAudioContext->Commit();
+
+	DP0_RET(err,"%d");
+	}
+
+TBool CDevAudio::IsMidState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::IsMidState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	if (aAdaptorState == EDevSoundAdaptorRemovingProcessingUnits || aAdaptorState == EDevSoundAdaptorUninitialising ||
+			aAdaptorState == EDevSoundAdaptorInitialising || aAdaptorState == EDevSoundAdaptorLoading ||
+			aAdaptorState == EDevSoundAdaptorUnloading || aAdaptorState == EDevSoundAdaptorStopping ||
+			aAdaptorState == EDevSoundAdaptorActivating || aAdaptorState == EDevSoundAdaptorPausing)
+		{
+		DP0_RET(ETrue,"%d");
+		}
+	DP0_RET(EFalse,"%d");
+	}
 
 // -----------------------------------------------------------------------------
 // From MA3FDevSoundAutoPauseResume
@@ -979,5 +1063,9 @@
 	DP_OUT();
 	}
 
+void CDevAudio::Panic(TMMFDevAudioPanicCodes aCode)
+	{
+	User::Panic(KMMFDevAudioPanicCategory, aCode);
+	}
 
 // End of file
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.h	Mon May 03 13:56:28 2010 +0300
@@ -43,6 +43,15 @@
 class MAudioStream;
 class MGlobalProperties;
 
+/**
+Panic category and codes that CDevAudio raises on the client
+*/
+_LIT(KMMFDevAudioPanicCategory, "CDevAudio");
+
+enum TMMFDevAudioPanicCodes
+	{
+	EValidStateBeforeCommit =1
+	};
 
 enum TDevSoundAdaptorState
 	{
@@ -148,6 +157,24 @@
 	TDevSoundAdaptorState ActiveState() const;
 
 	/**
+	* Retrieve the previous DevSound adaptor state
+	* @return void
+	*/
+	TDevSoundAdaptorState PreviousState() const;
+
+	/**
+	* Set the current DevSound adaptor state
+	* @return void
+	*/
+	void SetActiveState(TDevSoundAdaptorState aAdaptorState);
+
+	/**
+	* Set the previous DevSound adaptor state
+	* @return void
+	*/
+	void SetPreviousState(TDevSoundAdaptorState aAdaptorState);
+
+	/**
 	* SetVolume for DevSound
 	*/
 	TInt SetDevSoundVolume(TInt aVolume, TBool& aAsyncCompletion);
@@ -247,6 +274,9 @@
 	
 	TBool IsPrioritySet();
 	
+	//Panic function
+	void Panic(TMMFDevAudioPanicCodes aCode);
+
 protected:
 
 	CDevAudio(MDevSoundAdaptationObserver& aAdaptationObserver);
@@ -258,6 +288,9 @@
 	TInt CreateAudioProcessingUnits(TUid aSource, TUid aSink, TUid aCodec);
 	void DeleteAudioProcessingUnits();
 
+	TInt CommitAudioContext();
+	TBool IsMidState(TDevSoundAdaptorState aAdaptorState);
+
 /*
 * most of member data is protected for DevAudioControl access
 */
@@ -322,6 +355,11 @@
 	*/
 	TDevSoundAdaptorState iActiveState;
 
+	/**
+	* Previous DevSound Adaptor state
+	*/
+	TDevSoundAdaptorState iPreviousState;
+
 	TAudioState		iActiveStreamState;
 
 	TBool 	iReinitializing;
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.cpp	Mon May 03 13:56:28 2010 +0300
@@ -179,8 +179,11 @@
 
 	if (err == KErrNone)
 		{
+		err = iDevAudio->CommitAudioContext();
+		}
+	if (err == KErrNone)
+		{
 		iDevAudio->iActiveState = EDevSoundAdaptorUninitialising;
-		err = iDevAudio->iAudioContext->Commit();
 		}
 
 	DP0_RET(err,"%d");
@@ -198,7 +201,7 @@
 	TInt err = iDevAudio->iAudioStream->Unload();
 	if (err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		}
 	if (err == KErrNone)
 		{
@@ -332,7 +335,7 @@
 	
 	if(err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		if (err == KErrNone)
 			{
 			iDesiredMode = mode;
@@ -489,7 +492,7 @@
 		// It means we're here due to RequestGainAndBalance call
 		if(err == KErrNone && !aBecomingActive)
 			{
-			err = iDevAudio->iAudioContext->Commit();
+			err = iDevAudio->CommitAudioContext();
 			}		
 		}
 	DP0_RET(err,"%d");
@@ -546,7 +549,7 @@
 			err = iDevAudio->iAudioStream->Stop();
 			if(err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
@@ -559,7 +562,7 @@
 			err = iDevAudio->iAudioStream->Unload();
 			if(err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();	
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
@@ -572,7 +575,7 @@
 			err = iDevAudio->iAudioStream->Uninitialize();
 			if(err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
@@ -582,6 +585,16 @@
 			break;
 		case EDevSoundAdaptorCreated_Uninitialised:
 			readyToDestroy = ETrue;
+			break;
+		case EDevSoundAdaptorUnitialised_Uninitialised:
+			//If following condition is true, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
+			if(iDevAudio->iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
+				{
+				err = RemoveProcessingUnits();
+				break;
+				}
 		default:
 			break;
 		}
@@ -621,7 +634,7 @@
 
 	if (err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		}
 		
 	if(err == KErrNone)
@@ -847,8 +860,12 @@
 			{
 			iCurrentSampleRate = iDesiredSampleRate;
 			}
-		iDesiredSampleRate = 0;
 		}
+	else
+	    {
+        iAdaptationObserver->NotifyError(aError);
+	    }
+    iDesiredSampleRate = 0;
 	}
 
 // -----------------------------------------------------------------------------
@@ -864,8 +881,12 @@
 			{
 			iCurrentMode = iDesiredMode;
 			}
-		iDesiredMode = KNullUid;
 		}
+    else
+        {
+        iAdaptationObserver->NotifyError(aError);
+        }
+    iDesiredMode = KNullUid;
 	}
 
 // -----------------------------------------------------------------------------
@@ -935,6 +956,11 @@
 	DP_CONTEXT(CDevAudioControl::ContextEvent *CD1*, CtxDevSound, DPLOCAL);
 	DP_IN();
 
+    if(!(iAdaptationObserver->AdaptorControlsContext()))
+        {
+        iIgnoreAsyncOpComplete = ETrue;
+        }
+    
 	if (aEvent == KUidA3FContextUpdateComplete)
 		{
 	    if(iIgnoreAsyncOpComplete)
@@ -947,18 +973,15 @@
             iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
            	}
 		}
-	else if(aEvent == KUidA3FContextPreEmption || aEvent == KUidA3FContextPreEmptedCommit)
+	else if(aEvent == KUidA3FContextPreEmption)
 		{
-		
-		//Preemption during the below states should complete invoke AsynOperationComplete
-		if(iDevAudio->iActiveState!=EDevSoundAdaptorActivating && iDevAudio->iActiveState!=EDevSoundAdaptorLoading && 
-			iDevAudio->iActiveState!=EDevSoundAdaptorStopping && iDevAudio->iActiveState!=EDevSoundAdaptorUnloading
-			 && iDevAudio->iActiveState!=EDevSoundAdaptorPausing)
-			{
-			iIgnoreAsyncOpComplete = ETrue;
-			iAdaptationObserver->PreemptionStartedCallbackReceived();
-			}
+		//If we are in a normal pre-emption cycle, we should not be in a mid-state.
+		__ASSERT_DEBUG(!iDevAudio->IsMidState(iDevAudio->iActiveState), Panic(EInvalidStateDuringPreemptionCycle));
+		iIgnoreAsyncOpComplete = ETrue;
+		iAdaptationObserver->PreemptionStartedCallbackReceived();
 		}
+	//In a clashing pre-emption cycle we must be in a commit cycle, so do nothing here - CDevCommonControl deals
+	//with this case.
 	DP_OUT();
 	}
 
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevaudiocontrol.h	Mon May 03 13:56:28 2010 +0300
@@ -45,7 +45,8 @@
 	EStreamBeingDemotedToEIdle,
 	EAudioCodecIsNull,
 	EStreamMismatch,
-	EBufferMismatch
+	EBufferMismatch,
+	EInvalidStateDuringPreemptionCycle
 	};
 
 
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp	Mon May 03 13:56:28 2010 +0300
@@ -48,7 +48,7 @@
             err = iDevAudio->iAudioStream->Stop();
             if (err == KErrNone)
                 {
-                err = iDevAudio->iAudioContext->Commit();
+                err = iDevAudio->CommitAudioContext();
                 }
             if (err == KErrNone)
                 {
@@ -58,6 +58,17 @@
         case EDevSoundAdaptorGoingActive:
             iDevAudio->iActiveState = EDevSoundAdaptorStopping;
             break;
+        case EDevSoundAdaptorInitialised_Idle:
+        	{
+        	//If following condition is true, then we are here because of a
+        	//pre-emption clash in last Commit cycle started from
+        	//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
+        	if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
+        		{
+				err = Unload();
+				break;
+        		}
+        	}
         default:
             break;
         }
@@ -79,7 +90,7 @@
     TInt err = iDevAudio->iAudioStream->Prime();
     if ( err == KErrNone)
         {
-        err = iDevAudio->iAudioContext->Commit();
+        err = iDevAudio->CommitAudioContext();
         }
     if (err == KErrNone)
         {
@@ -101,13 +112,28 @@
         err = KErrNotReady;
         }
 
+    //If following condition is true, then we are here because of a
+    //pre-emption clash in last Commit cycle started from
+    //CDevCommonControl::ContextEventUpdateWithStateEventAndError.
+    if(iDevAudio->iActiveState == EDevSoundAdaptorInitialised_Idle &&
+    		iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
+    	{
+		err = Unload();
+		DP0_RET(err,"%d");
+    	}
+
+    if(err == KErrNone)
+        {
+        // Populate gain and balance values set in the Paused state and being cached
+        err = iDevAudio->RequestGainAndBalance(this);
+        }
     if(err == KErrNone)
         {
         err = iDevAudio->iAudioStream->Activate();
         }
     if ( err == KErrNone)
         {
-        err = iDevAudio->iAudioContext->Commit();
+        err = iDevAudio->CommitAudioContext();
         }
     if (err == KErrNone)
         {
@@ -182,12 +208,26 @@
     // Can't "switch {...}" on UIDs unfortunately:
     if (aEvent == KUidA3FContextUpdateComplete)
         {
-        if(iBeingPreempted && iStateEventReceived)
+        if(iBeingPreempted)
             {
-            //use a sub state pattern to make premtion cycles like other cycles.
-            DP1(DLERR,"Preemption error=%d", aError);
-            iDevAudio->iActiveState = EDevSoundAdaptorBeingPreempted;
-            iBeingPreempted=EFalse;
+			if(iStateEventReceived)
+				{
+				//use a sub state pattern to make pre-emption cycles like other cycles.
+				DP1(DLERR,"Preemption error=%d", aError);
+				iDevAudio->iActiveState = EDevSoundAdaptorBeingPreempted;
+				if(iPreemptionClash)
+					{
+					// remove last request from front of queue without processing it
+					iAdaptationObserver->PreemptionClashWithStateChange();
+					iPreemptionClash=EFalse;
+					}
+				}
+            else if(!iStateEventReceived && iPreemptionClash)
+        		{
+				iIgnoreAsyncOpComplete=ETrue;
+				iPreemptionClash=EFalse;
+        		}
+			iBeingPreempted=EFalse;
             }
 		ContextEventUpdateComplete(aError);
         }
@@ -195,16 +235,18 @@
     else if ((aEvent == KUidA3FContextCommitUpdate))
         {
         iBeingPreempted=EFalse; // clear being preempted
+        iPreemptionClash=EFalse; // clear pre-emption clash flag
         TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
         iIgnoreAsyncOpComplete = !adaptorControlsContext;
             // if we don't control context, always send a PreemptionFinishedCallbackReceived()
 		iStateEventReceived=EFalse;
         }
 
-    else if ((aEvent == KUidA3FContextPreEmption) or (aEvent == KUidA3FContextPreEmptedCommit))
+    else if (aEvent == KUidA3FContextPreEmption)
         {
         // clear iBeingPreepted - will be set in ContextEventPreEmption if req
         iBeingPreempted=EFalse;
+        iPreemptionClash=EFalse; // clear pre-emption clash flag
         TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
 		iStateEventReceived=EFalse;
         iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete
@@ -214,6 +256,26 @@
             iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete
             }
         }
+    else if (aEvent == KUidA3FContextPreEmptedCommit)
+        {
+		DP0(DLINFO,"KUidA3FContextPreEmptedCommit event received, thus clash with Pre-emption");
+        // clear iBeingPreepted - will be set in ContextEventPreEmption if req
+        iBeingPreempted=EFalse;
+        TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
+        if (adaptorControlsContext)
+        	{
+			// push current request that was being processed onto front of queue.
+        	iAdaptationObserver->PreemptionClash();
+        	iPreemptionClash=ETrue;
+        	}
+		iStateEventReceived=EFalse;
+        iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete
+        ContextEventPreEmption(aEvent, aError);
+        if (!adaptorControlsContext)
+            {
+            iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete
+            }
+        }
 
     else if (aEvent == KUidA3FContextAbort)
         {
@@ -426,7 +488,7 @@
         return;
         }
     
-    err = iDevAudio->iAudioContext->Commit();
+    err = iDevAudio->CommitAudioContext();
     if (err)
         {
         ContextEventAsynchronousPlayCompletion(err);
@@ -564,6 +626,18 @@
         return;
         }
 
+    //If the Commit cycle when going into EDevSoundAdaptorRemovingProcessingUnits fails due to pre-emption
+    //clash then we re-apply the client request again.
+    if (iDevAudio->iActiveState == EDevSoundAdaptorRemovingProcessingUnits && iIgnoreAsyncOpComplete)
+    	{
+		//Pop front of queue to re-apply the request again via CMMFDevSoundSession::DequeueRequest
+		//from the callback into CMMFDevSoundSession below:
+		iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
+		iIgnoreAsyncOpComplete = EFalse;
+		DP_OUT();
+		return;
+    	}
+
     iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised;
     
     if (iDevAudio->iReinitializing)
@@ -592,29 +666,78 @@
     {
     DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithoutStateEventButWithError, CtxDevSound, DPLOCAL);
     DP_IN();
-    
-    // NOTE: We shouldn't actually be in any of the states below when calling this function.
-    //       But just in case we are we will rewind the state before dealing with the error. 
-    switch (iDevAudio->iActiveState)
-        {
-    case EDevSoundAdaptorInitialising:
-        iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised;
-        ContextEventAsynchronousInitializeComplete(aError);
-        break;
-        
-    case EDevSoundAdaptorLoading:
-        iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
-        ContextEventAsynchronousPlayCompletion(aError);
-        break;
-        
-    case EDevSoundAdaptorActivating:
-        iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Idle;
-        ContextEventAsynchronousPlayCompletion(aError);
-        break;
-        
-    default:
-        break;
-        }
+
+    //If flag is true below then it must be due to a stateless normal pre-emption or
+    //stateless pre-emption clash scenario.
+    if(iIgnoreAsyncOpComplete)
+    	{
+		//If we are in pre-emption clash then callback below will retry the client request again.
+		iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); // notify client of end of cycle
+		iIgnoreAsyncOpComplete = EFalse;
+    	}
+    else
+    	{
+        TDevSoundAdaptorState previousState = iDevAudio->iPreviousState;
+
+        DP3(DLINFO,"Error with no state change, state %d, previous %d, error %d during Commit cycle",
+                    iDevAudio->iActiveState, previousState, aError);
+
+        // We can end up here for a number of reasons. For non "mid states", this is
+        // a standard error scenario. For some mid-states (e.g. Activating, Loading etc),
+        // when we try and "promote" the state, this happens when the promotion is rejected
+        // and we handle thus accordingly. For other mid-states the situation is less clear
+        // and we call AsynchronousOperationComplete() with the error assuming the parent
+        // session will deal with it. Whatever we don't want to stay in a mid-state, so
+        // rewind to the previous ("normal") one if we are in one.
+
+        // Longer term TODO. If the code were refactored so that the InitializeComplete(),
+        // PlayError() etc callback came from AsynchronousOperationComplete() then the
+        // following code might be simpler. Most of the time (at least) we get here because
+        // we are doing a session function, and we can use the function to determine what
+        // to do more easily than relying on the state. As it is, for some mid-states we
+        // try and work out what error code to generate. Not clear this covers 100% cases,
+        // although demotion transitions should not fail, so the problem cases might not occur.
+        //
+
+		//If we reach this condition then it is because of rejection/error during Commit cycle.
+		switch (iDevAudio->iActiveState)
+			{
+			case EDevSoundAdaptorInitialising:
+				{
+				iDevAudio->iActiveState = previousState;
+				ContextEventAsynchronousInitializeComplete(aError);
+				break;
+				}
+			case EDevSoundAdaptorLoading:
+				{
+				iDevAudio->iActiveState = previousState;
+				ContextEventAsynchronousPlayCompletion(aError);
+				break;
+				}
+			case EDevSoundAdaptorActivating:
+				{
+				iDevAudio->iActiveState = previousState;
+				ContextEventAsynchronousPlayCompletion(aError);
+				break;
+				}
+			case EDevSoundAdaptorRemovingProcessingUnits:
+			case EDevSoundAdaptorUninitialising:
+			case EDevSoundAdaptorUnloading:
+			case EDevSoundAdaptorStopping:
+			case EDevSoundAdaptorPausing:
+			    {
+                DP2(DLINFO,"Unexpected mid state [%d] when handling error [%d] during Commit cycle, workback", iDevAudio->iActiveState, aError);
+			    iDevAudio->iActiveState = previousState;
+                iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
+			    break;
+			    }
+			default:
+				{
+				DP2(DLINFO,"Unexpected state [%d] when handling error [%d] during Commit cycle", iDevAudio->iActiveState, aError);
+		        iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
+				}
+			}
+    	}
        
     DP_OUT();
     }
@@ -710,12 +833,15 @@
     
     iCallbackFromAdaptor = KCallbackNone;
     
-    if(iIgnoreAsyncOpComplete==EFalse)
+    if(!iIgnoreAsyncOpComplete)
         {
         iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
         }
-    
-    iIgnoreAsyncOpComplete=EFalse;
+    else
+        {
+        iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
+        iIgnoreAsyncOpComplete=EFalse;
+        }
     
     DP_OUT();
     }
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.h	Mon May 03 13:56:28 2010 +0300
@@ -80,6 +80,7 @@
     
 private:
     TBool iBeingPreempted;
+    TBool iPreemptionClash;
 	};
 
 #endif // CDEVCOMMONCONTROL_H
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp	Mon May 03 13:56:28 2010 +0300
@@ -143,7 +143,7 @@
 			err = iDevAudio->iAudioStream->Initialize();
 			if (err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				if (err == KErrNone)
 					{
 					iDevAudio->iActiveState = EDevSoundAdaptorInitialising;
@@ -195,7 +195,7 @@
 				}
 			if ( err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if(err == KErrNone)
 				{
@@ -204,8 +204,29 @@
 			}
 			break;
 
+		case EDevSoundAdaptorGoingActive:
+			{
+			//If following condition is false, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
+			if(iDevAudio->iPreviousState != EDevSoundAdaptorActivating)
+				{
+				break;
+				}
+			//Fall through as required
+			}
 		case EDevSoundAdaptorPaused_Primed:
 		case EDevSoundAdaptorInitialised_Idle:
+			{
+			//If following condition is true, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventAndError.
+			if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
+				{
+				err = Unload();
+				break;
+				}
+
 			err = iDevAudio->RequestGainAndBalance(this);
 			if (err==KErrNone)
 				{
@@ -213,13 +234,14 @@
 				}
 			if (err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
 				iDevAudio->iActiveState = EDevSoundAdaptorActivating;
 				}
 			break;
+			}
 		case EDevSoundAdaptorActive_Active:
 			// Deliberate fall through - set err=KErrNotReady for PlayInit when already active
 		default:
@@ -323,7 +345,7 @@
 	TInt err = iDevAudio->iAudioStream->Stop();
 	if ( err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		if(err == KErrNone)
 			{
 			iDevAudio->iActiveState = EDevSoundAdaptorStopping;
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevrecordcontrol.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevrecordcontrol.cpp	Mon May 03 13:56:28 2010 +0300
@@ -143,7 +143,7 @@
 			err = iDevAudio->iAudioStream->Initialize();
 			if (err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				if (err == KErrNone)
 					{
 					iDevAudio->iActiveState = EDevSoundAdaptorInitialising;
@@ -195,7 +195,7 @@
 				}
 			if ( err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if(err == KErrNone)
 				{
@@ -204,8 +204,28 @@
 			}
 			break;
 
+		case EDevSoundAdaptorGoingActive:
+			{
+			//If following condition is false, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
+			if(iDevAudio->iPreviousState != EDevSoundAdaptorActivating)
+				{
+				break;
+				}
+			//Fall through as required
+			}
 		case EDevSoundAdaptorPaused_Primed:
 		case EDevSoundAdaptorInitialised_Idle:
+			{
+			//If following condition is true, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventAndError.
+			if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
+				{
+				err = Unload();
+				break;
+				}
 			err = iDevAudio->RequestGainAndBalance(this);
 			if (err==KErrNone)
 				{
@@ -213,14 +233,14 @@
 				}
 			if (err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
 				iDevAudio->iActiveState = EDevSoundAdaptorActivating;
 				}
 			break;
-
+			}
 		default:
 			err = KErrNotReady;
 			break;
@@ -338,7 +358,7 @@
     TInt err = iDevAudio->iAudioStream->Stop();
     if ( err == KErrNone)
         {
-        err = iDevAudio->iAudioContext->Commit();
+        err = iDevAudio->CommitAudioContext();
         if(err == KErrNone)
             {
             iDevAudio->iActiveState = EDevSoundAdaptorStopping;
--- a/devsound/a3fdevsound/src/devsoundadaptor/cdevtonecontrol.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevtonecontrol.cpp	Mon May 03 13:56:28 2010 +0300
@@ -156,7 +156,7 @@
 	err = iDevAudio->iAudioStream->Initialize();
 	if (err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		}
 	if (err == KErrNone)
 		{
@@ -195,7 +195,7 @@
 				}
 			if ( err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if(err == KErrNone)
 				{
@@ -204,8 +204,28 @@
 			}
 			break;
 
+		case EDevSoundAdaptorGoingActive:
+			{
+			//If following condition is false, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
+			if(iDevAudio->iPreviousState != EDevSoundAdaptorActivating)
+				{
+				break;
+				}
+			//Fall through as required
+			}
 		case EDevSoundAdaptorPaused_Primed:
 		case EDevSoundAdaptorInitialised_Idle:
+			{
+			//If following condition is true, then we are here because of a
+			//pre-emption clash in last Commit cycle started from
+			//CDevCommonControl::ContextEventUpdateWithStateEventAndError.
+			if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
+				{
+				err = Unload();
+				break;
+				}
 			DP0(DLINFO, "Already in loaded state");
 			err = iDevAudio->RequestGainAndBalance(this);
 			if (err==KErrNone)
@@ -214,13 +234,14 @@
 				}
 			if (err == KErrNone)
 				{
-				err = iDevAudio->iAudioContext->Commit();
+				err = iDevAudio->CommitAudioContext();
 				}
 			if (err == KErrNone)
 				{
 				iDevAudio->iActiveState = EDevSoundAdaptorActivating;
 				}
 			break;
+			}
 		case EDevSoundAdaptorActive_Active:
 		default:
 			err = KErrNotReady;
@@ -339,7 +360,7 @@
 	TInt err = iDevAudio->iAudioStream->Stop();
 	if ( err == KErrNone)
 		{
-		err = iDevAudio->iAudioContext->Commit();
+		err = iDevAudio->CommitAudioContext();
 		if(err == KErrNone)
 			{
 			iDevAudio->iActiveState = EDevSoundAdaptorStopping;
--- a/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.cpp	Mon May 03 13:56:28 2010 +0300
@@ -923,5 +923,13 @@
 	{
 	iBody->BufferErrorEvent();
 	}
+
+EXPORT_C void CMMFDevSoundAdaptation::RollbackAdaptorActiveStateToBeforeCommit()
+	{
+	DP_CONTEXT(CMMFDevSoundAdaptation::RollbackAdaptorActiveStateToBeforeCommit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iBody->RollbackAdaptorActiveStateToBeforeCommit();
+	DP_OUT();
+	}
 	
 // End of file
--- a/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptation.h	Mon May 03 13:56:28 2010 +0300
@@ -229,6 +229,27 @@
 	 */
 	virtual TBool AdaptorControlsContext() const = 0;
 
+	/*
+	 * Callback indicating that a clash with pre-emption has occurred during the commit cycle
+	 * and to push the current request that was being processed onto front of queue.
+	 */
+
+	virtual void PreemptionClash() = 0;
+
+	/*
+	 * Callback indicating the clash with pre-emption during the commit cycle was with state change,
+	 * so the current request that was previously pushed onto the front of queue should be removed
+	 * without processing.
+	 */
+
+	virtual void PreemptionClashWithStateChange() = 0;
+
+	/*
+	 * Callback to indicate an error has been noticed. This is to be cached until subsequent
+	 * AsynchronousOperationComplete(), and handled then if needs.
+	 */
+	virtual void NotifyError(TInt aError) = 0;
+
 	};
 
 
@@ -883,6 +904,12 @@
 	*/
 	IMPORT_C void BufferErrorEvent();
 	
+	/**
+	* Used rollback the adapror active state to the previous state prior a Commit call
+	* @return void
+	*/
+	IMPORT_C void RollbackAdaptorActiveStateToBeforeCommit();
+
 protected:
 
 	// So that nobody can extend
--- a/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1243,3 +1243,15 @@
 	ASSERT(iDevAudio);
 	iDevAudio->GetAudioControl()->BufferErrorEvent();
 	}
+
+void CMMFDevSoundAdaptation::CBody::RollbackAdaptorActiveStateToBeforeCommit()
+	{
+	DP_CONTEXT(CMMFDevSoundAdaptation::CBody::RollbackAdaptorActiveStateToBeforeCommit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TDevSoundAdaptorState previousState = iDevAudio->PreviousState();
+	// Set previous state to the active state set after state changing Commit call
+	iDevAudio->SetPreviousState(iDevAudio->ActiveState());
+	// Set active state to the previous state set before state changing Commit call
+	iDevAudio->SetActiveState(previousState);
+	DP_OUT();
+	}
--- a/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/devsoundadaptor/mmfdevsoundadaptationbody.h	Mon May 03 13:56:28 2010 +0300
@@ -665,6 +665,12 @@
 	*/
 	void BufferErrorEvent();
 
+	/**
+	* Used rollback the adapror active state to the previous state prior a Commit call
+	* @return void
+	*/
+	void RollbackAdaptorActiveStateToBeforeCommit();
+
 private:
 
 	CBody(MDevSoundAdaptationObserver& aDevSoundObserver,
--- a/devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.cpp	Mon May 03 13:56:28 2010 +0300
@@ -29,6 +29,25 @@
 const TInt KInitialTime = 100000;  //100ms
 const TInt KTimeIncrement = 50000; // 50ms 
 
+_LIT_SECURITY_POLICY_C1(KServerHasDRMRights, ECapabilityDRM);
+
+// -----------------------------------------------------------------------------
+// RMMFAudioServerProxy::OpenSessionToTrustedAudioServer
+//
+// -----------------------------------------------------------------------------
+//	
+TInt RMMFAudioServerProxy::OpenSessionToTrustedAudioServer()
+	{
+	return CreateSession(KAudioServerName,
+                                TVersion(KMMFAudioServerVersion,
+                                KMMFAudioServerMinorVersionNumber,
+                                KMMFAudioServerBuildVersionNumber),
+                                -1, // Global pool
+                                EIpcSession_Unsharable,
+                                &KServerHasDRMRights,
+                                NULL); // NULL required for synchronous behaviour
+	}	
+
 // -----------------------------------------------------------------------------
 // RMMFAudioServerProxy::Open
 //
@@ -38,12 +57,8 @@
 	{
 	const TUidType serverUid(KNullUid,KNullUid,KUidAudioServer);
 	// Assume the server is already running and attempt to create a session
-	// 4 message slots
-	TInt err = CreateSession(KAudioServerName,
-								TVersion(KMMFAudioServerVersion,
-								KMMFAudioServerMinorVersionNumber,
-								KMMFAudioServerBuildVersionNumber));
-
+	TInt err = OpenSessionToTrustedAudioServer();
+	
 	if(err == KErrNotFound)
 		{
 		// Server not running
@@ -92,9 +107,8 @@
 				{
 				User::After(waitTime);
 				waitTime+=KTimeIncrement;
-				err = CreateSession(KAudioServerName, TVersion(KMMFAudioServerVersion,
-														KMMFAudioServerMinorVersionNumber,
-														KMMFAudioServerBuildVersionNumber));
+				err = OpenSessionToTrustedAudioServer();				
+				
 				if(err==KErrNone)
 					{
 					//Session created successfully
@@ -105,10 +119,7 @@
 		else
 			{
 			// Create the root server session
-			err = CreateSession(KAudioServerName,
-							TVersion(KMMFAudioServerVersion,
-									KMMFAudioServerMinorVersionNumber,
-									KMMFAudioServerBuildVersionNumber));
+            err = OpenSessionToTrustedAudioServer();
 			}
 		}
 	return err;
--- a/devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfaudioserverproxy/mmfaudioserverproxy.h	Mon May 03 13:56:28 2010 +0300
@@ -68,6 +68,10 @@
 	* @return TInt handle to the DevSound server.
 	*/
 	IMPORT_C TInt GetDevSoundSessionHandle();
+	
+private:
+
+	TInt OpenSessionToTrustedAudioServer();
 	};
 
 #endif      // MMFAUDIOSERVERPROXY_H
--- a/devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundcallbackhandler.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundcallbackhandler.cpp	Mon May 03 13:56:28 2010 +0300
@@ -18,7 +18,17 @@
 // INCLUDE FILES
 #include "mmfdevsoundproxy.h"
 #include "mmfdevsoundcallbackhandler.h"
+#ifdef _DEBUG
+#include <e32debug.h>
 
+#define SYMBIAN_DEBPRN0(str)                RDebug::Print(str, this)
+#define SYMBIAN_DEBPRN1(str, val1)          RDebug::Print(str, this, val1)
+#define SYMBIAN_DEBPRN2(str, val1, val2)    RDebug::Print(str, this, val1, val2)
+#else
+#define SYMBIAN_DEBPRN0(str)
+#define SYMBIAN_DEBPRN1(str, val1)
+#define SYMBIAN_DEBPRN2(str, val1, val2)
+#endif //_DEBUG
 
 // ============================ MEMBER FUNCTIONS ==============================
 
@@ -101,11 +111,13 @@
 //
 void CMsgQueueHandler::ReceiveEvents()
 	{
-	if (!IsActive())
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::ReceiveEvents - Enter"));	
+    if (!IsActive())
 		{
 		iMsgQueue->NotifyDataAvailable(iStatus);
 		SetActive();
 		}
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::ReceiveEvents - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -116,7 +128,8 @@
 //
 void CMsgQueueHandler::RunL()
 	{
-	TInt err = iMsgQueue->Receive(iCurrentItem);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunL - Enter"));
+    TInt err = iMsgQueue->Receive(iCurrentItem);
 
 	if (err == KErrNone || err == KErrUnderflow)
 		{
@@ -205,6 +218,7 @@
 				}
 			}
 		}
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunL - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -214,9 +228,11 @@
 //
 TInt CMsgQueueHandler::RunError(TInt aError)
 	{
-	TMMFEvent event;
+    SYMBIAN_DEBPRN1(_L("CMsgQueueHandler[0x%x]::RunError - Enter. Error [%d]"), aError);
+    TMMFEvent event;
 	event.iErrorCode = aError;
 	iDevSoundObserver.SendEventToClient(event);
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunError - Exit"));
 	return KErrNone;
 	}
 
@@ -228,7 +244,9 @@
 //
 void CMsgQueueHandler::DoCancel()
 	{
-	iMsgQueue->CancelDataAvailable();
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoCancel - Enter"));
+    iMsgQueue->CancelDataAvailable();
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoCancel - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -238,7 +256,9 @@
 //
 void CMsgQueueHandler::DoInitComplete()
 	{
-	iDevSoundObserver.InitializeComplete(iCurrentItem.iErrorCode);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoInitComplete - Enter"));
+    iDevSoundObserver.InitializeComplete(iCurrentItem.iErrorCode);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoInitComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -248,8 +268,10 @@
 //
 void CMsgQueueHandler::DoPlayErrorComplete()
 	{
-	iAsyncQueueFinish->CallBack(); // async call to Finish()
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPlayErrorComplete - Enter"));
+    iAsyncQueueFinish->CallBack(); // async call to Finish()
 	iDevSoundObserver.PlayError(iCurrentItem.iErrorCode);
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPlayErrorComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -260,7 +282,8 @@
 //
 void CMsgQueueHandler::DoBTBFCompleteL()
 	{
-	// Returns either chunk handle or NULL
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBFCompleteL - Enter"));
+    // Returns either chunk handle or NULL
 	// any error is assumed to be due to a pending PlayError(), so the error here is ignored - the PlayError() call will ensure the client remains lively
 	// the chunk has been closed by the server. No action should be taken.
 	TBool requestChunk = iDataBuffer==NULL; // if we have no buffer, tell server we need a chunk handle
@@ -281,6 +304,7 @@
 		
 		iDevSoundObserver.BufferToBeFilled(iDataBuffer);
 		}
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBFCompleteL - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -291,7 +315,8 @@
 //
 void CMsgQueueHandler::DoBTBECompleteL()
 	{
-	// Returns either chunk handle or NULL
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBECompleteL - Enter"));
+    // Returns either chunk handle or NULL
 	// any error is assumed to be due to a pending RecordError(), so the error here is ignored - the RecordError() call will ensure the client remains lively
 	// the chunk has been closed by the server. No action should be taken.
 	TInt handle = iDevSoundProxy->BufferToBeEmptiedData(iSetPckg);
@@ -305,6 +330,7 @@
 		iDataBuffer->Data().SetLength(iSetPckg().iRequestSize);
 		iDevSoundObserver.BufferToBeEmptied(iDataBuffer);
 		}
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBECompleteL - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -314,8 +340,10 @@
 //
 void CMsgQueueHandler::DoRecordErrorComplete()
 	{
-	iAsyncQueueFinish->CallBack(); // async call to Finish()
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoRecordErrorComplete - Enter"));
+    iAsyncQueueFinish->CallBack(); // async call to Finish()
 	iDevSoundObserver.RecordError(iCurrentItem.iErrorCode);
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoRecordErrorComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -325,7 +353,9 @@
 //
 void CMsgQueueHandler::DoToneFinishedComplete()
 	{
-	iDevSoundObserver.ToneFinished(iCurrentItem.iErrorCode);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoToneFinishedComplete - Enter"));
+    iDevSoundObserver.ToneFinished(iCurrentItem.iErrorCode);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoToneFinishedComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -335,7 +365,9 @@
 //
 void CMsgQueueHandler::DoSendEventToClientComplete()
 	{
-	iDevSoundObserver.SendEventToClient(iCurrentItem.iEventPckg());
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoSendEventToClientComplete - Enter"));
+    iDevSoundObserver.SendEventToClient(iCurrentItem.iEventPckg());
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoSendEventToClientComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -346,9 +378,11 @@
 //
 void CMsgQueueHandler::DoPausedRecordComplete()
 	{
-	ASSERT(iEmptyBuffer);
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPausedRecordComplete - Enter"));
+    ASSERT(iEmptyBuffer);
 	iEmptyBuffer->SetLastBuffer(ETrue);
 	iDevSoundObserver.BufferToBeEmptied(iEmptyBuffer);
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPausedRecordComplete - Exit"));
 	}
 
 // ----------------------------------------------------------------------------
@@ -358,7 +392,8 @@
 //
 void CMsgQueueHandler::AssignDataBufferToChunkL(TInt aHandle)
 	{
-	if ( iChunk.Handle() )
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::AssignDataBufferToChunkL - Enter"));
+    if ( iChunk.Handle() )
 		{
 		iChunk.Close();
 		}
@@ -374,20 +409,24 @@
 		{
 		iDataBuffer = CMMFPtrBuffer::NewL();	
 		}
-	UpdateDataBufferL(); 
+	UpdateDataBufferL();
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::AssignDataBufferToChunkL - Exit"));
 	}
 	
 void CMsgQueueHandler::UpdateDataBufferL()
 	{
-	ASSERT(iDataBuffer); // to get here, we should have a data buffer
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::UpdateDataBufferL - Enter"));
+    ASSERT(iDataBuffer); // to get here, we should have a data buffer
 	iDataBuffer->SetPtr(iChunkDataPtr);
 	iDataBuffer->SetRequestSizeL(iSetPckg().iRequestSize);
-	iDataBuffer->SetLastBuffer(EFalse);	
+	iDataBuffer->SetLastBuffer(EFalse);
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::UpdateDataBufferL - Exit"));
 	}
 	
 void CMsgQueueHandler::Finish()
 	{
-	if (iDataBuffer)
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::Finish - Enter"));
+    if (iDataBuffer)
 		{
 		delete iDataBuffer;
 		iDataBuffer = NULL;
@@ -396,6 +435,7 @@
 		{
 		iChunk.Close();
 		}
+	SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::Finish - Exit"));
 	}
 
 // 	AsyncQueueStartCallback
@@ -403,14 +443,16 @@
 
 TInt CMsgQueueHandler::AsyncQueueFinishCallback(TAny* aPtr)
 	{
-	CMsgQueueHandler* self = static_cast<CMsgQueueHandler*>(aPtr);
+    CMsgQueueHandler* self = static_cast<CMsgQueueHandler*>(aPtr);
 	self->DoAsyncQueueFinishCallback();
 	return KErrNone;
 	}
 	
 void CMsgQueueHandler::DoAsyncQueueFinishCallback()
 	{
-	Finish();
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoAsyncQueueFinishCallback - Enter"));
+    Finish();
+    SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoAsyncQueueFinishCallback - Exit"));
 	}
 
 
--- a/devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundproxy.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfdevsoundproxy/mmfdevsoundproxy.cpp	Mon May 03 13:56:28 2010 +0300
@@ -127,7 +127,7 @@
 EXPORT_C TInt RMMFDevSoundProxy::Open()
 	{
 	SYMBIAN_DEBPRN0(_L("RMMFDevSoundProxy[0x%x]::Open - Enter"));
-	TInt err = iMsgQueue.CreateGlobal(KNullDesC, KMaxMessageQueueItems);
+	TInt err = iMsgQueue.CreateGlobal(KNullDesC, KMaxMessageQueueItems, EOwnerThread);
 	// global, accessible to all that have its handle
 	
 	if (err == KErrNone)
--- a/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp	Mon May 03 13:56:28 2010 +0300
@@ -26,15 +26,15 @@
 #define SYMBIAN_DEBPRN0(str)                RDebug::Print(str, this)
 #define SYMBIAN_DEBPRN1(str, val1)          RDebug::Print(str, this, val1)
 #define SYMBIAN_DEBPRN2(str, val1, val2)    RDebug::Print(str, this, val1, val2)
+#define SYMBIAN_DEBPRN3(str, val1, val2, val3)    RDebug::Print(str, this, val1, val2, val3)
 #else
 #define SYMBIAN_DEBPRN0(str)
 #define SYMBIAN_DEBPRN1(str, val1)
 #define SYMBIAN_DEBPRN2(str, val1, val2)
+#define SYMBIAN_DEBPRN3(str, val1, val2, val3)
 #endif //_DEBUG
 
-//Assume that we can have two user request and one callback request
-//at the same time (maximum).
-const TInt KMaxQueueRequest = 3;
+const TInt KMaxQueueRequest = 6;
 
 //	MEMBER FUNCTIONS 
 
@@ -222,14 +222,23 @@
 	}
 
 //
+// NeedToQueue - mid-commit cycle or async queue start AO is active
+//
+TBool CMMFDevSoundSession::NeedToQueue() const
+    {
+    return iOperationCompletePending || iAsyncQueueStart->IsActive();
+    }
+
+//
 // CMMFDevSoundSession::ServiceL
 // (other items were commented in a header).
 //
 void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage)
 	{
 	SYMBIAN_DEBPRN2(_L("\nCMMFDevSoundSession[0x%x] NEW REQUEST %02x while pending=%d"),
-	        aMessage.Function(), iOperationCompletePending || iAsyncQueueStart->IsActive());
-	if( iOperationCompletePending || iAsyncQueueStart->IsActive())
+	        aMessage.Function(), NeedToQueue());
+	
+	if(NeedToQueue())
 		{
 		// if not possible to service now, then queue request
 		EnqueueRequest(aMessage);
@@ -256,12 +265,17 @@
 //
 void CMMFDevSoundSession::DoServiceRequestL(const RMmfIpcMessage& aMessage)
 	{
+	iRequestBeingServiced.SetMessage(aMessage);
 	iAsyncQueueStart->Cancel(); // just in case.
-	TMMFMessageDestinationPckg destinationPckg;
+    ResetNotifiedError();
+
+    TMMFMessageDestinationPckg destinationPckg;
 	MmfMessageUtil::ReadL(aMessage, 0, destinationPckg);
+	SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - DestinationHandle [%d] InterfaceId [%d] "), destinationPckg().DestinationHandle(), destinationPckg().InterfaceId());
 	if ((destinationPckg().DestinationHandle() == KMMFObjectHandleDevSound) &&
 	    (destinationPckg().InterfaceId() == KUidInterfaceMMFDevSound))
 		{
+        SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - Request [%d]"), aMessage.Function());
 		TBool complete = EFalse;
 		switch(aMessage.Function())
 			{
@@ -437,23 +451,37 @@
 			// Complete the message
 			// Synchronous requests & Pseudo-asynchronous
 			aMessage.Complete(KErrNone);
-			}
-		// Note: There are operations that not complete the message using the following flag
-		// So if the message is not completed, cannot be assumed that there is an operation pending
-		
-		if(iOperationCompletePending)
-			{
-			// Keep a copy of the message for Asynchronous requests & Pseudo-asynchronous
-			iRequestBeingServiced.SetMessage(aMessage);
+
+			// Store function if we need to re-apply it again due to pre-emption clash
+			if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous)
+				{
+				iRedoFunction = aMessage.Function();
+				}
 			}
 		}
+	else if (aMessage.Function() == RMessage2::EDisConnect)
+	    {
+        TBool complete = iAdapter->CloseDevSound();
+        if(!complete)
+            {
+            iRequestBeingServiced.SetMessage(aMessage);
+            iOperationCompletePending = ETrue;
+            ResetNotifiedError();
+            }
+        else
+            {
+            // if we get here, iClosing wait will have been started and we'd be waiting
+            iClosingWait->AsyncStop();
+            }
+	    }
 	else
 		{
 		// If there's a CI extension, see if that handles this request
 		TInt err = KErrNotSupported;
 		if (iCIExtension)
 			{
-			iOperationCompletePending = ETrue;
+            SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest [%d]"), aMessage.Function());
+            iOperationCompletePending = ETrue;
 			iHandlingExtdCI = ETrue;
 			TRAPD(err2, err = iCIExtension->HandleMessageL(aMessage));
 			if (err2)
@@ -462,6 +490,7 @@
 				}
 			iOperationCompletePending = EFalse;
 			iHandlingExtdCI = EFalse;
+			SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest[%d] - Exit with Error[%d] "), aMessage.Function(),err);
 			}
 
 		if (err != KErrNone)
@@ -472,6 +501,80 @@
 		}
 	}
 
+void CMMFDevSoundSession::DoServiceAlreadyCompletedRequestL(const TInt aFunction)
+	{
+    ResetNotifiedError();
+
+	switch(aFunction)
+		{
+		case EMMFDevSoundProxyInitialize1:
+			DoAlreadyCompletedInitialize1L();
+			break;
+		case EMMFDevSoundProxyInitialize2:
+			DoAlreadyCompletedInitialize2L();
+			break;
+		case EMMFDevSoundProxyInitialize4:
+			DoAlreadyCompletedInitialize4L();
+			break;
+		case EMMFDevSoundProxyPlayInit:
+			DoAlreadyCompletedPlayInitL();
+			break;
+		case EMMFDevSoundProxyRecordInit:
+			DoAlreadyCompletedRecordInitL();
+			break;
+		case EMMFDevSoundProxyPlayTone:
+			DoAlreadyCompletedPlayToneL();
+			break;
+		case EMMFDevSoundProxyPlayDualTone:
+			DoAlreadyCompletedPlayDualToneL();
+			break;
+		case EMMFDevSoundProxyPlayDTMFString:
+			DoAlreadyCompletedPlayDTMFStringL();
+			break;
+		case EMMFDevSoundProxyPlayToneSequence:
+			DoAlreadyCompletedPlayToneSequenceL();
+			break;
+		case EMMFDevSoundProxyPlayFixedSequence:
+			DoAlreadyCompletedPlayFixedSequenceL();
+			break;
+		default:
+			User::Leave(KErrNotSupported);
+			break;
+		}
+
+	}
+
+void CMMFDevSoundSession::HandleAlreadyCompletedRequest()
+	{
+	TRAPD(err,DoServiceAlreadyCompletedRequestL(iRedoFunction));
+
+	if (err != KErrNone)
+		{
+		switch(iRedoFunction)
+			{
+			case EMMFDevSoundProxyInitialize1:
+			case EMMFDevSoundProxyInitialize2:
+			case EMMFDevSoundProxyInitialize4:
+				InitializeComplete(err);
+				break;
+			case EMMFDevSoundProxyPlayInit:
+				PlayError(err);
+				break;
+			case EMMFDevSoundProxyRecordInit:
+				RecordError(err);
+				break;
+			case EMMFDevSoundProxyPlayTone:
+			case EMMFDevSoundProxyPlayDualTone:
+			case EMMFDevSoundProxyPlayDTMFString:
+			case EMMFDevSoundProxyPlayToneSequence:
+			case EMMFDevSoundProxyPlayFixedSequence:
+				ToneFinished(err);
+				break;
+			default:
+				break;
+			}
+		}
+	}
 
 void CMMFDevSoundSession::EnqueueRequest(const RMmfIpcMessage& aMessage)
 	{
@@ -499,11 +602,13 @@
 //
 TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage)
 	{
-	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+    iMsgQueue.Close(); // close if already open
+	TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread
 	User::LeaveIfError(err);
 	DoSetClientConfigL();// added here instead of the CreateL()
 	TMMFDevSoundProxySettingsPckg devSoundBuf;
 	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
+	iCachedClientData = devSoundBuf;
 	TMMFState mode = devSoundBuf().iMode;
 	iAdapter->InitializeL(mode);
 	iBufferPlay = NULL;
@@ -515,16 +620,32 @@
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedInitialize1L
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedInitialize1L()
+	{
+	TMMFState mode = iCachedClientData().iMode;
+	iAdapter->InitializeL(mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	// Flag to queue any further request
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoInitialize2L
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage)
 	{
-	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+    iMsgQueue.Close(); // close if already open
+	TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread
 	User::LeaveIfError(err);
 	DoSetClientConfigL();// added here instead of the CreateL()
 	TMMFDevSoundProxySettingsPckg devSoundBuf;
 	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
+	iCachedClientData = devSoundBuf;
 	TUid HWDev = devSoundBuf().iHWDev;
 	TMMFState mode = devSoundBuf().iMode;
 	iAdapter->InitializeL(HWDev, mode);
@@ -534,16 +655,31 @@
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedInitialize2L
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedInitialize2L()
+	{
+	TUid HWDev = iCachedClientData().iHWDev;
+	TMMFState mode = iCachedClientData().iMode;
+	iAdapter->InitializeL(HWDev, mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	}
+
+//
 // CMMFDevSoundSession::DoInitialize4L
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage)
 	{
-	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+    iMsgQueue.Close();
+	TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread
 	User::LeaveIfError(err);
 	DoSetClientConfigL();// added here instead of the CreateL()
 	TMMFDevSoundProxySettingsPckg devSoundBuf;
 	aMessage.ReadL(TInt(1),devSoundBuf);
+	iCachedClientData = devSoundBuf;
 	TFourCC desiredFourCC = devSoundBuf().iDesiredFourCC;
 	TMMFState mode = devSoundBuf().iMode;
 	iAdapter->InitializeL(desiredFourCC, mode);
@@ -556,6 +692,21 @@
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedInitialize4L
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedInitialize4L()
+	{
+	TFourCC desiredFourCC = iCachedClientData().iDesiredFourCC;
+	TMMFState mode = iCachedClientData().iMode;
+	iAdapter->InitializeL(desiredFourCC, mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	// Flag to queue any further request
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoCancelInitialize
 // (other items were commented in a header).
 //
@@ -774,6 +925,16 @@
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayInitL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayInitL()
+	{
+	iAdapter->PlayInitL();
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoRecordInitL
 // (other items were commented in a header).
 //
@@ -785,6 +946,16 @@
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedRecordInitL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedRecordInitL()
+	{
+	iAdapter->RecordInitL();
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoPlayDataL
 // (other items were commented in a header).
 //
@@ -826,7 +997,8 @@
 //
 TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/)
 	{
-	// Sometimes Stop is not involved on a commit cycle
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoStopL - Enter"));
+    // Sometimes Stop is not involved on a commit cycle
 	TBool completed = iAdapter->Stop();
 	if (completed)
 		{
@@ -835,6 +1007,7 @@
 		iChunk.Close();
 		}
 	iOperationCompletePending = !completed;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoStopL - Exit. Return value is [%d]"), completed);
 	return completed;
 	}
 
@@ -855,38 +1028,70 @@
 //
 TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage)
 	{
-	TMMFDevSoundProxySettingsPckg devSoundBuf;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Enter"));
+    TMMFDevSoundProxySettingsPckg devSoundBuf;
 	aMessage.ReadL(TInt(1),devSoundBuf);
+	iCachedClientData = devSoundBuf;
 	TInt frequency = devSoundBuf().iFrequencyOne;
 	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
 	iAdapter->PlayToneL(frequency, duration);
 	iOperationCompletePending = ETrue;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayToneL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayToneL()
+	{
+	TInt frequency = iCachedClientData().iFrequencyOne;
+	TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration);
+	iAdapter->PlayToneL(frequency, duration);
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoPlayDualToneL
 // (other items were commented in a header).	
 //
 TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage)
 	{
-	TMMFDevSoundProxySettingsPckg devSoundBuf;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Enter"));
+    TMMFDevSoundProxySettingsPckg devSoundBuf;
 	aMessage.ReadL(TInt(1),devSoundBuf);
+	iCachedClientData = devSoundBuf;
 	TInt frequencyOne = devSoundBuf().iFrequencyOne;
 	TInt frequencyTwo = devSoundBuf().iFrequencyTwo;
 	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
 	iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration);
 	iOperationCompletePending = ETrue;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL()
+	{
+	TInt frequencyOne = iCachedClientData().iFrequencyOne;
+	TInt frequencyTwo = iCachedClientData().iFrequencyTwo;
+	TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration);
+	iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration);
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoPlayDTMFStringL
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage)
 	{
-	TInt dtmfLength = aMessage.GetDesLength(2);
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Enter"));
+    TInt dtmfLength = aMessage.GetDesLength(2);
 	
 	if(iDtmfString)
 		{
@@ -900,16 +1105,28 @@
 
 	iAdapter->PlayDTMFStringL(*iDtmfString);
 	iOperationCompletePending = ETrue;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL()
+	{
+	iAdapter->PlayDTMFStringL(*iDtmfString);
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoPlayToneSequenceL
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage)
 	{
-	TInt toneLength = aMessage.GetDesLength(1);
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Enter"));
+    TInt toneLength = aMessage.GetDesLength(1);
 
 	if(iToneSeqBuf)
 		{
@@ -923,36 +1140,61 @@
 
 	iAdapter->PlayToneSequenceL(*iToneSeqBuf);
 	iOperationCompletePending = ETrue;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL()
+	{
+	iAdapter->PlayToneSequenceL(*iToneSeqBuf);
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoPlayFixedSequenceL
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage)
 	{
-	TPckgBuf<TInt> buf;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Enter"));
+    TPckgBuf<TInt> buf;
 	aMessage.ReadL(TInt(1),buf);
 	TInt seqNum = buf();
-
+	iSeqNum = seqNum;
 	iAdapter->PlayFixedSequenceL(seqNum);
 	iOperationCompletePending = ETrue;
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
 //
+// CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL()
+	{
+	iAdapter->PlayFixedSequenceL(iSeqNum);
+	iOperationCompletePending = ETrue;
+	}
+
+//
 // CMMFDevSoundSession::DoSetDTMFLengthsL
 // (other items were commented in a header).
 //
 TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage)
 	{
-	TMMFDevSoundProxySettingsPckg devSoundBuf;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Enter"));
+    TMMFDevSoundProxySettingsPckg devSoundBuf;
 	aMessage.ReadL(TInt(1),devSoundBuf);
 	TTimeIntervalMicroSeconds32 toneOnLength = devSoundBuf().iToneOnLength;
 	TTimeIntervalMicroSeconds32 toneOffLength = devSoundBuf().iToneOffLength;
 	TTimeIntervalMicroSeconds32 pauseLength = devSoundBuf().iPauseLength;
 	User::LeaveIfError(iAdapter->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength));
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
@@ -962,11 +1204,13 @@
 //
 TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage)
 	{
-	TMMFDevSoundProxySettingsPckg devSoundBuf;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Enter"));
+    TMMFDevSoundProxySettingsPckg devSoundBuf;
 	aMessage.ReadL(TInt(1),devSoundBuf);
 	TTimeIntervalMicroSeconds duration = devSoundBuf().iDuration;
 	User::LeaveIfError(iAdapter->SetVolumeRamp(duration));
 	iOperationCompletePending = EFalse; // Volume ramp doesn't result on commit
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Exit. Return value is [%d]"), ETrue);
 	return ETrue; // operation complete
 	}
 
@@ -1044,13 +1288,14 @@
 //
 TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage)
 	{
-	TPckgBuf<TInt> countRepeat;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Enter"));
+    TPckgBuf<TInt> countRepeat;
 	aMessage.ReadL(TInt(1),countRepeat);
 
 	TPckgBuf<TTimeIntervalMicroSeconds> repeatTS;
 	aMessage.ReadL(TInt(2),repeatTS);
 	User::LeaveIfError(iAdapter->SetToneRepeats(countRepeat(), repeatTS()));
-	
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
@@ -1076,11 +1321,13 @@
 TBool CMMFDevSoundSession::DoFixedSequenceCountL(
 					const RMmfIpcMessage& aMessage)
 	{
-	TPckgBuf<TInt> fixSeqCountPckg;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Enter"));
+    TPckgBuf<TInt> fixSeqCountPckg;
 	TInt fixSeqCount = iAdapter->FixedSequenceCount();
 	fixSeqCountPckg = fixSeqCount;
 
 	aMessage.WriteL(TInt(2),fixSeqCountPckg);
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Exit. Return value is [%d]"), ETrue);
 	return ETrue;
 	}
 
@@ -1339,7 +1586,8 @@
 //
 void CMMFDevSoundSession::FlushEventQueue()
 	{
-	if(iMsgQueue.Handle() != 0)
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Enter"));
+    if(iMsgQueue.Handle() != 0)
 		{
 		TMMFDevSoundQueueItem queueItem;
 		TInt err = KErrNone;
@@ -1347,12 +1595,14 @@
 			{
 			err = iMsgQueue.Receive(queueItem);
 			}
-		}	
+		}
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Exit"));
 	}
 
 void CMMFDevSoundSession::FilterQueueEvent(TMMFDevSoundProxyRequest aRequest)
 	{
-	if(iMsgQueue.Handle() != 0)
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Enter"));
+    if(iMsgQueue.Handle() != 0)
 		{
 		// Pop and push events result at the queue 
 		// can be seen as "circular list"
@@ -1380,6 +1630,7 @@
 				}
 			}
 		}
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Exit"));
 	}
 
 //
@@ -1388,14 +1639,28 @@
 //
 void CMMFDevSoundSession::Disconnect(const RMessage2& aMessage)
 	{
-	TBool complete = iAdapter->CloseDevSound();
-	if(!complete)
-		{
-		iRequestBeingServiced.SetMessage(aMessage);
-		iOperationCompletePending = ETrue;
-		iClosingWait->Start();
-		}
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Enter"));
+    if (NeedToQueue())
+        {
+        // if we are in the middle of something, enqueue and wait
+        SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Add to queue"));
+        EnqueueRequest(aMessage);
+        iClosingWait->Start();
+        }
+    else
+        {
+        // else do now. Enter ActiveSchedulerWait to wait for AsyncOpComplete
+        TBool complete = iAdapter->CloseDevSound();
+        if(!complete)
+            {
+            iRequestBeingServiced.SetMessage(aMessage);
+            iOperationCompletePending = ETrue;
+            ResetNotifiedError();
+            iClosingWait->Start();
+            }
+        }
 	CSession2::Disconnect(aMessage);
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Exit"));
 	}
 
 
@@ -1507,11 +1772,13 @@
 //
 void CMMFDevSoundSession::ToneFinished(TInt aError)
 	{
-	TMMFDevSoundQueueItem item;
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Enter. Error [%d]"), aError);
+    TMMFDevSoundQueueItem item;
 	item.iRequest = EMMFDevSoundProxyTFEvent;
 	item.iErrorCode = aError;
 	// assumes sufficient space in the queue so ignores the return value
 	iMsgQueue.Send(item);
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Exit"));
 	}
 
 //
@@ -1553,7 +1820,7 @@
 //
 void CMMFDevSoundSession::PlayError(TInt aError)
 	{
-	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError [%d]"), aError);
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError - Enter [%d]"), aError);
 
 	// Set play error flag to ignore following PlayData requests
 	iPlayErrorOccured = ETrue;
@@ -1564,6 +1831,7 @@
 	iChunk.Close();
 	// assumes sufficient space in the queue so ignores the return value
 	iMsgQueue.Send(item);
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PlayError - Exit"));
 	}
 
 //
@@ -1647,7 +1915,7 @@
 //
 void CMMFDevSoundSession::CallbackFromAdaptorReceived(TInt aType, TInt aError)
 	{
-	
+    SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Enter. Type[%d] Error[%d]"), aType, aError);
 	if(aType == KCallbackRecordPauseComplete)
 		{
 		TMMFDevSoundQueueItem item;
@@ -1666,12 +1934,17 @@
 		}
 	else if (aType == KCallbackFlushComplete)
 		{
-		iRequestBeingServiced.Complete(aError);
-		iOperationCompletePending = EFalse;
+		if(!iHandlingExtdCI && iRequestBeingServiced.Function()==EMMFDevSoundProxyEmptyBuffers)
+			{
+			//If we come here then it is due to a EMMFDevSoundProxyEmptyBuffers request from client.
+			SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Calling TMMFDevSoundRequest::Complete on iRequestBeingServiced"));
+		    iRequestBeingServiced.Complete(aError);
+		    iOperationCompletePending = EFalse;
+			}
 		}
 	else
 		{
-		if( iOperationCompletePending )
+		if( NeedToQueue() )
 			{
 			// If not possible to service now, then queue request
 			// Encapsule the request
@@ -1692,6 +1965,7 @@
 				}
 			}
 		}
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Exit"));
 	}
 
 
@@ -1701,8 +1975,10 @@
 //
 void CMMFDevSoundSession::PreemptionStartedCallbackReceived()
 	{
-	// Solution: Enqueue any request that arrives before preemption is completed
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Enter"));
+    // Solution: Enqueue any request that arrives before preemption is completed
 	iOperationCompletePending = ETrue;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Exit"));
 	}
 
 //
@@ -1711,16 +1987,46 @@
 //
 void CMMFDevSoundSession::PreemptionFinishedCallbackReceived(TBool aCanStartNewOperation)
 	{
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Enter"));
     if (iHandlingExtdCI)
         {
         // we are in the middle of handling a CI, so ignore - will handle later when unwinding
-        return;
+        SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit. Exiting from if block for CI"));
+		return;
         }
 	iOperationCompletePending = EFalse;
 	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
 		{
 		DequeueRequest();
 		}
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit"));
+	}
+
+//
+// CMMFDevSoundSession::PreemptionClash
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::PreemptionClash()
+	{
+	//assumes sufficient space in the queue so ignore the return value
+	iQueuedRequests.Insert(iRequestBeingServiced, 0);
+	iPreemptionClash=ETrue;
+	}
+
+//
+// CMMFDevSoundSession::PreemptionClashWithStateChange
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::PreemptionClashWithStateChange()
+	{
+	#ifdef _DEBUG
+		TMMFDevSoundRequest msg = iQueuedRequests[0];
+		// message being removed should be the one we previously pushed via PreemptionClash()
+		__ASSERT_DEBUG(iRequestBeingServiced==msg, Panic(ERequestBeingServicedMismatch));
+	#endif
+	// remove without processing request with AsynchronousOperationComplete() completing the message
+	iQueuedRequests.Remove(0);
+	iPreemptionClash=EFalse;
 	}
 
 //
@@ -1754,13 +2060,15 @@
 //
 void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent)
 	{
-	TMMFDevSoundQueueItem item;
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Enter"));
+    TMMFDevSoundQueueItem item;
 	item.iRequest = EMMFDevSoundProxySETCEvent;
 	item.iErrorCode = KErrNone;
 	item.iEventPckg() = aEvent;
 	// assumes sufficient space in the queue so ignores the return value
 	TInt err = iMsgQueue.Send(item);
-	__ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
+    __ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Exit"));
 	}
 
 void CMMFDevSoundSession::AsynchronousOperationComplete(TInt aError, TBool aCanStartNewOperation)
@@ -1768,6 +2076,13 @@
     __ASSERT_DEBUG(!iHandlingExtdCI, Panic(EUnexpectedAsyncOpCompleteHandlingCI));
         // when handling CIs we should not reach here
 
+    TInt error = aError;
+    if (!error)
+        {
+        // if have no error payload, use notified error. It will be KErrNone if not set, so just use.
+        error = NotifiedError();
+        }
+
 	switch (iRequestBeingServiced.Type())
 		{
 		case TMMFDevSoundRequest::ESessionEvents:
@@ -1809,7 +2124,7 @@
 					FlushEventQueue();
 					}
 				
-				iRequestBeingServiced.Complete(aError);
+				iRequestBeingServiced.Complete(error);
 				iOperationCompletePending = EFalse;
 				}
 			}
@@ -1837,9 +2152,19 @@
 		default:
 			break;
 		}
+	
+	if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::ECallBackType )
+	    {	    
+	    SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete CallbackPF=%d pending=%d"),
+	            iRequestBeingServiced.IsCallBack(), iOperationCompletePending );
+	    }
+	else
+	    {
+	    SYMBIAN_DEBPRN3(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d Requestype=%d"),
+	            iRequestBeingServiced.Function(), iOperationCompletePending, iRequestBeingServiced.Type() );
+	    }
 
-	SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d"),iRequestBeingServiced.Function(), iOperationCompletePending );
-
+	    
 	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
 		{
 		DequeueRequest();
@@ -1848,6 +2173,7 @@
 
 void CMMFDevSoundSession::DequeueRequest()
 	{
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Enter"));
     iAsyncQueueStart->Cancel(); // if we're in here cancel any background request
 
 	TMMFDevSoundRequest msg = iQueuedRequests[0];
@@ -1876,6 +2202,7 @@
 		SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Flag can service new request\n"));
 		iAsyncQueueStart->CallBack();
 		}
+	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Exit"));
 	}
 	
 // 	AsyncQueueStartCallback
@@ -1893,11 +2220,29 @@
 	SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Service a queued request\n"));
 	TMMFDevSoundRequest msg = iQueuedRequests[0];
 	iQueuedRequests.Remove(0);
-	TRAPD(err,DoServiceRequestL(msg.Message()));
-    if(err != KErrNone)
-        {
-        msg.Complete(err);      
-        }
+	TInt err = KErrNone;
+	TBool doRequest = ETrue;
+	if(iPreemptionClash)
+		{
+		SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::AsyncQueueStartCallback - Re-applying client request due to Pre-emption clash"));
+		iPreemptionClash=EFalse; // clear flag before reading next request in queue
+		iAdapter->RollbackAdaptorActiveStateToBeforeCommit();
+		if ((iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous))
+			{
+		    doRequest = EFalse;
+		    HandleAlreadyCompletedRequest();
+			}
+		}
+
+	if (doRequest)
+		{
+		TRAP(err,DoServiceRequestL(msg.Message()));
+		if(err != KErrNone)
+			{
+			msg.Complete(err);
+			}
+		}
+
 	if (!iOperationCompletePending && iQueuedRequests.Count() != 0)
 		{
 		//dequeue next
@@ -1926,6 +2271,8 @@
 //
 void CMMFDevSoundSession::DoProcessingFinished()
 	{
+    ResetNotifiedError();
+
 	TBool asyncOperation = EFalse;
 	//ProcessingFinished should never fail
 	__ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingFinishedReceived(asyncOperation));
@@ -1941,6 +2288,8 @@
 //
 void CMMFDevSoundSession::DoProcessingError()
     {
+    ResetNotifiedError();
+
     TBool asyncOperation = EFalse;
     //ProcessingFinished should never fail
     __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingError(asyncOperation));
@@ -2025,7 +2374,7 @@
 	// Request kernel to create global RChunk if needed
 	if ( !iChunk.Handle() )
 		{
-		status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize);
+		status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize, EOwnerThread);
 		if ( status == KErrNone )
 			{
 			aBufPckg().iChunkOp = EOpen;
@@ -2273,7 +2622,7 @@
 	
 void CMMFDevSoundSession::Panic(TMMFDevSoundSessionPanicCodes aCode)
 	{
-	User::Panic(KMMFDevSoundSessionPanicCategory, aCode);
+    User::Panic(KMMFDevSoundSessionPanicCategory, aCode);
 	}
 
 void CMMFDevSoundSession::BufferErrorEvent()
@@ -2281,4 +2630,26 @@
 	// this will generate an processing error event and callback
 	iAdapter->BufferErrorEvent();
 	}
+
+void CMMFDevSoundSession::ResetNotifiedError()
+// called at beginning of commit cycle, so any error will be from callbacks
+    {
+    SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ResetNotifiedError"));
+    iNotifiedError = KErrNone;
+    }
+
+TInt CMMFDevSoundSession::NotifiedError() const
+// NotifiedError property
+    {
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifiedError(%d)"), iNotifiedError);
+    return iNotifiedError;
+    }
+
+void CMMFDevSoundSession::NotifyError(TInt aError)
+// cache notified error
+    {
+    SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifyError(%d)"), aError);
+    iNotifiedError = aError;
+    }
+
 // End of file
--- a/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.h	Mon May 03 13:56:28 2010 +0300
@@ -48,7 +48,8 @@
 	{
 	EMsgQueueFailedToSendMsg =1,
 	EQueueRequestsFailedToAppend,
-	EUnexpectedAsyncOpCompleteHandlingCI
+	EUnexpectedAsyncOpCompleteHandlingCI,
+	ERequestBeingServicedMismatch
 	};
 
 // CLASS DECLARATION
@@ -207,6 +208,14 @@
 	TBool DoInitialize1L(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service Initialize1L request that has already completed, but
+		not finished due to a pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedInitialize1L();
+
+	/**
 		Method to service Initialize2L request.
 		Leaves on failure.
 		@since 
@@ -217,6 +226,14 @@
 	TBool DoInitialize2L(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service Initialize2L request that has already completed, but
+		not finished due to a pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedInitialize2L();
+
+	/**
 		Method to service Initialize3L request.
 		Leaves on failure.
 		@param const RMmfIpcMessage& aMessage A reference to message object
@@ -235,6 +252,14 @@
 	TBool DoInitialize4L(const RMmfIpcMessage& aMessage);
 	
 	/**
+		Method to service Initialize4L request that has already completed, but
+		not finished due to a pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedInitialize4L();
+
+	/**
 		Method to service CancelInitialize request.
 		Leaves on failure.
 		@since 
@@ -388,6 +413,14 @@
 	TBool DoPlayInitL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service initialize DevSound to play request that has already completed,
+		but not finished due to a pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayInitL();
+
+	/**
 		Method to service initialize DevSound to record request.
 		Leaves on failure.
 		@since 
@@ -398,6 +431,14 @@
 	TBool DoRecordInitL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service initialize DevSound to record request that has already completed,
+		but not finished due to a pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedRecordInitL();
+
+	/**
 		Method to service signal DevSound to playing current buffer request.
 		Leaves on failure.
 		@since 
@@ -450,6 +491,15 @@
 	TBool DoPlayToneL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service signal DevSound to play simple tone operation
+		request that has already completed, but not finished due to a
+		pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayToneL();
+
+	/**
 		Method to service signal DevSound to play dual tone  operation
 		request.
 		Leaves on failure.
@@ -461,6 +511,15 @@
 	TBool DoPlayDualToneL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service signal DevSound to play dual tone operation
+		request that has already completed, but not finished due to a
+		pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayDualToneL();
+
+	/**
 		Method to service signal DevSound to play DTMFString operation
 		request.
 		Leaves on failure.
@@ -472,6 +531,15 @@
 	TBool DoPlayDTMFStringL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service signal DevSound to play DTMFString operation
+		request that has already completed, but not finished due to a
+		pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayDTMFStringL();
+
+	/**
 		Method to service signal DevSound to play tone sequence operation
 		request.
 		Leaves on failure.
@@ -483,6 +551,15 @@
 	TBool DoPlayToneSequenceL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service signal DevSound to play tone sequence operation
+		request that has already completed, but not finished due to a
+		pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayToneSequenceL();
+
+	/**
 		Method to service signal DevSound to play fixed sequence operation
 		request.
 		Leaves on failure.
@@ -494,6 +571,15 @@
 	TBool DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage);
 
 	/**
+		Method to service signal DevSound to play fixed sequence operation
+		request that has already completed, but not finished due to a
+		pre-emption clash during its commit cycle(s).
+		Leaves on failure.
+		@return void
+	*/
+	void DoAlreadyCompletedPlayFixedSequenceL();
+
+	/**
 		Method to service signal DevSound to initilize DTMF String operation
 		request.
 		Leaves on failure.
@@ -1313,6 +1399,9 @@
 
 	// from MDevSoundAdaptationObserver
 	TBool AdaptorControlsContext() const;
+	void PreemptionClash();
+	void PreemptionClashWithStateChange();
+    void NotifyError(TInt aError);
 
 	/**
 		MDevSoundAdaptationObserver callback.
@@ -1383,6 +1472,18 @@
 	void DoServiceRequestL(const RMmfIpcMessage& aMessage);
 
 	/*
+	Services the first request of queue for a pseudo asynchronous function that has already completed,
+	but needs to be re-applied again due to pre-emption clash.
+	*/
+	void DoServiceAlreadyCompletedRequestL(const TInt aFunction);
+
+	/*
+	Handles the first request of queue for a pseudo asynchronous function that has already completed,
+	but needs to be re-applied again due to pre-emption clash.
+	*/
+	void HandleAlreadyCompletedRequest();
+
+	/*
 	Services the first request at the FIFO
 	*/
 	void DoServiceNextRequestL();
@@ -1451,6 +1552,11 @@
 	static TInt AsyncQueueStartCallback(TAny* aPtr);
 	void AsyncQueueStartCallback();
 
+	void ResetNotifiedError();
+	TInt NotifiedError() const;
+
+	TBool NeedToQueue() const;
+
 protected:	// Data
 	CMMFDevSoundAdaptation* iAdapter;
 
@@ -1502,6 +1608,13 @@
 	
 	CActiveSchedulerWait*		iClosingWait;
 	CAsyncCallBack*				iAsyncQueueStart;
+
+	TInt iRedoFunction;
+	TMMFDevSoundProxySettingsPckg iCachedClientData;
+	TInt iSeqNum;
+	TBool iPreemptionClash;
+	TInt iNotifiedError;
+
 	};
 
 #endif // MMFDEVSOUNDSESSION_H
--- a/devsoundextensions/effectspresets/StereoWideningUtility/group/bld.inf	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsoundextensions/effectspresets/StereoWideningUtility/group/bld.inf	Mon May 03 13:56:28 2010 +0300
@@ -30,7 +30,7 @@
 PRJ_MMPFILES
 
 // AAC Encoder Plugin
-//StereoWideningUtility.mmp 	//Utility DLL 
+StereoWideningUtility.mmp 	//Utility DLL 
 
 
 
--- a/devsoundextensions/effectspresets/rom/EffectsPresets.iby	Fri Apr 16 16:34:49 2010 +0300
+++ b/devsoundextensions/effectspresets/rom/EffectsPresets.iby	Mon May 03 13:56:28 2010 +0300
@@ -25,9 +25,6 @@
 file=ABI_DIR\BUILD_DIR\EnvironmentalReverbUtility.dll		SHARED_LIB_DIR\EnvironmentalReverbUtility.dll
 file=ABI_DIR\BUILD_DIR\StereoWideningUtility.dll		SHARED_LIB_DIR\StereoWideningUtility.dll
 
-//CenRep Keys Backup for Audio Equalizer Utility
-data=DATAZ_\private\10207A8F\backup_registration.xml	private\10207A8F\backup_registration.xml
-
 // Effect Presets
 data=ZSYSTEM\install\EffectsPresets_Stub.SIS    System\Install\EffectsPresets_Stub.SIS
 
--- a/imagingandcamerafws/camerafw/Include/ecamimageprocessing.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/camerafw/Include/ecamimageprocessing.h	Mon May 03 13:56:28 2010 +0300
@@ -677,9 +677,9 @@
 		TRelativeRotation aRelativeRotation, TRelativeMirror aRelativeMirror, TRelativeFlipping aRelativeFlipping);
 	
 private:
-	CCameraImageProcessing(CCamera& aOwner);
-	void ConstructL();
-	void ConstructL(const MImplementationFactory& aImplFactory);
+	IMPORT_C CCameraImageProcessing(CCamera& aOwner);
+	IMPORT_C void ConstructL();
+	IMPORT_C void ConstructL(const MImplementationFactory& aImplFactory);
 	
 private:
 	CCamera& iOwner;
--- a/imagingandcamerafws/imagingfws/GifScaler/src/NQColorQuantizer.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/imagingfws/GifScaler/src/NQColorQuantizer.cpp	Mon May 03 13:56:28 2010 +0300
@@ -458,7 +458,7 @@
 	// For frequently chosen neurons, freq[i] is high and bias[i] is negative
 	// bias[i] = gamma*((1/netsize)-freq[i])
 
-	TInt bestd = ~(1<<31);
+	TInt bestd = ~((TUint32)1<<31);
 	TInt bestbiasd = bestd;
 	TInt bestpos = -1;
 	TInt bestbiaspos = bestpos;
--- a/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/scripts/TSU_ICL_COD_03.script	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/scripts/TSU_ICL_COD_03.script	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -525,3 +525,12 @@
 
 RUN_TEST_STEP -1, TSU_ICL_COD_03, MM-ICL-COD-U-5114-HP
 TEST_COMPLETE
+
+//AKAL-7YHLPR : Crash found in Themes Thread. Memory corruption with Gif image.
+RUN_TEST_STEP -1, TSU_ICL_COD_03, MM-ICL-COD-U-5108-HP
+TEST_COMPLETE
+
+//DEF144646 : Genius Case #144754: Nokia N97-1: Israel: N97 TIFF files not displayed properly. 
+RUN_TEST_STEP -1, TSU_ICL_COD_03, MM-ICL-COD-U-5109-HP 
+TEST_COMPLETE 
+
--- a/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -10242,3 +10242,163 @@
     return EPass;
     }
 
+//AKAL-7YHLPR : Crash found in Themes Thread.
+RTestStep_5108::RTestStep_5108(CTestSuite* aSuite)
+    {
+    iSuite = aSuite;
+    iTestStepName = _L("MM-ICL-COD-U-5108-HP");
+    }
+
+
+void RTestStep_5108::Close()
+    {
+    delete iScheduler;
+    iScheduler = NULL;
+    iFs.Close();
+    RFbsSession::Disconnect();
+    }
+
+
+RTestStep_5108* RTestStep_5108::NewL(CTestSuite* aSuite)
+    {
+    if (!aSuite)
+        {
+        User::Leave(KErrArgument);        
+        }
+    return new(ELeave) RTestStep_5108(aSuite);
+    }
+
+
+TVerdict RTestStep_5108::OpenL()
+    {
+    User::LeaveIfError(RFbsSession::Connect());
+    User::LeaveIfError(iFs.Connect());
+
+    iScheduler = new(ELeave) CActiveScheduler();
+    CActiveScheduler::Install(iScheduler);
+    
+    return EPass;
+    }
+
+
+/*
+ * Test added for AKAL-7YHLPR : Crash found in Themes Thread.
+ * The test is to check the possible memory corruption on decoding a test Gif image. The gif image has transparency
+ * color index of 128. Decode option is Fast decode and with EColor64k. With these combination, the memory corruption 
+ * happens. The test decodes all the frames in the image.
+ * If memory corruption happens, the test will panic and fail. No panic means the problem is fixed, and the test passes.
+ * The test also fails if all frames are not decoded successfully. 
+ */
+TVerdict RTestStep_5108::DoTestStepL()
+    {
+    INFO_PRINTF1(_L("AKAL-7YHLPR : Crash found in Themes Thread."));
+    INFO_PRINTF1(_L("Test checks for memory corruption on decoding Gif image with Tranparency index = 128, with EColor64K and in Fast decode mode"));
+    _LIT(KGifTranpIdx128, "c:\\tsu_icl_cod_03\\secret.gif");
+    CImageDecoder* decoder = NULL;
+    //create decoder with Fast decode 
+    decoder = CImageDecoder::FileNewL(iFs, KGifTranpIdx128, CImageDecoder::EPreferFastDecode);
+    CleanupStack::PushL(decoder);
+    CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+    //bitmap with EColor64K
+    TInt err = bitmap->Create(TSize(0,0), EColor64K);
+    CleanupStack::PushL(bitmap);
+    CActiveListener* listener = new (ELeave) CActiveListener;
+    CleanupStack::PushL(listener);//get the no. of frames in the image.
+    TInt frameCount = decoder->FrameCount();
+    TVerdict result = EPass;
+    //decode all the frames.
+    for(TInt i = 0; i < frameCount; i++)
+        {
+        const TFrameInfo& frameInfo = decoder->FrameInfo(i);
+        const TSize frameSize(frameInfo.iOverallSizeInPixels);
+        listener->InitialiseActiveListener();
+        err = bitmap->Resize(frameSize);
+        decoder->Convert(&listener->iStatus, *bitmap,i);
+        CActiveScheduler::Start();
+        err = listener->iStatus.Int();
+        if(err != KErrNone)
+            {
+            result = EFail; //fail if couldn't decode all frames.
+            break;
+            }
+        err = bitmap->Resize(TSize(0,0));
+        }
+    CleanupStack::PopAndDestroy(3); //listener, bitmap, decoder
+    return result;
+    }
+
+//DEF144646 : Genius Case #144754: Nokia N97-1: Israel: N97 TIFF files not displayed properly. 
+    RTestStep_5109::RTestStep_5109(CTestSuite* aSuite) 
+        { 
+        iSuite = aSuite; 
+        iTestStepName = _L("MM-ICL-COD-U-5109-HP"); 
+        } 
+      
+    void RTestStep_5109::Close() 
+        { 
+        delete iScheduler; 
+        iScheduler = NULL; 
+        iFs.Close(); 
+        RFbsSession::Disconnect(); 
+        } 
+      
+    RTestStep_5109* RTestStep_5109::NewL(CTestSuite* aSuite) 
+        { 
+        if (!aSuite) 
+            { 
+            User::Leave(KErrArgument);         
+            } 
+        return new(ELeave) RTestStep_5109(aSuite); 
+        } 
+      
+    TVerdict RTestStep_5109::OpenL() 
+        { 
+        User::LeaveIfError(RFbsSession::Connect()); 
+        User::LeaveIfError(iFs.Connect()); 
+      
+        iScheduler = new(ELeave) CActiveScheduler(); 
+        CActiveScheduler::Install(iScheduler); 
+         
+        return EPass; 
+        } 
+      
+    /* 
+     * Test added for PDEF144975: TIFF files not displayed properly 
+     * The test is to check the decoding a test tif image.  
+     */ 
+    TVerdict RTestStep_5109::DoTestStepL() 
+        { 
+        INFO_PRINTF1(_L("PDEF144975: TIFF files not displayed properly")); 
+        INFO_PRINTF1(_L("Test is to check the decoding of below tif image")); 
+        _LIT(KTifImage, "c:\\tsu_icl_cod_03\\3178500m.tif"); 
+        CImageDecoder* decoder = NULL; 
+        //create decoder  
+        decoder = CImageDecoder::FileNewL(iFs, KTifImage, CImageDecoder::EOptionNone); 
+        CleanupStack::PushL(decoder); 
+         
+        //Get frameinformation 
+        TInt frameNo = 0; 
+        const TFrameInfo& frameInfo = decoder->FrameInfo(frameNo); 
+         
+        //Create a destination bitmap 
+        CFbsBitmap* bitmap = new (ELeave) CFbsBitmap; 
+        TInt err = bitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode); 
+        User::LeaveIfError(err); 
+        CleanupStack::PushL(bitmap); 
+         
+        CActiveListener* listener = new (ELeave) CActiveListener; 
+        CleanupStack::PushL(listener); 
+        TVerdict result = EPass; 
+         
+        //decode the frame. 
+        listener->InitialiseActiveListener(); 
+        decoder->Convert(&listener->iStatus, *bitmap, frameNo); 
+        CActiveScheduler::Start(); 
+        err = listener->iStatus.Int(); 
+        if(err != KErrNone) 
+          { 
+          result = EFail; //fail if couldn't decode a frame. 
+          } 
+        CleanupStack::PopAndDestroy(3); //listener, bitmap, decoder 
+        return result; 
+        }
--- a/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestStep.h	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -2245,4 +2245,41 @@
     CActiveScheduler* iScheduler;
     };
 
+//AKAL-7YHLPR : Crash found in Themes Thread.
+//memory corruption for Gif image secret.gif 
+NONSHARABLE_CLASS(RTestStep_5108): public RICLCodecDefectTestStep
+    {
+public:
+    static RTestStep_5108* NewL(CTestSuite* aSuite);
+    // From RICLCodecDefectTestStep
+    TVerdict OpenL();
+    TVerdict DoTestStepL();
+    void Close();
+        
+private:
+    RTestStep_5108(CTestSuite* aSuite);
+        
+private:
+    RFs iFs;
+    CActiveScheduler* iScheduler;
+    };
+
+//DEF144646 : Genius Case #144754: Nokia N97-1: Israel: N97 TIFF files not displayed properly. 
+    NONSHARABLE_CLASS(RTestStep_5109): public RICLCodecDefectTestStep 
+        { 
+    public: 
+        static RTestStep_5109* NewL(CTestSuite* aSuite); 
+        // From RICLCodecDefectTestStep 
+        TVerdict OpenL(); 
+        TVerdict DoTestStepL(); 
+        void Close(); 
+             
+    private: 
+        RTestStep_5109(CTestSuite* aSuite); 
+             
+    private: 
+        RFs iFs; 
+        CActiveScheduler* iScheduler; 
+        }; 
+	
 #endif // ICLCODECDEFECTTESTSTEP_H
--- a/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestSuite.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/imagingandcamerafws/imagingunittest/TSU_ICL_COD_03/src/ICLCodecDefectTestSuite.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -127,6 +127,8 @@
 	AddTestStepL(RTestStep_5112::NewL(this));
 	AddTestStepL(RTestStep_5113::NewL(this));
 	AddTestStepL(RTestStep_5114::NewL(this));
+	AddTestStepL(RTestStep_5108::NewL(this));
+	AddTestStepL(RTestStep_5109::NewL(this));
 	}
 
 void CICLCodecDefectTestSuite::InitSystemPath()
--- a/mdfdevvideoextensions/nga_mdf_postprocessor/data/nga_mdf_postprocessor_stub.pkg	Fri Apr 16 16:34:49 2010 +0300
+++ b/mdfdevvideoextensions/nga_mdf_postprocessor/data/nga_mdf_postprocessor_stub.pkg	Mon May 03 13:56:28 2010 +0300
@@ -28,8 +28,3 @@
 ; Unique Vendor name
 :"Nokia"
 
-"\epoc32\release\armv5\urel\NGAPostProcHwDevice.dll"-"!:\sys\bin\NGAPostProcHwDevice.dll"
-
-"\epoc32\data\z\resource\plugins\NGAPostProcHwDevice.RSC"-"!:\resource\plugins\NGAPostProcHwDevice.RSC"
-
-
Binary file mdfdevvideoextensions/nga_mdf_postprocessor/data/nga_mdf_postprocessor_stub.sis has changed
--- a/mdfdevvideoextensions/nga_mdf_postprocessor/inc/NGAPostProcHwDevice.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mdfdevvideoextensions/nga_mdf_postprocessor/inc/NGAPostProcHwDevice.h	Mon May 03 13:56:28 2010 +0300
@@ -1062,6 +1062,7 @@
     TInt                                		iOverflowPictureCounter;
     TInt 								    	iVideoFrameBufSize;	
     TBool 										iResourceLost;
+    TBool 										iRedrawDone;
     
     //-- members for buffer management --
     MMmfVideoBufferManagementObserver*  		iVBMObserver;
--- a/mdfdevvideoextensions/nga_mdf_postprocessor/src/NGAPostProcHwDevice.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mdfdevvideoextensions/nga_mdf_postprocessor/src/NGAPostProcHwDevice.cpp	Mon May 03 13:56:28 2010 +0300
@@ -94,6 +94,7 @@
             iOverflowPictureCounter(0),
             iVideoFrameBufSize(0),
             iResourceLost(EFalse),
+            iRedrawDone(EFalse),
             iVBMObserver(NULL),
             count(0),
             iSurfaceMask(surfaceHints::EAllowAllExternals),
@@ -826,7 +827,7 @@
 { 
 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw ++"), this);
 	TInt err = KErrNone;
-	if(iResourceLost)
+	if(iResourceLost && !iRedrawDone)
 	{
         err = AddHints();
         if (err != KErrNone)
@@ -836,6 +837,7 @@
             iProxy->MdvppFatalError(this, err);	
             return;   
         }
+        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw registering the temp surface"), this);
 		err = RegisterSurface(iSurfaceId);
 		if (err != KErrNone)
 		{
@@ -846,10 +848,10 @@
 			iProxy->MdvppFatalError(this, err);	
 			return;   				
 		}
-
+		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw registering the temp surface done"), this);
         iSessionManager->PostPicture(iSurfaceId, 0, 1, EFalse);
         PublishSurfaceCreated();
-        iResourceLost = EFalse;
+        iRedrawDone = ETrue;
     }
     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw --"), this);
 }
@@ -1326,12 +1328,30 @@
 void CNGAPostProcHwDevice::MmvroResourcesLost(TUid )
 {
     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost ++"), this);
-	iResourceLost = ETrue;
-	Pause();
-	ReleaseInputQ();
-	iSessionManager->CancelUpdate();
-	ReleaseProcessQ();
-	iVideoSurfaceObserver->MmvsoRemoveSurface();
+    if(!iResourceLost)
+    {
+		iResourceLost = ETrue;
+		iRedrawDone = EFalse;
+		Pause();
+		ReleaseInputQ();
+		iSessionManager->CancelUpdate();
+		ReleaseProcessQ();
+		iVideoSurfaceObserver->MmvsoRemoveSurface();
+	}
+	else if(iResourceLost && iRedrawDone)
+	{
+		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost ResourceLost happening \
+					while Postprocessor is already in ResourceLoss state"), 
+	   				this);
+		iProxy->MdvppFatalError(this, KErrHardwareNotAvailable);	   				
+	    return;		
+	}
+	else
+	{
+		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost Ignoring the \
+					duplicate ResourceLoss call"), 
+	   				this);
+	}
     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost --"), this);
 }
 
--- a/mmlibs/mmfw/MMPFiles/client/MediaClientVideo.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/MMPFiles/client/MediaClientVideo.mmp	Mon May 03 13:56:28 2010 +0300
@@ -42,6 +42,10 @@
 source			mediaclientvideodisplaybody.cpp
 source			mediaclientextdisplayinterface.cpp
 source			mediaclientextdisplayhandler.cpp
+source			mediaclientwseventobserver.cpp
+source			mediaclientpolicyserverclient.cpp
+source			mediaclientpolicyserversession.cpp
+
 #endif 
 
 source			mmfclientvideoplayerbody.cpp
@@ -90,9 +94,4 @@
 	baseaddress	0x4F2A0000
 end
 
-MACRO __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
-
-
-                    
-
 SMPSAFE
--- a/mmlibs/mmfw/MMPFiles/client/mediaclientvideodisplay.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/MMPFiles/client/mediaclientvideodisplay.mmp	Mon May 03 13:56:28 2010 +0300
@@ -37,6 +37,9 @@
 source			mediaclientvideodisplaybody.cpp
 source			mediaclientextdisplayinterface.cpp 
 source			mediaclientextdisplayhandler.cpp
+source			mediaclientwseventobserver.cpp
+source			mediaclientpolicyserverclient.cpp
+source			mediaclientpolicyserversession.cpp
 
 library			ws32.lib
 library			euser.lib
@@ -46,8 +49,4 @@
 
 nostrictdef
 
-MACRO __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
-
 SMPSAFE
-
-                    
--- a/mmlibs/mmfw/Recogniser/src/constants.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/Recogniser/src/constants.h	Mon May 03 13:56:28 2010 +0300
@@ -71,7 +71,7 @@
 #define KExtXMF			_S(".xmf")
 #define KExtXPS			_S(".xps")
 #define KExtBeatnikRMF	_S(".rmf")
-
+#define KExtMOV         _S(".mov")  // for .mov extension
 
 //
 // Recognised MIME-types.
@@ -121,7 +121,7 @@
 #define KMimeXMF		_S8("audio/xmf")
 #define KMimeXPS		_S8("application/x-ext-packetsrc")
 #define KMimeBeatnikRMF _S8("audio/x-beatnik-rmf")
-
+#define KMimeQuickV     _S8("video/quicktime")  // for .mov extension
 
 //
 // Recognised header signatures.
--- a/mmlibs/mmfw/Recogniser/src/mpeg4parser.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/Recogniser/src/mpeg4parser.cpp	Mon May 03 13:56:28 2010 +0300
@@ -28,7 +28,7 @@
 static const TUint32 K3G2Brand = MAKE_INT32('3', 'g', '2', 0);
 static const TUint32 K3GSBrand = MAKE_INT32('3', 'g', 's', 0);	// Streaming servers.
 static const TUint32 K3GRBrand = MAKE_INT32('3', 'g', 'r', 0);	// Progresive download and MMS.
-
+static const TUint32 KQTBrand  = MAKE_INT32('q', 't', ' ', ' '); // for quicktime
 //
 // Box identifiers.
 //
@@ -103,7 +103,8 @@
 		{KExt3G2,	K3G2Brand,	KMime3G2_A,	KMime3G2_V},
 		{KExt3GP,	K3GSBrand,	KMime3GP_A,	KMime3GP_V},
 		{KExt3GP,	K3GRBrand,	KMime3GP_A,	KMime3GP_V},
-		{KExt3GA,	K3GPBrand,	KMime3GA,	NULL}
+		{KExt3GA,	K3GPBrand,	KMime3GA,	NULL},
+		{KExtMOV,   KQTBrand,   NULL, KMimeQuickV} // this entry is for .mov files
 	};
 
 static const TInt KMPEG4FileTypeCount = sizeof(KMPEG4Files) / sizeof(TMPEG4File);
@@ -465,6 +466,11 @@
 	// If the majorBrand isn't recognised we should also
 	// search the compatible brand list.
 	TInt64 bytesRemaining = iSize - KMPEG4FtypIntroLen;
+	//here there should be bytes remaining. Otherwise we cant read.
+	if( bytesRemaining <0 )
+	{
+	    User::Leave(KErrCorrupt);    
+	}
 	
 	iReader.Read32L(brand);
 	iBrandIndex = TMPEG4Parser::IsCompatibleBrand(brand);
--- a/mmlibs/mmfw/src/Client/Video/VideoPlayerBody.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/VideoPlayerBody.h	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -203,7 +203,6 @@
 	TInt EnableSubtitles(CMediaClientVideoDisplayBody& aDisplay);
 	TInt AddSubtitleConfig(CMediaClientVideoDisplayBody::TWindowData& aWindowData);
 	void GetSubtitleConfigFromWindowData(CMediaClientVideoDisplayBody::TWindowData& aWindowData, TMMFSubtitleWindowConfig& aConfig);
-	void UpdateSurfaceAndSubtitleConfigL(CMediaClientVideoDisplayBody& aDisplay,CMediaClientVideoDisplayBody::TWindowData& aWindowData, const TRect& aClipRect, TVideoRotation aRotation, const TRect& aCropRegion);
 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
 
 private:
@@ -232,7 +231,6 @@
 								const TRect& aClipRect, const TRect& aVideoExtent, RWindow* aWindow2);
 	TInt SurfaceCreated();
 	TInt SurfaceParametersChanged();
-	TInt SetBackgroundSurface(const CMediaClientVideoDisplayBody& aDisplay);
 	TInt RemoveSurface(TBool aControllerEvent);
 	TInt SetAllBackgroundSurfaces();
 
--- a/mmlibs/mmfw/src/Client/Video/mediaclientextdisplayhandler.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientextdisplayhandler.cpp	Mon May 03 13:56:28 2010 +0300
@@ -54,6 +54,8 @@
     iRootWindow = RWindowGroup(iWs);
     User::LeaveIfError(iRootWindow.Construct((TUint32)this, ETrue));
 
+    DEBUG_PRINTF2("CMediaClientExtDisplayHandler::ConstructL RWindowGroupId %d", iRootWindow.WindowGroupId());
+    
     DEBUG_PRINTF("CMediaClientExtDisplayHandler::ConstructL RWindow Create");
     iExternalDisplayWindow = RWindow(iWs);
     User::LeaveIfError(iExternalDisplayWindow.Construct(iRootWindow,((TUint32)(this)) + 1));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientpolicyserverclient.cpp	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "mediaclientpolicyserverclient.h"
+#include <e32std.h>
+#include "mediaclientvideotrace.h"
+
+CMediaClientPolicyServerClient* CMediaClientPolicyServerClient::NewL()
+    {
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::NewL +++");
+    
+    CMediaClientPolicyServerClient* self = new( ELeave ) CMediaClientPolicyServerClient();
+    
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::NewL ---");
+    return self;
+    }
+
+CMediaClientPolicyServerClient::~CMediaClientPolicyServerClient()
+    {
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::~CMediaClientPolicyServerClient +++");
+    iSession.Close();
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::~CMediaClientPolicyServerClient ---");
+    }
+
+void CMediaClientPolicyServerClient::SetSurface(const TSurfaceId& aSurfaceId)
+    {
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::SetSurface +++");
+            
+    if( aSurfaceId.IsNull() )
+        {
+        DEBUG_PRINTF("CMediaClientPolicyServerClient::SetSurface NULL SurfaceId received");
+        }
+    else
+        {
+        iSurfaceId = aSurfaceId;
+        DEBUG_PRINTF2("CMediaClientPolicyServerClient::SetSurface - SurfaceId 0 0x%x", iSurfaceId.iInternal[0]);  
+        DEBUG_PRINTF2("CMediaClientPolicyServerClient::SetSurface - SurfaceId 1 0x%x", iSurfaceId.iInternal[1]);  
+        DEBUG_PRINTF2("CMediaClientPolicyServerClient::SetSurface - SurfaceId 2 0x%x", iSurfaceId.iInternal[2]);  
+        DEBUG_PRINTF2("CMediaClientPolicyServerClient::SetSurface - SurfaceId 3 0x%x", iSurfaceId.iInternal[3]);  
+        }
+    
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::SetSurface ---");
+    }
+
+void CMediaClientPolicyServerClient::FocusChanged(TBool aForeground)    
+    {
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::FocusChanged +++");
+
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::FocusChanged - SurfaceId 0 0x%x", iSurfaceId.iInternal[0]);  
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::FocusChanged - SurfaceId 1 0x%x", iSurfaceId.iInternal[1]);  
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::FocusChanged - SurfaceId 2 0x%x", iSurfaceId.iInternal[2]);  
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::FocusChanged - SurfaceId 3 0x%x", iSurfaceId.iInternal[3]);  
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::FocusChanged - Focus %d", aForeground);  
+
+    if( iSurfaceId.IsNull() )
+        {
+        DEBUG_PRINTF(" CMediaClientPolicyServerClient::FocusChanged SurfaceId is NULL ... ignore focus change event");
+        }
+    else
+        {
+        DEBUG_PRINTF(" CMediaClientPolicyServerClient::FocusChanged Send focus change event to PS");
+        TFocusSurfaceChangedEvent focusChangedMessage;
+        focusChangedMessage.iSurfaceId = iSurfaceId;
+        focusChangedMessage.iForeground = aForeground;
+        TPckgBuf<TFocusSurfaceChangedEvent> buffer(focusChangedMessage);
+        TIpcArgs messageArguments(&buffer);
+        
+        TInt error = iSession.SendMessage(KFocusSurfaceChanged, messageArguments);
+    
+        if(error)
+            {
+            DEBUG_PRINTF2(" CMediaClientPolicyServerClient::FocusChanged SendMessage failed, error = %d", error);
+            }
+        }    
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::FocusChanged ---");
+    }
+
+TBool CMediaClientPolicyServerClient::IgnoreProcess(TSecureId aId)
+    {
+    DEBUG_PRINTF("CMediaClientPolicyServerClient::IgnoreProcess +++");
+    
+    TBool ignore = (
+            (aId == 0x10281EF2) ||  // aknnfysrv
+            (aId == 0x10207218) ||  // akncapserver
+            (aId == 0x10003a4a)     // eiksrvs
+            );
+    
+    DEBUG_PRINTF2("CMediaClientPolicyServerClient::IgnoreProcess --- return %d", ignore);
+    return ignore;
+    }
+
+TInt CMediaClientPolicyServerClient::Connect()
+    {
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::Connect +++");
+    TInt error = iSession.Connect();
+    DEBUG_PRINTF2(" CMediaClientPolicyServerClient::Connect --- return %d", error);   
+    return error;
+    }
+
+void CMediaClientPolicyServerClient::Close()
+    {
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::Close +++");
+    iSession.Close();
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::Close ---");   
+    }
+
+CMediaClientPolicyServerClient::CMediaClientPolicyServerClient()
+    {
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::CMediaClientPolicyServerClient +++");
+    iSurfaceId = TSurfaceId::CreateNullId();
+    DEBUG_PRINTF(" CMediaClientPolicyServerClient::CMediaClientPolicyServerClient ---");
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientpolicyserverclient.h	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef MEDIACLIENTPOLICYSERVERCLIENT_H
+#define MEDIACLIENTPOLICYSERVERCLIENT_H
+
+#include "mediaclientpolicyserversession.h"
+#include <e32base.h>
+#include <graphics/surface.h>
+
+const TInt KFocusSurfaceChanged = 9; // taken from Policy Server
+
+NONSHARABLE_CLASS(CMediaClientPolicyServerClient) : public CBase
+    {
+private:
+    class TFocusSurfaceChangedEvent
+        {
+        public:
+            TSurfaceId iSurfaceId;
+            TBool iForeground;        
+        };
+
+public:
+    static CMediaClientPolicyServerClient* NewL();
+    virtual ~CMediaClientPolicyServerClient();
+
+public:
+    TInt Connect();
+    void Close();
+    void SetSurface(const TSurfaceId& aSurfaceId);
+    void FocusChanged(TBool aForeground);  
+    TBool IgnoreProcess(TSecureId aId);
+    
+private:
+    CMediaClientPolicyServerClient();
+
+private:
+    RMediaClientPolicyServerSession iSession;
+    TSurfaceId iSurfaceId;
+    };
+
+#endif // MEDIACLIENTPOLICYSERVERCLIENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientpolicyserversession.cpp	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,119 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "mediaclientpolicyserversession.h"
+#include <e32std.h>
+#include "mediaclientvideotrace.h"
+
+// Policy Server EXE name
+_LIT( KIvePolicyServerImg, "ivepolicyserver" );
+
+// Policy Server thread name
+_LIT( KIvePolicyServerName, "!ivepolicyserver0x10204C27" ); 
+
+// Number of asynchronous message slots
+const TInt KIveAsyncMessageSlots = 1;
+
+static TInt StartServer()
+    {
+    DEBUG_PRINTF("medialclientsession StartServer +++");
+    
+    RProcess server;
+    TInt error = server.Create(KIvePolicyServerImg, KNullDesC);
+    if (error != KErrNone)
+        {
+        DEBUG_PRINTF2("medialclientsession StartServer server creation failed %d", error);
+        return error;
+        }
+        
+    TRequestStatus status;
+
+    server.Rendezvous(status);
+    if (status != KRequestPending)
+        {
+        server.Kill( 0 );
+        // abort startup
+        }
+    else
+        {
+        server.Resume();
+        // logon OK - start the server
+        }
+
+    User::WaitForRequest(status);
+    // wait for start or death
+    error = (server.ExitType() == EExitPanic) ? KErrGeneral : status.Int();
+    server.Close();
+   
+    DEBUG_PRINTF(" medialclientsession StartServer ---");
+    return error;
+    }
+
+RMediaClientPolicyServerSession::RMediaClientPolicyServerSession():
+    RSessionBase()
+    {
+    DEBUG_PRINTF(" RMediaClientPolicyServerSession::RMediaClientPolicyServerSession +++");
+    DEBUG_PRINTF(" RMediaClientPolicyServerSession::RMediaClientPolicyServerSession ---");
+    }
+
+TInt RMediaClientPolicyServerSession::Connect()
+    {
+    DEBUG_PRINTF(" RMediaClientPolicyServerSession::Connect +++");
+    
+    TInt error = KErrNone;
+    for (TInt i = 0; i < 2; i++)
+        {
+        // Try to create session.
+        error = CreateSession(KIvePolicyServerName, TVersion( 0, 0, 0 ), KIveAsyncMessageSlots);
+
+        if (error != KErrNotFound && error != KErrServerTerminated) 
+            {
+            DEBUG_PRINTF("RMediaClientPolicyServerSession::Connect Server found and session created."); 
+            DEBUG_PRINTF2("RMediaClientPolicyServerSession::Connect --- returns %d", error);
+            return error;
+            }
+  
+        // If session failed, try to start server once.
+        if (i == 0)
+            {            
+            DEBUG_PRINTF("RMediaClientPolicyServerSession::Connect StartServer");
+            // Start server
+            error = StartServer();                     
+            if (error != KErrNone && error != KErrAlreadyExists)
+                {
+                DEBUG_PRINTF("RMediaClientPolicyServerSession::Connect Server startup failed.");
+                DEBUG_PRINTF2("RMediaClientPolicyServerSession::Connect --- returns %d", error);
+                return error;
+                }
+            }
+        else
+            {
+            DEBUG_PRINTF2("RMediaClientPolicyServerSession::Connect Session creation failed error %d", error);
+            }
+        }
+    
+    DEBUG_PRINTF2("RMediaClientPolicyServerSession::Connect --- returns %d", error);
+    return error;
+    }
+
+TInt RMediaClientPolicyServerSession::SendMessage( TInt aFunction, const TIpcArgs &aArgs ) const 
+    {
+    DEBUG_PRINTF("RMediaClientPolicyServerSession::SendMessage +++");
+
+    TInt error = SendReceive( aFunction, aArgs );    
+    
+    DEBUG_PRINTF2("RMediaClientPolicyServerSession::SendMessage --- returns %d", error);
+    return error;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientpolicyserversession.h	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef MEDIACLIENTPOLICYSERVERSESSION_H
+#define MEDIACLIENTPOLICYSERVERSESSION_H
+
+#include <e32std.h>
+
+/**
+ @file
+ @internalComponent
+ 
+*/
+class RMediaClientPolicyServerSession : public RSessionBase
+    {
+public:
+
+    RMediaClientPolicyServerSession();
+    
+    TInt Connect(); 
+    TInt SendMessage( TInt aFunction, const TIpcArgs &aArgs ) const;
+    };
+
+#endif // MEDIACLIENTPOLICYSERVERSESSION_H
+
--- a/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.cpp	Mon May 03 13:56:28 2010 +0300
@@ -15,6 +15,7 @@
 
 #include "mediaclientvideodisplaybody.h"
 #include "mediaclientvideotrace.h"
+#include "mediaclientpolicyserverclient.h"
 #include <surfaceeventhandler.h>
 #include <mmf/plugin/mmfmediaclientextdisplayinterface.hrh>
 #include <e32cmn.h>
@@ -62,15 +63,36 @@
 
 	SetWindowArrayPtr2Client();
 
-	CreateExtDisplayPluginL();
-	
-	// Try and enable display switching by default. If this leaves then do so quietly.
-	// Either the client has no scheduler installed or the device does not support external
-	// switching (i.e. no plugin was found) 
-	TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl));
-	err = err; // remove compile warning
-	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err);
-	
+	// External display switching and wserv events are only possible if there is
+	// an active scheduler in client thread
+	if(CActiveScheduler::Current())
+	    {
+        CreateExtDisplayPluginL();
+        iWsEventObserver = CMediaClientWsEventObserver::NewL(*this);
+
+        iServerClient = CMediaClientPolicyServerClient::NewL();
+        if(iServerClient->Connect() != KErrNone)
+            {
+            delete iServerClient;
+            iServerClient = NULL;
+            }
+        
+        if(IsSurfaceCreated() && iServerClient)
+            {
+            iServerClient->SetSurface(iSurfaceId);
+            }
+        
+        // Try and enable display switching by default. If this leaves then do so quietly.
+        // Either the client has no scheduler installed or the device does not support external
+        // switching (i.e. no plugin was found) 
+        TRAPD(err, SetExternalDisplaySwitchingL(aExtDisplaySwitchingControl));
+        err = err; // remove compile warning
+        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConstructL SetExternalDisplaySwitchingL returned with %d", err);
+	    }
+	else
+	    {
+	    DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL No CActiveScheduler - ext display and focus features disabled ");
+	    }
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ConstructL ---");
 	}
 
@@ -106,6 +128,10 @@
 	RemoveExtDisplayPlugin();
 	REComSession::FinalClose();
 	
+    delete iWsEventObserver;
+
+    delete iServerClient;
+    
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::~CMediaClientVideoDisplayBody ---");
 	}
 
@@ -129,7 +155,7 @@
 void CMediaClientVideoDisplayBody::AddDisplayWindowL(const RWindowBase* aWindow, const TRect& aClipRect, const TRect& aCropRegion, const TRect& aVideoExtent, 
 															TReal32 aScaleWidth, TReal32 aScaleHeight, TVideoRotation aRotation, 
 															TAutoScaleType aAutoScaleType, TInt aHorizPos, TInt aVertPos, RWindow* aWindow2)
-	{
+	{	
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::AddDisplayWindowL +++");
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aWindow WsHandle 0x%X", aWindow->WsHandle());
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::AddDisplayWindowL - aClipRect %d,%d - %d,%d", aClipRect.iTl.iX, aClipRect.iTl.iY, aClipRect.iBr.iX, aClipRect.iBr.iY);
@@ -140,6 +166,16 @@
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL - aAutoScaleType %d", aAutoScaleType);
     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::AddDisplayWindowL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
 
+	if (!IsRotationValid(aRotation))
+		{
+		User::Leave(KErrArgument);
+		}
+
+	if (!IsAutoScaleTypeValid(aAutoScaleType))
+		{
+		User::Leave(KErrArgument);
+		}
+
 	TInt pos = iClientWindows.Find(aWindow->WsHandle(), TWindowData::CompareByWsHandle);
 	
 	if (pos != KErrNotFound)
@@ -152,24 +188,25 @@
 	
 	iCropRegion = aCropRegion;
 	
+	TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
+    UpdateFocus();
+	
 	if (IsSurfaceCreated())
 		{
-		// first client window just added
-        if((iClientWindows.Count() == 1) && iClientRequestedExtDisplaySwitching)
+        // if first window was just added OR the new window has moved us from out of focus to in focus
+        if(((iClientWindows.Count() == 1) || !prevClientWindowIsInFocus) && iClientRequestedExtDisplaySwitching &&
+                iClientWindowIsInFocus && iExtDisplayConnected)
             {
-            if(iExtDisplayConnected)
+            TRAPD(err, CreateExtDisplayHandlerL());
+            DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err);
+            if(err == KErrNone)
                 {
-                TRAPD(err, CreateExtDisplayHandlerL());
-                DEBUG_PRINTF2("CMediaClientVideoDisplayBody::AddDisplayWindowL CreateExtDisplayHandlerL error %d", err);
-                if(err == KErrNone)
-                    {
-                    SetWindowArrayPtr2Ext();
-                    User::LeaveIfError(RedrawWindows(aCropRegion));
-                    }
+                SetWindowArrayPtr2Ext();
+                User::LeaveIfError(RedrawWindows(aCropRegion));
                 }
             }
         
-        if(!iExtDisplayConnected || !iExtDisplayHandler)
+        if(!iSwitchedToExternalDisplay)
             {
             User::LeaveIfError(SetBackgroundSurface(winData, aCropRegion));
             }
@@ -190,25 +227,32 @@
 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
 	
 	if (pos >= 0)
-		{
-		if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler))
-			{
-			iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue);
+	    {
+	    if(IsSurfaceCreated() && !iSwitchedToExternalDisplay)
+            {
+            iClientWindows[pos].iWindow->RemoveBackgroundSurface(ETrue);
             // Make sure all window rendering has completed before proceeding
             RWsSession* ws = iClientWindows[pos].iWindow->Session();
             if (ws)
-              {
-              ws->Finish();
-              }
-			}
-		iClientWindows.Remove(pos);
-		
-		if(iClientWindows.Count() == 0 && iExtDisplayConnected && iExtDisplayHandler)
-		    {
-		    RemoveBackgroundSurface(ETrue);
-		    SetWindowArrayPtr2Client();
-		    RemoveExtDisplayHandler();
-		    }
+                {
+                ws->Finish();
+                }
+            }
+
+	    iClientWindows.Remove(pos);
+	    
+	    TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
+        UpdateFocus();
+
+        // if only window was just removed OR removal has moved us from in focus to out of focus
+        if((iClientWindows.Count() == 0 || prevClientWindowIsInFocus) && iSwitchedToExternalDisplay &&
+                !iClientWindowIsInFocus)
+            {
+            RemoveBackgroundSurface(ETrue);
+            SetWindowArrayPtr2Client();
+            RemoveExtDisplayHandler();
+            RedrawWindows(iCropRegion);
+            }
 		}
 	
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveDisplayWindow ---");
@@ -235,13 +279,18 @@
 	iAspectRatio = aAspectRatio;
 	iCropRegion = aCropRegion;
 	
+	if(iServerClient)
+	    {
+        iServerClient->SetSurface(iSurfaceId);
+	    }
+	
 	if (emitEvent && iEventHandler)
 		{
 		iEventHandler->MmsehSurfaceCreated(iDisplayId, iSurfaceId, iCropRect, iAspectRatio);
 		}
 
 	TInt err = KErrNone;
-    if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching)
+    if((iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching && iClientWindowIsInFocus)
         {
         if(iExtDisplayConnected && !iExtDisplayHandler)
             {
@@ -256,7 +305,7 @@
     
     err = RedrawWindows(aCropRegion);
     
-    DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCreated ---");
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCreated --- Return error %d", err);
 	return err;
 	}
 
@@ -296,7 +345,7 @@
 
         iSurfaceId = TSurfaceId::CreateNullId();
 
-        if(iExtDisplayConnected && iExtDisplayHandler)
+        if(iSwitchedToExternalDisplay)
             {
             SetWindowArrayPtr2Client();
             RemoveExtDisplayHandler();
@@ -315,26 +364,47 @@
 
     if (!IsSurfaceCreated())
 		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrNotSupproted");
 		return KErrNotSupported;
 		}
 
 	if (iSurfaceId != aSurfaceId)
 		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error KErrInUse");
 		return KErrInUse;
 		}
-	
-	iCropRect = aCropRect;
-	iAspectRatio = aAspectRatio;
-	
+
 	if (iEventHandler)
 		{
-		iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, iCropRect, iAspectRatio);
+		iEventHandler->MmsehSurfaceParametersChanged(iSurfaceId, aCropRect, aAspectRatio);
 		}
 
-	RedrawWindows(iCropRegion);
-	
-	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged ---");
-	return KErrNone;
+	TInt error = KErrNone;
+	if (iCropRect != aCropRect || iAspectRatio != aAspectRatio)
+		{
+		// We only need to redraw if the aspect ratio has changed, or the area of the video to
+		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
+		TBool redraw = EFalse;
+		if (iAspectRatio != aAspectRatio || SurfaceCropRectChangeRequiresRedraw(iCropRect, aCropRect, iCropRegion))
+			{
+			redraw = ETrue;
+			}
+
+		iCropRect = aCropRect;
+		iAspectRatio = aAspectRatio;
+
+		if (redraw)
+			{
+			error = RedrawWindows(iCropRegion);
+			}
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceParametersChanged - Surface parameters have not changed");
+		}
+
+	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceParametersChanged --- Return error %d", error);
+	return error;
 	}
 	
 TInt CMediaClientVideoDisplayBody::RedrawWindows(const TRect& aCropRegion)
@@ -363,7 +433,7 @@
 	return err;
 	}
 
-void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos)
+void CMediaClientVideoDisplayBody::UpdateCropRegionL(const TRect& aCropRegion, TInt aPos, TBool aRedrawIndividualWindow)
     {
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL +++");
 
@@ -374,14 +444,19 @@
         {
         if(prevCropRegion == aCropRegion)
             {
-            if(!iExtDisplayConnected || !iExtDisplayHandler)
+            if(!iSwitchedToExternalDisplay && aRedrawIndividualWindow)
                 {
                 User::LeaveIfError(SetBackgroundSurface(iClientWindows[aPos], aCropRegion));
                 }
             }
         else
             {
-            User::LeaveIfError(RedrawWindows(aCropRegion));
+			// We only need to redraw if the area of the video to display (i.e the
+			// intersection of client crop region and surface crop rectangle) has changed.
+			if (ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
+				{
+				User::LeaveIfError(RedrawWindows(aCropRegion));
+				}
             }
         }
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateCropRegionL ---");    
@@ -395,15 +470,29 @@
     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
 
+	if (!IsAutoScaleTypeValid(aScaleType))
+		{
+		User::Leave(KErrArgument);
+		}
+
     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
 	User::LeaveIfError(pos);
-	
-	iClientWindows[pos].iAutoScaleType = aScaleType;
-	iClientWindows[pos].iHorizPos = aHorizPos;
-	iClientWindows[pos].iVertPos = aVertPos;
 
-	UpdateCropRegionL(aCropRegion, pos);
-	
+	TBool parameterChanged = EFalse;
+	if (aScaleType != iClientWindows[pos].iAutoScaleType || aHorizPos != iClientWindows[pos].iHorizPos || aVertPos != iClientWindows[pos].iVertPos)
+		{
+		iClientWindows[pos].iAutoScaleType = aScaleType;
+		iClientWindows[pos].iHorizPos = aHorizPos;
+		iClientWindows[pos].iVertPos = aVertPos;
+		parameterChanged = ETrue;
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters have not changed");
+		}
+
+	UpdateCropRegionL(aCropRegion, pos, parameterChanged);
+
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetAutoScaleL ---");
 	}
 	
@@ -415,12 +504,26 @@
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
 
+	if (!IsRotationValid(aRotation))
+		{
+		User::Leave(KErrArgument);
+		}
+
     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
 	User::LeaveIfError(pos);
-	
-	iClientWindows[pos].iRotation = aRotation;
 
-    UpdateCropRegionL(aCropRegion, pos);
+	TBool parameterChanged = EFalse;
+	if (aRotation != iClientWindows[pos].iRotation)
+		{
+		iClientWindows[pos].iRotation = aRotation;
+		parameterChanged = ETrue;
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL - Rotation has not changed");
+		}
+
+    UpdateCropRegionL(aCropRegion, pos, parameterChanged);
 
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetRotationL ---");
 	}
@@ -450,11 +553,22 @@
 		User::Leave(KErrArgument);
 		}
 
-	iClientWindows[pos].iScaleWidth = aWidthPercentage;
-	iClientWindows[pos].iScaleHeight = aHeightPercentage;
-	iClientWindows[pos].iAutoScaleType = EAutoScaleNone;
-	
-    UpdateCropRegionL(aCropRegion, pos);
+	TBool parameterChanged = EFalse;
+	if (aWidthPercentage != iClientWindows[pos].iScaleWidth ||
+	    aHeightPercentage != iClientWindows[pos].iScaleHeight ||
+		EAutoScaleNone != iClientWindows[pos].iAutoScaleType)
+		{
+		iClientWindows[pos].iScaleWidth = aWidthPercentage;
+		iClientWindows[pos].iScaleHeight = aHeightPercentage;
+		iClientWindows[pos].iAutoScaleType = EAutoScaleNone;
+		parameterChanged = ETrue;
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters have not changed");
+		}
+
+    UpdateCropRegionL(aCropRegion, pos, parameterChanged);
 	
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetScaleFactorL ---");
 	}
@@ -476,23 +590,44 @@
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - aScaleType %d", aScaleType);
     DEBUG_PRINTF3("CMediaClientVideoDisplayBody::SetAutoScaleL - aHorizPos %d, aVertPos %d", aHorizPos, aVertPos);
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetAutoScaleL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
-	
+
+	if (!IsAutoScaleTypeValid(aScaleType))
+		{
+		User::Leave(KErrArgument);
+		}
+
     TRect prevCropRegion(iCropRegion);
 	iCropRegion = aCropRegion;
+	
+	TBool parameterChanged;
 	TInt count = iClientWindows.Count();
-	
+
 	for (TInt i = 0; i < count; ++i)
 		{
-		iClientWindows[i].iAutoScaleType = aScaleType;
-		iClientWindows[i].iHorizPos = aHorizPos;
-		iClientWindows[i].iVertPos = aVertPos;
-	    if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler))
+		parameterChanged = EFalse;
+		if (aScaleType != iClientWindows[i].iAutoScaleType || aHorizPos != iClientWindows[i].iHorizPos || aVertPos != iClientWindows[i].iVertPos)
+			{
+			iClientWindows[i].iAutoScaleType = aScaleType;
+			iClientWindows[i].iHorizPos = aHorizPos;
+			iClientWindows[i].iVertPos = aVertPos;
+			parameterChanged = ETrue;
+			}
+		else
+			{
+			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetAutoScaleL - Scale parameters for window pos %d have not changed", i);
+			}
+
+		// We only need to redraw if the scale parameters have changed, or the area of the video
+		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
+		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
 			{
 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
 			}
 		}
-	
-	if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion))
+
+	// We only need to redraw if the area of the video to display (i.e the
+	// intersection of client crop region and surface crop rectangle) has changed.
+	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
         {
         User::LeaveIfError(RedrawWindows(aCropRegion));
         }
@@ -506,20 +641,41 @@
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - aRotation %d", aRotation);
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetRotationL - aCropRegion %d,%d - %d,%d", aCropRegion.iTl.iX, aCropRegion.iTl.iY, aCropRegion.iBr.iX, aCropRegion.iBr.iY);
 
+	if (!IsRotationValid(aRotation))
+		{
+		User::Leave(KErrArgument);
+		}
+
     TRect prevCropRegion(iCropRegion);
     iCropRegion = aCropRegion;
+
+	TBool parameterChanged;
 	TInt count = iClientWindows.Count();
 	
 	for (TInt i = 0; i < count; ++i)
 		{
-		iClientWindows[i].iRotation = aRotation;
-        if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler))
+		parameterChanged = EFalse;
+		if (aRotation != iClientWindows[i].iRotation)
+			{
+			iClientWindows[i].iRotation = aRotation;
+			parameterChanged = ETrue;
+			}
+		else
+			{
+			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetRotationL - Rotation for window pos %d has not changed", i);
+			}
+
+		// We only need to redraw if the scale parameters have changed, or the area of the video
+		// to display (i.e the intersection of client crop region and surface crop rectangle) has changed.
+		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
 			{
 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
 			}
 		}
 	
-    if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion))
+	// We only need to redraw if the area of the video to display (i.e the
+	// intersection of client crop region and surface crop rectangle) has changed.
+	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
         {
         User::LeaveIfError(RedrawWindows(aCropRegion));
         }
@@ -540,20 +696,39 @@
 	
     TRect prevCropRegion(iCropRegion);
 	iCropRegion = aCropRegion;
+
+	TBool parameterChanged;
 	TInt count = iClientWindows.Count();
 	
 	for (TInt i = 0; i < count; ++i)
 		{
-		iClientWindows[i].iScaleWidth = aWidthPercentage;
-		iClientWindows[i].iScaleHeight = aHeightPercentage;
-		iClientWindows[i].iAutoScaleType = EAutoScaleNone;
-        if (IsSurfaceCreated() && (!iExtDisplayConnected || !iExtDisplayHandler))
+		parameterChanged = EFalse;
+		
+		if (aWidthPercentage != iClientWindows[i].iScaleWidth ||
+		    aHeightPercentage != iClientWindows[i].iScaleHeight ||
+			EAutoScaleNone != iClientWindows[i].iAutoScaleType)
+			{
+			iClientWindows[i].iScaleWidth = aWidthPercentage;
+			iClientWindows[i].iScaleHeight = aHeightPercentage;
+			iClientWindows[i].iAutoScaleType = EAutoScaleNone;
+			parameterChanged = ETrue;
+			}
+		else
+			{
+			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetScaleFactorL - Scale parameters for window pos %d have not changed", i);
+			}
+
+		// We only need to redraw if the scale parameters have changed, or the area of the video to
+		// display (i.e the intersection of client crop region and surface crop rectangle) has changed.
+		if (IsSurfaceCreated() && !iSwitchedToExternalDisplay && (parameterChanged || ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect)))
 			{
 			User::LeaveIfError(SetBackgroundSurface(iClientWindows[i], aCropRegion));
 			}
 		}
-	
-    if (IsSurfaceCreated() && iExtDisplayConnected && iExtDisplayHandler && (aCropRegion != prevCropRegion))
+
+	// We only need to redraw if the area of the video to display (i.e the
+	// intersection of client crop region and surface crop rectangle) has changed.
+	if (IsSurfaceCreated() && iSwitchedToExternalDisplay && ClientCropRegionChangeRequiresRedraw(prevCropRegion, aCropRegion, iCropRect))
         {
         User::LeaveIfError(RedrawWindows(aCropRegion));
         }
@@ -570,10 +745,24 @@
 	
 	TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
 	User::LeaveIfError(pos);
-	
-	iClientWindows[pos].iClipRect = aWindowClipRect;
 
-    UpdateCropRegionL(aCropRegion, pos);
+	TBool parameterChanged = EFalse;
+	if (aWindowClipRect != iClientWindows[pos].iClipRect)
+		{
+		// We only want to redraw if the change in the clipping rectangle would result
+		// in a change to the area of the display used for the video.
+		// The video is always displayed in the intersection of the clipping rectangle
+		// and the video extent, so check if this has changed.
+		parameterChanged = IntersectionAreaChanged(iClientWindows[pos].iClipRect, aWindowClipRect, iClientWindows[pos].iVideoExtent);
+
+		iClientWindows[pos].iClipRect = aWindowClipRect;
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL - Clip rect parameter has not changed");
+		}
+
+    UpdateCropRegionL(aCropRegion, pos, parameterChanged);
 
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowClipRectL ---");
 	}
@@ -587,10 +776,19 @@
 
     TInt pos = iClientWindows.Find(aWindow.WsHandle(), TWindowData::CompareByWsHandle);
 	User::LeaveIfError(pos);
-	
-	iClientWindows[pos].iVideoExtent = aVideoExtent;
 
-    UpdateCropRegionL(aCropRegion, pos);
+	TBool parameterChanged = EFalse;
+	if (aVideoExtent != iClientWindows[pos].iVideoExtent)
+		{
+		iClientWindows[pos].iVideoExtent = aVideoExtent;
+		parameterChanged = ETrue;
+		}
+	else
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL - Video extent parameter has not changed");
+		}
+
+    UpdateCropRegionL(aCropRegion, pos, parameterChanged);
     
 	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetVideoExtentL ---");
 	}
@@ -656,8 +854,8 @@
             break;
         default:
             // Should never get to default unless there's been some programming error.
-            User::Invariant();
-            break;
+			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
+			return KErrArgument;
         }
     
     TReal32 viewportAspect = pixelAspectRatio * inputWidth / inputHeight;
@@ -828,8 +1026,8 @@
         break;
     default:
         // Should never get to default unless there's been some programming error.
-        User::Invariant();
-        break;
+		DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetBackgroundSurface --- Returned with error %d", KErrArgument);
+        return KErrArgument;
     }
     
     DEBUG_PRINTF5("CMediaClientVideoDisplayBody::SetBackgroundSurface - viewport2 %d,%d - %d,%d", viewport.iTl.iX, viewport.iTl.iY, viewport.iBr.iX, viewport.iBr.iY);
@@ -924,8 +1122,9 @@
 		    break;
 		default:
 			// Should never get to default unless there's been some programming error.
-			User::Invariant();
-			// This is never reached, just to keep the compiler happy
+			DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- Failed due to %d bad aRotation argument", aRotation);
+			__ASSERT_DEBUG(FALSE, User::Invariant());
+			// Use the normal option otherwise
 			orientation = CFbsBitGc::EGraphicsOrientationNormal;
 		}
     DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ConvertRotation --- return %d", orientation);	
@@ -978,34 +1177,8 @@
 
     if(iClientRequestedExtDisplaySwitching != aControl)
         {
-        iClientRequestedExtDisplaySwitching = aControl;
-        
-        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL SurfaceCreated %d", IsSurfaceCreated());
-        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL Client window count %d", iClientWindows.Count());
-        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL External Display Connected %d", iExtDisplayConnected);          
-        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching);          
-        
-        if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iExtDisplayConnected)
-            {
-            if(iClientRequestedExtDisplaySwitching)
-                {
-                TRAPD(err, CreateExtDisplayHandlerL());
-                DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL CreateExtDisplayHandlerL error %d", err);
-                if(err == KErrNone)
-                    {
-                    RemoveBackgroundSurface(ETrue);
-                    SetWindowArrayPtr2Ext();
-                    RedrawWindows(iCropRegion);
-                    }
-                }
-            else if(iExtDisplayHandler)
-                {
-                RemoveBackgroundSurface(ETrue);
-                RemoveExtDisplayHandler();
-                SetWindowArrayPtr2Client();
-                RedrawWindows(iCropRegion);
-                }
-            }
+        iClientRequestedExtDisplaySwitching = aControl;     
+        SwitchSurface();
         }
     
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetExternalDisplaySwitchingL ---");
@@ -1018,28 +1191,7 @@
 	if(iExtDisplayConnected != aExtDisplayConnected)
 	    {
 	    iExtDisplayConnected = aExtDisplayConnected;
-
-        if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching)
-            {
-            if(iExtDisplayConnected)
-                {
-                TRAPD(err, CreateExtDisplayHandlerL());
-                DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MedcpcExtDisplayNotifyConnected CreateExtDisplayHandlerL error %d", err);
-                if(err == KErrNone)
-                    {
-                    RemoveBackgroundSurface(ETrue);
-                    SetWindowArrayPtr2Ext();
-                    RedrawWindows(iCropRegion);
-                    }
-                }
-            else if(iExtDisplayHandler)
-                {
-                RemoveBackgroundSurface(ETrue);
-                RemoveExtDisplayHandler();
-                SetWindowArrayPtr2Client();
-                RedrawWindows(iCropRegion);
-                }
-            }
+        SwitchSurface();
 	    }
 	else
 	    {
@@ -1054,6 +1206,7 @@
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client +++");
 
     iWindowsArrayPtr = &iClientWindows;
+    iSwitchedToExternalDisplay = EFalse;
 
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Client ---");
     }
@@ -1063,6 +1216,7 @@
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext +++");
 
     iWindowsArrayPtr = &iExtDisplayWindows;
+    iSwitchedToExternalDisplay = ETrue;
 
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::SetWindowArrayPtr2Ext ---");
     }
@@ -1136,3 +1290,228 @@
         }    
     DEBUG_PRINTF("CMediaClientVideoDisplayBody::RemoveExtDisplayPlugin ---");
     }
+
+void CMediaClientVideoDisplayBody::MmcweoFocusWindowGroupChanged()
+    {
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged +++");
+    
+    TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
+    UpdateFocus();
+    
+    if(prevClientWindowIsInFocus != iClientWindowIsInFocus)
+        {
+        SwitchSurface();
+        }
+    
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged ---");
+    }
+
+TBool CMediaClientVideoDisplayBody::MmcweoIgnoreProcess(TSecureId aId)
+    {
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess +++");
+    
+    TBool ignore = ETrue;
+    if (iServerClient)
+        {
+        ignore = iServerClient->IgnoreProcess(aId);
+        }
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MmcweoIgnoreProcess --- return %d", ignore);
+    return ignore;
+    }
+
+void CMediaClientVideoDisplayBody::UpdateFocus()
+    {
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus +++");
+    
+    if(!iWsEventObserver)
+        {
+        iClientWindowIsInFocus = ETrue;
+        DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Event Observer is NULL");
+        DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
+        return;
+        }
+    
+    TBool prevClientWindowIsInFocus = iClientWindowIsInFocus;
+    
+    TInt focusGroupId;
+    if(iWsEventObserver->FocusWindowGroupId(focusGroupId) == KErrNone)
+        {
+        iClientWindowIsInFocus = EFalse;
+        TInt count = iClientWindows.Count();
+        for(TInt i = 0; i < count; i++)
+            {
+            if(iClientWindows[i].iWindow->WindowGroupId() == focusGroupId)
+                {
+                iClientWindowIsInFocus = ETrue;
+                break;
+                }
+            }
+        }
+    else
+        {
+        DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus Error retrieving focus WgId from observer");
+        iClientWindowIsInFocus = ETrue;
+        }
+
+    if(iServerClient && (prevClientWindowIsInFocus != iClientWindowIsInFocus))
+        {
+        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::MweocFocusWindowGroupChanged calling server, focus %d", iClientWindowIsInFocus);
+        iServerClient->FocusChanged(iClientWindowIsInFocus);
+        }
+    
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::UpdateFocus Client window in focus %d", iClientWindowIsInFocus);
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::UpdateFocus ---");
+    }
+
+void CMediaClientVideoDisplayBody::SwitchSurface()
+    {
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface +++");
+
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface SurfaceCreated %d", IsSurfaceCreated());
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client window count %d", iClientWindows.Count());
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Requested Ext Display Switching %d", iClientRequestedExtDisplaySwitching);
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface Client Window in Focus %d", iClientWindowIsInFocus);
+    DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface External Display Connected %d", iExtDisplayConnected);
+
+    if(IsSurfaceCreated() && (iClientWindows.Count() > 0) && iClientRequestedExtDisplaySwitching &&
+            iClientWindowIsInFocus && iExtDisplayConnected)
+        {
+        TRAPD(err, CreateExtDisplayHandlerL());
+        DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SwitchSurface CreateExtDisplayHandlerL error %d", err);
+        if(err == KErrNone)
+            {
+            // Set background surface for external display window before removing from client windows.
+            // Required for switching of paused video
+            SetWindowArrayPtr2Ext();
+            RedrawWindows(iCropRegion);
+            SetWindowArrayPtr2Client();
+            RemoveBackgroundSurface(ETrue);
+            SetWindowArrayPtr2Ext();
+            }
+        }
+    else if(iSwitchedToExternalDisplay)
+        {
+        // Set background surface for clientwindows before removing from external display window.
+        // Required for switching of paused video
+        SetWindowArrayPtr2Client();
+        RedrawWindows(iCropRegion);
+        SetWindowArrayPtr2Ext();
+        RemoveBackgroundSurface(ETrue);
+        RemoveExtDisplayHandler();
+        SetWindowArrayPtr2Client();
+        }
+
+    DEBUG_PRINTF("CMediaClientVideoDisplayBody::SwitchSurface ---");
+    }
+
+TBool CMediaClientVideoDisplayBody::IsRotationValid(TVideoRotation aVideoRotation)
+	{
+	if (aVideoRotation == EVideoRotationNone ||
+	    aVideoRotation == EVideoRotationClockwise90 ||
+		aVideoRotation == EVideoRotationClockwise180 ||
+		aVideoRotation == EVideoRotationClockwise270)
+		{
+		return ETrue;
+		}
+
+	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsRotationValid - Rotation %d not valid", aVideoRotation);
+	return EFalse;
+	}
+
+TBool CMediaClientVideoDisplayBody::IsAutoScaleTypeValid(TAutoScaleType aAutoScaleType)
+	{
+	if (aAutoScaleType == EAutoScaleNone ||
+	    aAutoScaleType == EAutoScaleBestFit ||
+	    aAutoScaleType == EAutoScaleClip ||
+	    aAutoScaleType == EAutoScaleStretch)
+		{
+		return ETrue;
+		}
+
+	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::IsAutoScaleTypeValid - Auto scale %d not valid", aAutoScaleType);
+	return EFalse;
+	}
+
+/**
+Check whether a change in the surface crop rectangle would mean that the surface viewport calculated in SetBackgroundSurface would change.
+The surface viewport is the intersection of the surface crop rectangle and the client crop region
+*/
+TBool CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw(TRect aOldSurfaceCropRect, TRect aNewSurfaceCropRect, TRect aClientCropRegion)
+	{
+	DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw +++");
+	
+	// If aClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
+	// This means that only aOldSurfaceCropRect is being used to decide which part of the video is displayed.
+	// By setting aClientCropRect to the same as aOldSurfaceCropRect we ensure that only aOldSurfaceCropRect is
+	// used in the subsequent intersection area checks.
+	if (aClientCropRegion.IsEmpty())
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw - Client crop region is empty");		
+		aClientCropRegion = aOldSurfaceCropRect;
+		}
+
+	TBool ret = IntersectionAreaChanged(aOldSurfaceCropRect, aNewSurfaceCropRect, aClientCropRegion);
+
+	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::SurfaceCropRectChangeRequiresRedraw --- ret = %d", ret);
+
+	return ret;
+	}
+
+/**
+Check whether a change in the client crop region would mean that the surface viewport calculated in SetBackgroundSurface would change.
+The surface viewport is the intersection of the surface crop rectangle and the client crop region
+*/
+TBool CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw(TRect aOldClientCropRegion, TRect aNewClientCropRegion, TRect aSurfaceCropRect)
+	{
+	DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw +++");
+
+	// If aOldClientCropRegion is empty then it is not currently being used in the SetBackgroundSurface calculations.
+	// This means that only aSurfaceCropRect is being used to decide which part of the video is displayed. By
+	// setting aOldClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
+	// used in the subsequent intersection area checks.
+	if (aOldClientCropRegion.IsEmpty())
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - Old client crop region is empty");
+		aOldClientCropRegion = aSurfaceCropRect;
+		}
+
+	// If aNewClientCropRegion is empty then it will not be used in the SetBackgroundSurface calculations.
+	// This means that only aSurfaceCropRect will impact which part of the video is displayed. By
+	// setting aNewClientCropRegion to the same as aSurfaceCropRect we ensure that only aSurfaceCropRect is
+	// used in the subsequent intersection area checks.
+	if (aNewClientCropRegion.IsEmpty())
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw - New client crop region is empty");
+		aNewClientCropRegion = aSurfaceCropRect;
+		}
+
+	TBool ret = IntersectionAreaChanged(aOldClientCropRegion, aNewClientCropRegion, aSurfaceCropRect);
+
+	DEBUG_PRINTF2("CMediaClientVideoDisplayBody::ClientCropRegionChangeRequiresRedraw --- ret = %d", ret);
+
+	return ret;
+	}
+
+/**
+Check whether the change in size of a rectangle means its intersection with another rectangle has changed.
+This is used to check whether changes in things like the surface crop rectangle, client crop region, and window clip rectangle, would mean
+the area of video displayed would change.
+*/
+TBool CMediaClientVideoDisplayBody::IntersectionAreaChanged(TRect aOldRect, TRect aNewRect, TRect aOtherRect)
+	{
+	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOldRect %d,%d - %d,%d", aOldRect.iTl.iX, aOldRect.iTl.iY, aOldRect.iBr.iX, aOldRect.iBr.iY);
+	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aNewRect %d,%d - %d,%d", aNewRect.iTl.iX, aNewRect.iTl.iY, aNewRect.iBr.iX, aNewRect.iBr.iY);
+	DEBUG_PRINTF5("CMediaClientVideoDisplayBody::IntersectionAreaChanged - aOtherRect %d,%d - %d,%d", aOtherRect.iTl.iX, aOtherRect.iTl.iY, aOtherRect.iBr.iX, aOtherRect.iBr.iY);
+
+	aOldRect.Intersection(aOtherRect);
+	aNewRect.Intersection(aOtherRect);
+
+	if (aOldRect != aNewRect)
+		{
+		DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged - Intersection area has changed");
+		return ETrue;
+		}
+
+	DEBUG_PRINTF("CMediaClientVideoDisplayBody::IntersectionAreaChanged - Intersection area has not changed");
+	return EFalse;
+	}
--- a/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientvideodisplaybody.h	Mon May 03 13:56:28 2010 +0300
@@ -17,6 +17,7 @@
 #define MEDIACLIENTVIDEODISPLAYBODY_H
 
 #include "mediaclientextdisplayhandler.h"
+#include "mediaclientwseventobserver.h"
 #include <graphics/surface.h>
 #include <graphics/surfaceconfiguration.h>
 #include <mmf/common/mmfvideosurfacecustomcommands.h>
@@ -24,13 +25,15 @@
 #include <mmf/plugin/mmfmediaclientextdisplayinterface.h>
 
 class MMMFSurfaceEventHandler;
+class CMediaClientPolicyServerClient;
 
 /**
 @internalTechnology
 @released
 
 */
-NONSHARABLE_CLASS(CMediaClientVideoDisplayBody) : public CBase, public MExtDisplayConnectionProviderCallback
+NONSHARABLE_CLASS(CMediaClientVideoDisplayBody) : public CBase, public MExtDisplayConnectionProviderCallback,
+public MMediaClientWsEventObserverCallback
 	{
 private:
 	NONSHARABLE_CLASS(TWindowData)
@@ -143,15 +146,27 @@
 	TInt SetBackgroundSurface(TWindowData& aWindowData, const TRect& aCropRegion);
 	TBool HasWindows() const;
 	
-    void MedcpcExtDisplayNotifyConnected(TBool aExtDisplayConnected);
-
-    void UpdateCropRegionL(const TRect& aCropRegion, TInt aPos);
+    void UpdateCropRegionL(const TRect& aCropRegion, TInt aPos, TBool aRedrawIndividualWindow);
     void CreateExtDisplayPluginL();
     void RemoveExtDisplayPlugin();
     void CreateExtDisplayHandlerL();
     void RemoveExtDisplayHandler();
     void SetWindowArrayPtr2Client();
     void SetWindowArrayPtr2Ext();
+    void SwitchSurface();
+    void UpdateFocus();
+	TBool IsRotationValid(TVideoRotation aVideoRotation);
+	TBool IsAutoScaleTypeValid(TAutoScaleType aAutoScaleType);
+	TBool SurfaceCropRectChangeRequiresRedraw(TRect aOldSurfaceCropRect, TRect aNewSurfaceCropRect, TRect aClientCropRegion);
+	TBool ClientCropRegionChangeRequiresRedraw(TRect aOldClientCropRegion, TRect aNewClientCropRegion, TRect aSurfaceCropRect);
+	TBool IntersectionAreaChanged(TRect aOldRect, TRect aNewRect, TRect aOtherRect);
+
+    // MExtDisplayConnectionProviderCallback
+    void MedcpcExtDisplayNotifyConnected(TBool aExtDisplayConnected);
+
+    // MMediaClientWsEventObserverCallback
+    void MmcweoFocusWindowGroupChanged();
+    TBool MmcweoIgnoreProcess(TSecureId aId);
     
 private:
 
@@ -164,14 +179,19 @@
 	RArray<TWindowData> iClientWindows;
 	RArray<TWindowData> iExtDisplayWindows;
 	RArray<TWindowData>* iWindowsArrayPtr;
+	TBool iSwitchedToExternalDisplay;
 	
 	TRect iCropRegion;
 	TBool iClientRequestedExtDisplaySwitching;
 	CExtDisplayConnectionProviderInterface* iExtDisplayConnectionProvider;
 	CMediaClientExtDisplayHandler* iExtDisplayHandler;
+	CMediaClientWsEventObserver* iWsEventObserver;
+	TBool iClientWindowIsInFocus;
     TBool iExtDisplayConnected;
     TBool iExtDisplaySwitchingSupported;
 	
+    CMediaClientPolicyServerClient* iServerClient;
+    
 	friend class CVideoPlayerUtility::CBody;	
 	friend class CTestStepUnitMMFVidClient;
 	};
--- a/mmlibs/mmfw/src/Client/Video/mediaclientvideotrace.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientvideotrace.h	Mon May 03 13:56:28 2010 +0300
@@ -18,7 +18,7 @@
 #ifndef MEDIACLIENTVIDEOTRACE_H_
 #define MEDIACLIENTVIDEOTRACE_H_
 
-#ifdef __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
+#ifdef _DEBUG
 
 #include <e32debug.h>
 
@@ -28,7 +28,7 @@
 #define DEBUG_PRINTF4(a,b,c,d) RDebug::Printf(a,b,c,d)
 #define DEBUG_PRINTF5(a, b, c, d, e) RDebug::Printf(a,b,c,d,e)
 
-#else // __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
+#else // _DEBUG
 
 #define DEBUG_PRINTF(a)
 #define DEBUG_PRINTF2(a, b)
@@ -36,6 +36,6 @@
 #define DEBUG_PRINTF4(a, b, c, d)
 #define DEBUG_PRINTF5(a, b, c, d, e)
 
-#endif // __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
+#endif // _DEBUG
 
 #endif // MEDIACLIENTVIDEOTRACE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientwseventobserver.cpp	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,177 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "mediaclientwseventobserver.h"
+#include "mediaclientvideotrace.h"
+
+CMediaClientWsEventObserver* CMediaClientWsEventObserver::NewL(MMediaClientWsEventObserverCallback& aCallback)
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::NewL +++");
+    CMediaClientWsEventObserver* self = new (ELeave) CMediaClientWsEventObserver(aCallback);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    DEBUG_PRINTF("CMediaClientWsEventObserver::NewL ---");
+    return self;
+    }
+
+CMediaClientWsEventObserver::CMediaClientWsEventObserver(MMediaClientWsEventObserverCallback& aCallback) :
+CActive(EPriorityStandard),
+iCallback(aCallback)
+    {   
+    DEBUG_PRINTF("CMediaClientWsEventObserver::CMediaClientWsEventObserver +++"); 
+    DEBUG_PRINTF("CMediaClientWsEventObserver::CMediaClientWsEventObserver ---");
+    }
+
+void CMediaClientWsEventObserver::ConstructL()
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL +++");
+    
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL RWsSession Connect");
+    TInt err = iWs.Connect();
+    if (err != KErrNone)
+        {
+        DEBUG_PRINTF2("CMediaClientWsEventObserver::ConstructL Windows Server unavailable, err %d", err);
+        User::Leave(err);
+        }
+    
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL RWindowGroup Create");
+    iWindowGroup = RWindowGroup(iWs);
+    User::LeaveIfError(iWindowGroup.Construct((TUint32)this, EFalse));
+
+    // Send created window to the background and hide it from the
+    // application switcher    
+    iWindowGroup.SetOrdinalPosition( -1, -1000 ); // -1000 = ECoeWinPriorityNeverAtFront
+
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL RWindowGroup EnableFocusChangeEvents");
+    User::LeaveIfError(iWindowGroup.EnableFocusChangeEvents());
+    
+    UpdateFocusWindowGroupId(ETrue);
+    DEBUG_PRINTF3("CMediaClientWsEventObserver::ConstructL Initial WgId %d Error %d", iWgId, iWgIdError);
+
+    CActiveScheduler::Add(this);
+
+    // register with window server to receive focus change notifications
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL iWs.EventReady()");
+    iWs.EventReady(&iStatus);
+
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL SetActive()");
+    SetActive();
+    
+    DEBUG_PRINTF("CMediaClientWsEventObserver::ConstructL ---");
+    }
+
+CMediaClientWsEventObserver::~CMediaClientWsEventObserver()
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::~CMediaClientWsEventObserver +++");
+
+    Cancel();
+
+    iWindowGroup.Close();
+    
+    iWs.Close();
+    
+    DEBUG_PRINTF("CMediaClientWsEventObserver::~CMediaClientWsEventObserver ---");
+    }
+
+TInt CMediaClientWsEventObserver::FocusWindowGroupId(TInt& aFocusGroupId)
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::FocusWindowGroupId +++");
+    aFocusGroupId = iWgId;
+    DEBUG_PRINTF3("CMediaClientWsEventObserver::FocusWindowGroupId --- WgId %d, Error %d", iWgId, iWgIdError);
+    return iWgIdError;
+    }
+
+void CMediaClientWsEventObserver::UpdateFocusWindowGroupId(TBool aConstruction)
+    {
+    DEBUG_PRINTF2("CMediaClientWsEventObserver::UpdateFocusWindowGroupId +++, construction %d", aConstruction);
+    
+    TInt wgId = iWs.GetFocusWindowGroup();
+    DEBUG_PRINTF2("CMediaClientWsEventObserver::UpdateFocusWindowGroupId id %d ", wgId);
+
+    // get the thread that owns windowgroup id
+    TThreadId threadId;
+    iWgIdError = iWs.GetWindowGroupClientThreadId(wgId, threadId);
+    if(iWgIdError != KErrNone)
+        {
+        DEBUG_PRINTF2("CMediaClientWsEventObserver::UpdateFocusWindowGroupId --- Get Thread Id error %d", iWgIdError);
+        return;
+        }
+    
+    RThread thread;    
+    iWgIdError = thread.Open(threadId);
+    if(iWgIdError != KErrNone)
+        {
+        DEBUG_PRINTF2("CMediaClientWsEventObserver::UpdateFocusWindowGroupId --- Open thread error %d", iWgIdError);
+        return;
+        }
+    
+    TSecureId fgThreadId = thread.SecureId();
+    thread.Close();
+    
+    if(iCallback.MmcweoIgnoreProcess(fgThreadId))
+        {
+        // If ignore returns ETrue during construction the previous value of iWgId does not contain a valid id. It is 0.
+        // This is an error case so set error flag accordingly.
+        if(aConstruction)
+            {
+            iWgIdError = KErrNotSupported;    
+            }
+        }
+    else
+        {
+        iWgId = wgId;
+        }
+
+    DEBUG_PRINTF("CMediaClientWsEventObserver::UpdateFocusWindowGroupId --- ");
+    }
+
+void CMediaClientWsEventObserver::RunL()
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::RunL +++");
+
+    iWs.GetEvent(iEvent);    
+
+    DEBUG_PRINTF("CMediaClientWsEventObserver::RunL EventReady()");
+    iWs.EventReady(&iStatus);
+    DEBUG_PRINTF("CMediaClientWsEventObserver::RunL SetActive()");
+    SetActive();
+
+    DEBUG_PRINTF2("CMediaClientWsEventObserver::RunL() Ws event.Type %d", iEvent.Type());
+    if(iEvent.Type() == EEventFocusGroupChanged)
+        {
+        DEBUG_PRINTF("CMediaClientWsEventObserver::RunL Received EEventFocusGroupChanged");
+        
+        TInt prevWgId = iWgId;
+        UpdateFocusWindowGroupId(EFalse);
+        if((iWgIdError != KErrNone) || (iWgId != prevWgId))
+            {
+            iCallback.MmcweoFocusWindowGroupChanged();
+            }
+        }
+    else
+        {
+        DEBUG_PRINTF("CMediaClientWsEventObserver::RunL Event Ignored");
+        }
+
+    DEBUG_PRINTF("CMediaClientWsEventObserver::RunL ---");
+    }
+
+void CMediaClientWsEventObserver::DoCancel()
+    {
+    DEBUG_PRINTF("CMediaClientWsEventObserver::DoCancel +++");
+    iWs.EventReadyCancel();
+    DEBUG_PRINTF("CMediaClientWsEventObserver::DoCancel ---");
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Client/Video/mediaclientwseventobserver.h	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef MEDIACLIENTWSEVENTOBSERVER_H
+#define MEDIACLIENTWSEVENTOBSERVER_H
+
+#include <e32base.h> 
+#include <w32std.h> 
+
+class MMediaClientWsEventObserverCallback
+    {
+public:
+    virtual void MmcweoFocusWindowGroupChanged() = 0;
+    virtual TBool MmcweoIgnoreProcess(TSecureId aId) = 0;
+    };
+
+NONSHARABLE_CLASS(CMediaClientWsEventObserver) : public CActive
+    {
+public:
+    static CMediaClientWsEventObserver* NewL(MMediaClientWsEventObserverCallback& aCallback);
+    ~CMediaClientWsEventObserver();
+    
+    TInt FocusWindowGroupId(TInt& aFocusGroupId);
+    
+    // from CActive
+    void RunL();
+    void DoCancel();
+    
+private:
+    CMediaClientWsEventObserver(MMediaClientWsEventObserverCallback& aCallback);
+    void ConstructL();
+    void UpdateFocusWindowGroupId(TBool aConstruction);
+    
+private:
+    RWsSession iWs;
+    RWindowGroup iWindowGroup;
+    MMediaClientWsEventObserverCallback& iCallback;
+    TWsEvent iEvent;
+    TInt iWgId;
+    TInt iWgIdError; 
+    };
+
+#endif // MEDIACLIENTWSEVENTOBSERVER_H
+
--- a/mmlibs/mmfw/src/Client/Video/mmfclientvideoplayerbody.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Client/Video/mmfclientvideoplayerbody.cpp	Mon May 03 13:56:28 2010 +0300
@@ -171,6 +171,7 @@
 #ifdef SYMBIAN_BUILD_GCE
 	,iGlobalScaleWidth(100.0f),
 	iGlobalScaleHeight(100.0f),
+	iGlobalAutoScaleType(EAutoScaleBestFit),  // Really need some platform specific way of defining this. Not everyone will want it.
 	iGlobalHorizPos(EHorizontalAlignCenter),
 	iGlobalVertPos(EVerticalAlignCenter)
 #endif
@@ -753,7 +754,15 @@
 				if (window.iRotation != aRotation)
 					{
 					// update config only if setting has actually changed
-					UpdateSurfaceAndSubtitleConfigL(*display, window, window.iClipRect, aRotation, iCropRegion);
+					display->SetRotationL(*window.iWindow, aRotation, iCropRegion);
+
+					if (iSubtitleUtility)
+						{
+						TMMFSubtitleWindowConfig config;
+						GetSubtitleConfigFromWindowData(window, config);
+
+						iSubtitleUtility->UpdateSubtitleConfig(config);
+						}
 					}
 				}
 #else
@@ -857,9 +866,11 @@
 		// Crop region setting is not sent to controller when graphics surfaces are used.
 		// If the surface has been created, perform crop region with the help of graphics surfaces;
 		// otherwise, just store the crop region info.
-		
-		iCropRegion = aCropRegion;
-		User::LeaveIfError(SetAllBackgroundSurfaces());
+		if (aCropRegion != iCropRegion)
+			{
+			iCropRegion = aCropRegion;
+			User::LeaveIfError(SetAllBackgroundSurfaces());
+			}
 		}
 #else
 	User::LeaveIfError(iVideoPlayControllerCustomCommands.SetCropRegion(aCropRegion));
@@ -1245,11 +1256,9 @@
 	TInt error2 = KErrNone;
 	for (TInt i = 0; i < count; ++i)
 		{
-		// ignore error and continue to set parameters
-		iActiveDisplays[i]->SurfaceParametersChanged(surfaceId, cropRect, aspectRatio);
+		error2 = iActiveDisplays[i]->SurfaceParametersChanged(surfaceId, cropRect, aspectRatio);
 		
-		// save the error for the first failure and attempt to redraw remaining displays
-		error2 = iActiveDisplays[i]->RedrawWindows(iCropRegion);
+		// Save the error for the first failure only
 		if ((error2 != KErrNone) && (error == KErrNone))
 			{
 			error = error2;
@@ -1745,7 +1754,15 @@
 	if (currentWin.iClipRect != aWindowClipRect)
 		{
 		// update config only if setting has actually changed
-		UpdateSurfaceAndSubtitleConfigL(*display, currentWin, aWindowClipRect, currentWin.iRotation, iCropRegion);
+		display->SetWindowClipRectL(aWindow, aWindowClipRect, iCropRegion);
+
+		if (iSubtitleUtility)
+			{
+			TMMFSubtitleWindowConfig config;
+			GetSubtitleConfigFromWindowData(currentWin, config);
+
+			iSubtitleUtility->UpdateSubtitleConfig(config);
+			}
 		}
 #else
 	display->SetWindowClipRectL(aWindow, aWindowClipRect, iCropRegion);
@@ -1822,7 +1839,15 @@
 	CMediaClientVideoDisplayBody::TWindowData& currentWin = windows[pos];
 	if (currentWin.iRotation != aRotation)
 		{
-		UpdateSurfaceAndSubtitleConfigL(*display, currentWin, currentWin.iClipRect, aRotation, iCropRegion);
+		display->SetRotationL(aWindow, aRotation, iCropRegion);
+
+		if (iSubtitleUtility)
+			{
+			TMMFSubtitleWindowConfig config;
+			GetSubtitleConfigFromWindowData(currentWin, config);
+
+			iSubtitleUtility->UpdateSubtitleConfig(config);
+			}
 		}
 #else
 	display->SetRotationL(aWindow, aRotation, iCropRegion);
@@ -2172,38 +2197,6 @@
 	return NULL;
 	}
 
-// Update the supplied window with the new clip rect and rotation
-// If updating of surface failed, this function leave after restoring the original aWindowData
-void CVideoPlayerUtility::CBody::UpdateSurfaceAndSubtitleConfigL(CMediaClientVideoDisplayBody& aDisplay,CMediaClientVideoDisplayBody::TWindowData& aWindowData, const TRect& aClipRect, TVideoRotation aRotation, const TRect& aCropRegion)
-	{
-	TRect oldClipRect = aWindowData.iClipRect;
-	TVideoRotation oldRotation = aWindowData.iRotation;
-	
-	aWindowData.iClipRect = aClipRect;
-	aWindowData.iRotation = aRotation;
-	
-	if (aDisplay.IsSurfaceCreated())
-		{
-		TInt err = aDisplay.SetBackgroundSurface(aWindowData, aCropRegion);
-		if (KErrNone != err)
-			{
-			aWindowData.iClipRect = oldClipRect;
-			aWindowData.iRotation = oldRotation;
-			User::Leave(err);
-			}
-		}
-	
-	// Set background was successful or surface was not created, so 
-	// update subtitle config if subtitles are enabled
-	if (iSubtitleUtility)
-		{
-		TMMFSubtitleWindowConfig config;
-		GetSubtitleConfigFromWindowData(aWindowData, config);
-
-		iSubtitleUtility->UpdateSubtitleConfig(config);
-		}
-	}
-
 void CVideoPlayerUtility::CBody::GetSubtitleConfigFromWindowData(CMediaClientVideoDisplayBody::TWindowData& aWindowData, TMMFSubtitleWindowConfig& aConfig)
 	{
 	aConfig.iWindowId = aWindowData.iWindow->WsHandle();
--- a/mmlibs/mmfw/src/Plugin/Codec/audio/GSM610/101F504A.rss	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Plugin/Codec/audio/GSM610/101F504A.rss	Mon May 03 13:56:28 2010 +0300
@@ -16,7 +16,7 @@
 //
 
 #include <ecom/registryinfo.rh>
-#include <mmf/plugin/mmfCodecImplementationUIDs.hrh>
+#include <mmf/plugin/mmfcodecimplementationuids.hrh>
 #include <mmf/plugin/mmfplugininterfaceuids.hrh>
 
 RESOURCE REGISTRY_INFO theInfo
--- a/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmffile.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmffile.cpp	Mon May 03 13:56:28 2010 +0300
@@ -19,7 +19,7 @@
 #include <mmf/common/mmfutilities.h>
 #include <mmf/common/mmfcontroller.h>
 #include <mmf/common/mmfpaniccodes.h>
-#include <mmf/server/MmfFile.h>
+#include <mmf/server/mmffile.h>
 #include "MmffilePriv.h"
 #include "FileAccess.h"
 
--- a/mmlibs/mmfw/src/server/BaseClasses/Mmfformat.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/src/server/BaseClasses/Mmfformat.cpp	Mon May 03 13:56:28 2010 +0300
@@ -16,8 +16,8 @@
 #include <mmf/common/mmfcontrollerpluginresolver.h>
 #include <mmf/server/mmfdatabuffer.h>
 #include <mmf/common/mmfutilities.h>
-#include <mmf/server/Mmfclip.h>
-#include <mmf/server/MmfFile.h>
+#include <mmf/server/mmfclip.h>
+#include <mmf/server/mmffile.h>
 #include <mmf/server/mmfformat.h>
 
 //static const TUid KUidMmfPluginInterfaceFormatDecode = {KMmfUidPluginInterfaceFormatDecode};
--- a/mmlibs/mmfw/tsrc/mmfintegrationtest/vclntavi/src/testvideoplayer2.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfintegrationtest/vclntavi/src/testvideoplayer2.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -265,7 +265,6 @@
     iMediaClientVideoDisplay = CMediaClientVideoDisplay::NewL(displayId);
     
 	TRect videoExtent = clipRect;
-	TVideoRotation rotation = EVideoRotationNone;
 	TReal32 scaleWidth(100.0f);
 	TReal32 scaleHeight(100.0f);
 	TInt horizPos(EHorizontalAlignCenter);
@@ -276,11 +275,102 @@
 	TReal32 widthP; 
 	TReal32 heightP;
 	RWindow newWindow;
-	TVideoRotation videoRotation(EVideoRotationClockwise180);
+	
+	// Check for invalid rotation when adding new window
+	INFO_PRINTF1(_L("Testing invalid rotations for AddDisplayWindowL"));
+	TInt err = KErrNone;
+	TVideoRotation rotation = static_cast<TVideoRotation>(-1);
+	TRAP(err, iMediaClientVideoDisplay->AddDisplayWindowL(iWindow, clipRect, cropRegion, videoExtent, scaleWidth, scaleHeight, rotation, EAutoScaleBestFit, horizPos, vertPos, iWindow));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->AddDisplayWindowL() did not leave with KErrArgument for negative rotation"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	rotation = static_cast<TVideoRotation>(4);
+	TRAP(err, iMediaClientVideoDisplay->AddDisplayWindowL(iWindow, clipRect, cropRegion, videoExtent, scaleWidth, scaleHeight, rotation, EAutoScaleBestFit, horizPos, vertPos, iWindow));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->AddDisplayWindowL() did not leave with KErrArgument for out of range rotation"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	rotation = EVideoRotationNone;
+
+	// Check for invalid autoScaleType when adding new window
+	INFO_PRINTF1(_L("Testing invalid autoScaleType for AddDisplayWindowL"));
+	TAutoScaleType autoScaleType = static_cast<TAutoScaleType>(-1);
+	TRAP(err, iMediaClientVideoDisplay->AddDisplayWindowL(iWindow, clipRect, cropRegion, videoExtent, scaleWidth, scaleHeight, rotation, autoScaleType, horizPos, vertPos, iWindow));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->AddDisplayWindowL() did not leave with KErrArgument for negative scale"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	autoScaleType = static_cast<TAutoScaleType>(4);
+	TRAP(err, iMediaClientVideoDisplay->AddDisplayWindowL(iWindow, clipRect, cropRegion, videoExtent, scaleWidth, scaleHeight, rotation, autoScaleType, horizPos, vertPos, iWindow));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->AddDisplayWindowL() did not leave with KErrArgument for out of range scale"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
 	
 	iMediaClientVideoDisplay->AddDisplayWindowL(iWindow, clipRect, cropRegion, videoExtent, scaleWidth, scaleHeight, rotation, EAutoScaleBestFit, horizPos, vertPos, iWindow);
 	INFO_PRINTF1(_L("iMediaClientVideoDisplay->AddDisplayWindowL()"));   
-    
+
+	// Check for invalid rotation when setting rotation for window
+	INFO_PRINTF1(_L("Testing invalid rotation for SetRotationL"));
+	TVideoRotation videoRotation = static_cast<TVideoRotation>(-1);
+	TRAP(err, iMediaClientVideoDisplay->SetRotationL(*iWindow, videoRotation, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetRotationL(window) did not leave with KErrArgument for negative value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	videoRotation = static_cast<TVideoRotation>(4);
+	TRAP(err, iMediaClientVideoDisplay->SetRotationL(*iWindow, videoRotation, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetRotationL(window) did not leave with KErrArgument for out of range value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	// Check for invalid rotation when setting rotation for all windows
+	videoRotation = static_cast<TVideoRotation>(-1);
+	TRAP(err, iMediaClientVideoDisplay->SetRotationL(videoRotation, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetRotationL() did not leave with KErrArgument for negative value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	videoRotation = static_cast<TVideoRotation>(4);
+	TRAP(err, iMediaClientVideoDisplay->SetRotationL(videoRotation, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetRotationL() did not leave with KErrArgument for out of range value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	videoRotation = EVideoRotationClockwise180;
+
     iMediaClientVideoDisplay->SetRotationL(*iWindow, videoRotation, cropRegion);
     INFO_PRINTF1(_L("iMediaClientVideoDisplay->SetRotationL()"));
     
@@ -311,6 +401,49 @@
     
     iMediaClientVideoDisplay->SetWindowClipRectL(*iWindow, clipRect, cropRegion);
     INFO_PRINTF1(_L("iMediaClientVideoDisplay->SetWindowClipRectL()"));
+
+	// Check for invalid autoScaleType when setting autoScaleType for window
+	INFO_PRINTF1(_L("Testing invalid autoScaleType for SetAutoScaleL"));
+	autoScaleType = static_cast<TAutoScaleType>(-1);
+	TRAP(err, iMediaClientVideoDisplay->SetAutoScaleL(*iWindow, autoScaleType, horizPos, vertPos, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetAutoScaleL(window) did not leave with KErrArgument for negative value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	autoScaleType = static_cast<TAutoScaleType>(4);
+	TRAP(err, iMediaClientVideoDisplay->SetAutoScaleL(*iWindow, autoScaleType, horizPos, vertPos, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetAutoScaleL(window) did not leave with KErrArgument for out of range value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	// Check for invalid autoScaleType when setting autoScaleType for all windows
+	autoScaleType = static_cast<TAutoScaleType>(-1);
+	TRAP(err, iMediaClientVideoDisplay->SetAutoScaleL(autoScaleType, horizPos, vertPos, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetAutoScaleL() did not leave with KErrArgument for negative value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
+
+	autoScaleType = static_cast<TAutoScaleType>(4);
+	TRAP(err, iMediaClientVideoDisplay->SetAutoScaleL(autoScaleType, horizPos, vertPos, cropRegion));
+	if (err != KErrArgument)
+		{
+		ERR_PRINTF1(_L("iVideoPlayer2->SetAutoScaleL() did not leave with KErrArgument for out of range value"));
+    	iTestStepResult = EFail;
+    	CActiveScheduler::Stop();
+    	return;
+		}
     
     iMediaClientVideoDisplay->SetAutoScaleL(EAutoScaleBestFit, horizPos, vertPos, cropRegion);
     INFO_PRINTF1(_L("iMediaClientVideoDisplay->SetAutoScaleL()"));
--- a/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.cpp	Mon May 03 13:56:28 2010 +0300
@@ -84,10 +84,19 @@
 	// the rest of the parameters can be ignored
 	TPckgBuf<TInt> volumePkg (aVol);
 	TMMFMessageDestinationPckg setVolDest (TMMFMessageDestination(KUidTestSetVolIf, 0));
-	TInt result = iCommand->CustomCommandSync(setVolDest, 0, volumePkg, KNullDesC8);
+	TInt result = iCommand->CustomCommandSync(setVolDest, ETestSetVolIfSetVolCommand, volumePkg, KNullDesC8);
 	return result;
 	}
 
+TInt CA3fClientCiStubExtn::Vol(TInt aMaxVol)
+    {
+    // again the key is is the destination package
+    TPckgBuf<TInt> maxVolPkg (aMaxVol);
+    TMMFMessageDestinationPckg setVolDest (TMMFMessageDestination(KUidTestSetVolIf, 0));
+    TInt result = iCommand->CustomCommandSync(setVolDest, ETestSetVolIfVolCommand, maxVolPkg, KNullDesC8);
+    return result;
+    }
+
 // __________________________________________________________________________
 // Server-side extension
 
@@ -170,24 +179,41 @@
 	
 TInt CSetVol::HandleMessageL(const RMmfIpcMessage& aMessage)
 	{
-	TPckgBuf<TInt> volPckg;
-	MmfMessageUtil::ReadL(aMessage, 1, volPckg);
-	UpdateA3fPointers(); // grab pointers to context, stream etc
-	SetVolumeL(volPckg());
-	
-	User::LeaveIfError(iContext->RegisterAudioContextObserver(*this));
-	
-	TInt error = iContext->Commit();
-	if (!error)
-		{
-		iError = KErrNone;
-		iWait->Start();
-		error = iError;
-		}
-	(void) iContext->UnregisterAudioContextObserver(*this);
-	
-	aMessage.Complete(error); 
-	return KErrNone; // KErrNone says we've handled the message
+    switch (aMessage.Function())
+        {
+        case ETestSetVolIfSetVolCommand:
+            {
+            TPckgBuf<TInt> volPckg;
+            MmfMessageUtil::ReadL(aMessage, 1, volPckg);
+            UpdateA3fPointers(); // grab pointers to context, stream etc
+            SetVolumeL(volPckg());
+
+            User::LeaveIfError(iContext->RegisterAudioContextObserver(*this));
+
+            TInt error = iContext->Commit();
+            if (!error)
+                {
+                iError = KErrNone;
+                iWait->Start();
+                error = iError;
+                }
+            (void) iContext->UnregisterAudioContextObserver(*this);
+
+            aMessage.Complete(error);
+            return KErrNone; // KErrNone says we've handled the message
+            }
+        case ETestSetVolIfVolCommand:
+            {
+            TPckgBuf<TInt> maxVolPckg;
+            MmfMessageUtil::ReadL(aMessage, 1, maxVolPckg);
+            UpdateA3fPointers(); // grab pointers to context, stream etc
+            TInt result = VolumeL(maxVolPckg());
+            aMessage.Complete(result);
+            return KErrNone; // KErrNone says we've handled the message
+            }
+        default:
+            return KErrArgument;
+        }
 	}
 	
 void CSetVol::UpdateA3fPointers()
@@ -224,6 +250,23 @@
 	User::LeaveIfError(gainControl->SetGain(channelGains));	
 	CleanupStack::PopAndDestroy(&channelGains);
 	}
+
+TInt CSetVol::VolumeL(TInt aMaxVolume)
+    {
+    RArray<TAudioChannelGain>   channelGains;
+    CleanupClosePushL(channelGains);
+    TInt maxGain;
+
+    MAudioGainControl* gainControl = static_cast<MAudioGainControl*>(iGain->Interface(KUidAudioGainControl));
+    User::LeaveIfError(gainControl->GetGain(channelGains));
+    User::LeaveIfError(gainControl->GetMaxGain(maxGain));
+
+    TInt basicVolume = (channelGains[0].iGain + channelGains[1].iGain) / 2;
+    TInt result = basicVolume * aMaxVolume / maxGain; // scale to 0 to maxVolume
+
+    CleanupStack::PopAndDestroy(&channelGains);
+    return result;
+    }
 	
 void CSetVol::ContextEvent(TUid aEvent, TInt aError)
 	{
--- a/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/a3fcistubextn.h	Mon May 03 13:56:28 2010 +0300
@@ -26,6 +26,12 @@
 
 class CSetVol;
 
+enum TSetVolCommands
+    {
+    ETestSetVolIfSetVolCommand,
+    ETestSetVolIfVolCommand,
+    };
+
 /**
 *
 * CA3fClientCiStubExtn
@@ -52,6 +58,7 @@
 	
 	// from MTestSetVolIf
 	TInt SetVol(TInt aVolume);
+	TInt Vol(TInt aMaxVolume);
 	
 protected:
 	TUid iKey;
@@ -109,6 +116,7 @@
 	
 	void UpdateA3fPointers();
 	void SetVolumeL(TInt aVol);
+	TInt VolumeL(TInt aMaxVolume);
 	
 	MCustomInterface* iInterface; // not owned
 	MAudioContext* iContext;
--- a/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/testsetvol.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/a3fcistubextn/testsetvol.h	Mon May 03 13:56:28 2010 +0300
@@ -24,6 +24,8 @@
 public:
 	// Backdoor to set volume - support via CIClient/ServerExtension
 	virtual TInt SetVol(TInt aVolume) = 0;
+	// Backdoor to volume - actually the gain value from the context scaled to 0..aMaxVol
+	virtual TInt Vol(TInt aMaxVol) = 0;
 	};
 
 
--- a/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/src/TSU_MMF_DEVSOUND_STEP.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/DevSoundTest/src/TSU_MMF_DEVSOUND_STEP.cpp	Mon May 03 13:56:28 2010 +0300
@@ -675,7 +675,7 @@
 		}
 	else
 		{
-		// Temp addition to check for alternative CI implementation
+		// Check for alternative CI implementation
 		MTestSetVolIf *volIf = static_cast<MTestSetVolIf*>(iMMFDevSound->CustomInterface(KUidTestSetVolIf));
 		if (volIf)
 			{
@@ -4435,9 +4435,16 @@
 			//note test does not make any assumptions as to what the supported datatypes are
 			if (numberOfSupportedDataTypes)
 				{
+				TUint32 testsFourCC = TFourCC(_L8("TST*")).FourCC(); // if any fourCc matches first three chars then we treat as test
 				for (TUint entryNumber = 0; entryNumber < numberOfSupportedDataTypes; entryNumber++)
 					{
 					TUint32 fourCC = supportedDataTypes[entryNumber].FourCC();
+					if ((testsFourCC&0xFFFFFF) == (fourCC&0xFFFFFF))
+						{
+						// comparison ignoring top byte - equates to last digit of fourCC
+						continue;
+						}
+					
 					ResetCallbacks();
 					TRAP(err,iMMFDevSound->InitializeL(*this, fourCC, prioritySettings.iState));
 					if ((err)||(iCallbackError))
@@ -4523,9 +4530,16 @@
 			//note test does not make any assumptions as to what the supported datatypes are
 			if (numberOfSupportedDataTypes)
 				{
+				TUint32 testsFourCC = TFourCC(_L8("TST*")).FourCC(); // if any fourCc matches first three chars then we treat as test
 				for (TUint entryNumber = 0; entryNumber < numberOfSupportedDataTypes; entryNumber++)
 					{
 					TUint32 fourCC = supportedDataTypes[entryNumber].FourCC();
+					if ((testsFourCC&0xFFFFFF) == (fourCC&0xFFFFFF))
+						{
+						// comparison ignoring top byte - equates to last digit of fourCC
+						continue;
+						}
+					
 					ResetCallbacks();
 					TRAP(err,iMMFDevSound->InitializeL(*this, fourCC, prioritySettings.iState));
 					if ((err)||(iCallbackError))
@@ -7561,7 +7575,7 @@
 			iDevSoundObserver1 = CMultiInitTestDevSoundObserver::NewL(this, EObserver1);
 			delete iDevSoundObserver2;
 			iDevSoundObserver2 = NULL;
-			iMMFDevSound->InitializeL(*iDevSoundObserver1, TUid::Uid(KMmfUidHwDevicePCM8ToPCM16), EMMFStatePlaying);
+			iMMFDevSound->InitializeL(*iDevSoundObserver1, KMMFFourCCCodePCM8, EMMFStatePlaying);
 			iTestState = EInit2Observer1;
 			}
 		else
@@ -7576,7 +7590,7 @@
 			iDevSoundObserver2 = CMultiInitTestDevSoundObserver::NewL(this, EObserver2);
 			delete iDevSoundObserver1;
 			iDevSoundObserver1 = NULL;
-			iMMFDevSound->InitializeL(*iDevSoundObserver2, TUid::Uid(KMmfUidHwDevicePCM8ToPCM16), EMMFStatePlaying);
+			iMMFDevSound->InitializeL(*iDevSoundObserver2, KMMFFourCCCodePCM8, EMMFStatePlaying);
 			INFO_PRINTF1(_L("Initialising with Observer2"));
 			iTestState = EInit2Observer2;
 			}
@@ -8682,6 +8696,23 @@
 									StopTest (KErrGeneral);
 									break;
 									}
+						        // Check the low-level a3f volume. Should have been applied by now
+						        MTestSetVolIf *volIf = static_cast<MTestSetVolIf*>(iMMFDevSound->CustomInterface(KUidTestSetVolIf));
+						        if (volIf)
+						            {
+						            TInt vol = volIf->Vol(iMMFDevSound->MaxVolume());
+	                                if (vol == iVolume)
+	                                    {
+	                                    INFO_PRINTF1(_L("Low-level volume returned equal previous set value as expected"));
+	                                    }
+	                                else
+	                                    {
+	                                    ERR_PRINTF3(_L("Low-level volume returned different set value = %d (expect %d)"), vol, iVolume);
+	                                    StopTest (KErrGeneral);
+	                                    break;
+	                                    }
+						            }
+
 								INFO_PRINTF1(_L("Call iMMFDevSound::GetPlayBalanceL for verifying."));
 								TInt getLSpeakerBalance = 0;
 								TInt getRSpeakerBalance = 0;
--- a/mmlibs/mmfw/tsrc/mmfunittest/MmpFiles/TSU_MMF_VCLNT_01.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/MmpFiles/TSU_MMF_VCLNT_01.mmp	Mon May 03 13:56:28 2010 +0300
@@ -50,6 +50,9 @@
 source			../../../../src/Client/Video/mediaclientvideodisplaybody.cpp
 source			../../../../src/Client/Video/mediaclientextdisplayinterface.cpp
 source			../../../../src/Client/Video/mediaclientextdisplayhandler.cpp
+source			../../../../src/Client/Video/mediaclientwseventobserver.cpp
+source			../../../../src/Client/Video/mediaclientpolicyserverclient.cpp
+source			../../../../src/Client/Video/mediaclientpolicyserversession.cpp
 source			teststepvidplayereventhandler.cpp
 #endif
 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
@@ -118,6 +121,8 @@
 #endif //SYMBIAN_BUILD_GCE
 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
 
+MACRO __ENABLE_MEDIA_CLIENT_VIDEO_TRACE__
+
 NOSTRICTDEF
 
 SMPSAFE
--- a/mmlibs/mmfw/tsrc/mmfunittest/group/BLD.INF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmlibs/mmfw/tsrc/mmfunittest/group/BLD.INF	Mon May 03 13:56:28 2010 +0300
@@ -331,7 +331,7 @@
 ../aclnt/TSU_MMF_ACLNT_01/data/smallwav_audiorights.xml		c:/mm/mmf/testfiles/aclnt/smallwav_audiorights.xml
 
 //Test data Add to test DEF140670 
-../ACLNT/TSU_MMF_ACLNT_01/Data/recordtest.wav		c:/mm/mmf/testfiles/aclnt/recordtest.wav
+../aclnt/TSU_MMF_ACLNT_01/data/recordtest.wav		c:/mm/mmf/testfiles/aclnt/recordtest.wav
 
 // remove recorded.wav, as it causes problems
 //../ACLNT/TSU_MMF_ACLNT_01/Data/recorded.wav	c:/mm/mmf/testfiles/aclnt/recorded.wav
--- a/mmplugins/imagingplugins/codecs/GifCodec/GIFcodec.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/GifCodec/GIFcodec.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -256,8 +256,8 @@
 		if (maskProc)
 			maskProc->FlushPixels();
 		pos = iFrameOffset;
-		
-		if(iGifImageControl && iGifImageControl->iTransparentColorIndex != KErrNotFound)
+		//in case of iFast64kMode == true, palette is of type T64KPixel
+		if(iGifImageControl && iGifImageControl->iTransparentColorIndex != KErrNotFound && !iFast64kMode)
 			{
 			// reset the transparency index
 			if (iTranspColIdx != KTranspColIdxNotPresent)
@@ -436,8 +436,6 @@
             i64KPalette[idx] = iPalette[idx]._Color64K();
             } 
             while (++idx < KGifColorTableMaxEntries);
-            
-        iPalette = reinterpret_cast<const TRgb*>( i64KPalette );
         }
         
     if (imageProc == NULL)
--- a/mmplugins/imagingplugins/codecs/JPEGCodec/JPEGCodec.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/JPEGCodec/JPEGCodec.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1467,7 +1467,7 @@
 	do
 		{
 		index = (index << 1) + 1;
-		index +=((look & TUint(1<<31)) != 0);
+		index +=((look & ((TUint32)1<<31)) != 0);
 		look<<=1;
 		} while (++bitCount < nb);
 
--- a/mmplugins/imagingplugins/codecs/JPEGCodec/JPGQUANT.CPP	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/JPEGCodec/JPGQUANT.CPP	Mon May 03 13:56:28 2010 +0300
@@ -226,6 +226,7 @@
                 register TAligned64Value dstValue;
 				register TAligned64Value qValue;
 				register TAligned64Value zValue;
+				dstValue.iAligment = 0; //to remove possible RVCT warning
 				zValue.iAligment = *reinterpret_cast<const TUint64*>(zigZagPtr);
                 
 				qValue.iAligment = *qPtr++;                
--- a/mmplugins/imagingplugins/codecs/PNGCodec/PngScanlineDecoder.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/PNGCodec/PngScanlineDecoder.cpp	Mon May 03 13:56:28 2010 +0300
@@ -327,7 +327,7 @@
     
     while (aDataPtr < aDataPtrLimit)
         {
-        *scanLinePtr++ = (0xFF << 24) | (aDataPtr[0] << 16) | (aDataPtr[1] << 8) | aDataPtr[2]; 
+        *scanLinePtr++ = ((TUint32)0xFF << 24) | ((TUint32)aDataPtr[0] << 16) | ((TUint32)aDataPtr[1] << 8) | aDataPtr[2]; 
 
         aDataPtr += KPngDepth3BytesPerPixel;
         }
--- a/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFCodec.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFCodec.cpp	Mon May 03 13:56:28 2010 +0300
@@ -158,7 +158,7 @@
 		case EFinish:
 			{
 			err = iRecordTable->InsertRecordL(iIfdOffset, iIfdSize);
-			if (err != KErrNone)
+			if (err != KErrNone && err != KErrAlreadyExists)
 				{
 				User::Leave(KErrCorrupt);
 				}
--- a/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFFax.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFFax.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1154,7 +1154,7 @@
 	if(!iBitCacheLength)
 		return(ETiffFaxUnderflow);
 
-	if(iBitCache&(1<<31))
+	if(iBitCache&((TUint32)1<<31))
 		iState = E1d;
 	else
 		iState = E2d;
--- a/mmplugins/lib3gp/impl/inc/mp4file.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/lib3gp/impl/inc/mp4file.h	Mon May 03 13:56:28 2010 +0300
@@ -56,5 +56,8 @@
 mp4_i32 deleteMetaDataFiles(MP4HandleImp handle);
 mp4_i32 closeMetaDataFiles(MP4HandleImp handle);
 mp4_i32	openStdlib();
+
+TInt RecommendedBufferSize(MP4HandleImp aHandle);
+
 #endif
 // End of File
--- a/mmplugins/lib3gp/impl/src/file.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/lib3gp/impl/src/file.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1758,4 +1758,48 @@
 }
 
 
+TInt RecommendedBufferSize(MP4HandleImp aHandle)
+	{
+	TInt recommendedSize = READBUFSIZE;
+	
+    MP4HandleImp handle = (MP4HandleImp)aHandle;
+    if (handle)
+    	{
+		// handle->rfile will be set in the cases of
+		// - MP4ParseOpen(MP4FileName) <if the filename is set>
+		// - MP4ParseOpenFileHandle64(RFile64)
+		// - MP4ParseOpenFileHandle(RFile) <via MP4ParseOpenFileHandle64()>
+		//
+		// It will not be set by MP4ParseOpenCAF()
+
+		RFs* fs = (RFs*)handle->fs;
+		RFile64* file64 = (RFile64*)handle->rfile;
+		
+		if (fs && file64)
+			{
+			TInt driveNumber = 0;
+			TDriveInfo driveInfo;
+			TVolumeIOParamInfo volumeInfo;
+			
+			TInt err = file64->Drive(driveNumber, driveInfo);
+			if (err == KErrNone)
+				{
+				err = fs->VolumeIOParam(driveNumber, volumeInfo);
+				}
+			
+			if (err == KErrNone)
+				{
+				if (volumeInfo.iRecReadBufSize != KErrNotSupported)
+					{
+					recommendedSize = Max(recommendedSize, volumeInfo.iRecReadBufSize);
+					}
+				}
+				
+			}
+    	}
+
+    return recommendedSize;
+	}
+	
+
 // End of File
--- a/mmplugins/lib3gp/impl/src/mp4compose.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/lib3gp/impl/src/mp4compose.cpp	Mon May 03 13:56:28 2010 +0300
@@ -1311,7 +1311,8 @@
 
     return MP4_OK;
     }
-
+	
+	
 extern EXPORT_C MP4Err MP4SetCustomFileBufferSizes( MP4Handle apihandle, 
                                                                mp4_u32 mediaWriteBufferSize,
                                                                mp4_u32 writeBufferMaxCount,
@@ -1322,14 +1323,19 @@
     if (!handle)
         return MP4_ERROR;
     
-    // Read Buffer size
-    if ( (readBufferSize) && 
-         (readBufferSize != handle->readBufferSize) )
+    // If no specific file size is given we try to use an 'optimal' buffer size.
+    if (readBufferSize == 0)
+    	{
+    	readBufferSize = RecommendedBufferSize(handle);
+		}
+
+	if (readBufferSize > handle->readBufferSize)
         {
         handle->readBufferSize = readBufferSize;
         if (handle->diskReadBuf)
             {
             mp4free(handle->diskReadBuf);
+            handle->diskReadBuf = NULL;
             if ((handle->diskReadBuf = (mp4_u8 *)mp4malloc(handle->readBufferSize)) == NULL)
                 {
                 return MP4_OUT_OF_MEMORY;
--- a/mmplugins/lib3gp/impl/src/mp4parse.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/lib3gp/impl/src/mp4parse.cpp	Mon May 03 13:56:28 2010 +0300
@@ -165,7 +165,7 @@
   	if (openStdlib() !=  MP4_OK)
   		{
   		// clean up
-  		mp4free((*handle)->diskReadBuf);
+		mp4free((*handle)->diskReadBuf);
 		mp4free((*handle)->buf);
 		listDestroyList((*handle)->mem);
 		closeFile(*handle);
--- a/mmplugins/lib3gp/wrapper/src/c3gpparse.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/lib3gp/wrapper/src/c3gpparse.cpp	Mon May 03 13:56:28 2010 +0300
@@ -2157,3 +2157,5 @@
 	_LIT(K3GPParsePanicName, "C3GPParse");
 	User::Panic(K3GPParsePanicName, aPanic);
 	}
+
+	
--- a/mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggPlayController/oggdecode.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggPlayController/oggdecode.h	Mon May 03 13:56:28 2010 +0300
@@ -19,8 +19,8 @@
 
 #include <mmf/server/mmffile.h>
 #include <stdlib.h>
-#include "oggutil.h"
-#include "vorbisinfo.h"
+#include "OggUtil.h"
+#include "VorbisInfo.h"
 
 static const TInt KNumHeaders = 3;// vorbis has 3 header packets
 //Average oggpage is of size 4K. we read 4K buffer during seeking and finding duration sothat we expect
--- a/mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggRecordController/OggEncode.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/mmfwplugins/src/Plugin/Controller/Audio/OggVorbis/OggRecordController/OggEncode.h	Mon May 03 13:56:28 2010 +0300
@@ -18,8 +18,8 @@
 #define OGGENCODE_H
 
 #include <mmf/server/mmfclip.h>
-#include "oggutil.h"
-#include "vorbisinfo.h"
+#include "OggUtil.h"
+#include "VorbisInfo.h"
 
 #ifdef VORBIS_DEBUG
 #define DEBUG(x) RDebug::Print(_L(x))
--- a/mmplugins/mmfwplugins/src/Plugin/Format/MmfWAVFormat/mmfwavformat.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmplugins/mmfwplugins/src/Plugin/Format/MmfWAVFormat/mmfwavformat.cpp	Mon May 03 13:56:28 2010 +0300
@@ -951,12 +951,12 @@
 	//the sink buffer size will be used to determine the frame time.
 	//check media id &pass onto clip
 
+	//[ precondition the buffer is not null ]
+	__ASSERT_DEBUG( aBuffer, Panic( EPreconditionViolation ) );
+	
 	if ((aBuffer != NULL) && (!CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type())))
 		User::Leave(KErrNotSupported);
 	
-	//[ precondition the buffer is not null ]
-	__ASSERT_DEBUG( aBuffer, Panic( EPreconditionViolation ) );
-	
 	//[ precondition it must be audio ]
 	if(aMediaId.iMediaType!=KUidMediaTypeAudio)
 		User::Leave(KErrNotSupported);
--- a/mmtestenv/mmtestfw/MMPFiles/TestFrameworkClient.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/MMPFiles/TestFrameworkClient.mmp	Mon May 03 13:56:28 2010 +0300
@@ -25,6 +25,7 @@
 
 SOURCEPATH		../Source/TestFrameworkClient
 SOURCE			Log.cpp
+SOURCE			testfwclientsession.cpp
 SOURCE			TestSuite.cpp
 SOURCE			TestStep.cpp
 SOURCE			TestUtils.cpp
--- a/mmtestenv/mmtestfw/Source/TestFrameworkClient/Log.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/Source/TestFrameworkClient/Log.cpp	Mon May 03 13:56:28 2010 +0300
@@ -47,251 +47,6 @@
 
 /**
  *
- * Global : start a server
- * NOTE. Function is global static as only one server will ever run at any time
- * (there may be multiple client sessions)
- *
- * @return	"TInt"
- *			Error code (KErrNone if successful)
- *
- * @xxxx
- *
- */
-GLDEF_C TInt StartServer()
-// Start the server process/thread which lives in an (EPOC)EXE object
-	{
-	const TUidType serverUid(KNullUid, KNullUid, KTestFrameworkServerUid3);
-
-
-// EPOC is easy, we just create a new server process. Simultaneous launching
-// of two such processes should be detected when the second one attempts to
-// create the server object, failing with KErrAlreadyExists.
-
-	RProcess server;
-	TInt r = server.Create(KTestFrameworkServerImg, KNullDesC, serverUid);
-
-	if (r != KErrNone)
-		return r;
-
-	
-	TRequestStatus rendezvous;
-	server.Rendezvous(rendezvous);
-
-	if (rendezvous!=KRequestPending)
-		{
-		server.Kill(0);
-		}
-	else
-		{
-		server.Resume();
-		}
-
-
-	User::WaitForRequest(rendezvous);		// wait for start or death
-
-	// we can't use the 'exit reason' if the server panicked as this
-	// is the panic 'reason' and may be '0' which cannot be distinguished
-	// from KErrNone
-	if (rendezvous!=KErrNone)
-		{
-		server.Close();
-		}
-
-	// server started (at last). Cancel and consume the death-notification
-	// before reporting success
-	return rendezvous.Int();
-	}
-
-/**
- *
- * Constructor for RTestFrameworkClientSession
- *
- * @xxxx
- *
- */
-RTestFrameworkClientSession::RTestFrameworkClientSession()
-	{
-	}
-
-/**
- *
- * Client session : connect to server.
- * Will start a new server session if no server exists
- *
- * @return	"TInt"
- *			Error code (KErrNone if connect successful)
- *
- * @xxxx
- *
- */
-TInt RTestFrameworkClientSession::Connect()
-	{
-	// NOTE : this loop is ugly and can probably be rewritten to be more graceful
-	const TInt KNumRetries = 2;
-
-	TInt retry = KNumRetries;
-	for (;;)
-		{
-		TInt r = CreateSession(KTestFrameworkServerName, TVersion(KTestFrameworkServerMajorVersionNumber,
-																  KTestFrameworkServerMinorVersionNumber,
-																  KTestFrameworkServerBuildVersionNumber));
-		if (r == KErrNone)
-			{
-#ifdef __IPC_V2_PRESENT__
-			r = ShareAuto();
-#else
-			r = Share(RSessionBase::EAutoAttach);
-#endif
-			if (r!=KErrNone)
-				Close();
-			return r;
-			}
-		if (r != KErrNotFound && r != KErrServerTerminated)
-			{
-			return r;
-			}
-		if (--retry == 0)
-			return r;
-		r = StartServer();
-		if (r != KErrNone && r != KErrAlreadyExists)
-			return r;
-		}
-	}
-
-/**
- *
- * Request creation of an input window.
- * NOTE. For initialisation of input console only - unlikely to
- * be required by user
- *
- * @param	"TRectBuf& aAllocatedWindow"
- *			Window dimensions
- *
- * @param	"TRequestStatus& aReqStat"
- *			Request status
- *
- * @xxxx
- *
- */
-void RTestFrameworkClientSession::CreateInputWindow(TRectBuf& aAllocatedWindow, TRequestStatus& aReqStat)
-	{
-	SendReceiveResult(ECreateInputWindow, aAllocatedWindow, aReqStat);
-	}
-
-/**
- *
- * Request window change notifications
- * NOTE. For initialisation of input console only - unlikely to
- * be required by user
- *
- * @param	"TRectBuf& aNewWindow"
- *			New window dimensions
- *
- * @param	"TRequestStatus& aReqStat"
- *			Request status
- *
- * @xxxx
- *
- */
-void RTestFrameworkClientSession::NotifyIfWindowChange(TRectBuf& aNewWindow, TRequestStatus& aReqStat)
-	{
-	SendReceiveResult(ENotifyIfWindowChange, aNewWindow, aReqStat);
-	}
-
-/**
- *
- * Cancel window change notifications
- * NOTE. For initialisation of input console only - unlikely to
- * be required by user
- *
- * @return	"TInt"
- *			SendReceive error code
- *
- * @xxxx
- *
- */
-TInt RTestFrameworkClientSession::CancelNotifyIfWindowChange()
-	{
-	return SendReceive(ECancelNotifyIfWindowChange);
-	}
-
-
-/**
- *
- * Open a log server session
- *
- * @param	"const TDesC& aLogName"
- *			The log name
- *
- * @param	"TInt aLogMode"
- *			The log mode (a bitmask of TTestFrameworkLogMode)
- *
- * @xxxx
- *
- */
-void RTestFrameworkClientSession::OpenLog(const TDesC& aLogName, TInt aLogMode)
-	{
-	(void) SendReceive(EOpenLog, aLogName, aLogMode);
-	}
-
-/**
- *
- * Write message string to log server session
- *
- * @param	"const TDesC& aMsg"
- *			The message string
- *
- * @param	"TInt aLogMode"
- *			The log mode (a bitmask of TTestFrameworkLogMode)
- *
- * @xxxx
- *
- */
-void RTestFrameworkClientSession::WriteLog(const TDesC& aMsg, TInt aLogMode)
-	{
-	(void) SendReceive(EWriteLog, aMsg, aLogMode);
-	}
-
-/**
- *
- * Send close log message to server
- *
- * @xxxx
- *
- */
-void RTestFrameworkClientSession::CloseLog()
-	{
-	SendReceive(ECloseLog);
-	}
-
-/**
- *
- * Retrieve log status from server
- *
- * @return	"TInt"
- *			The log status (a bitmask of TTestFrameworkLogMode)
- *
- * @xxxx
- *
- */
-TInt RTestFrameworkClientSession::LogStatus()
-	{
-	TInt res = 0;
-	TPckgBuf<TInt> pckg;
-	TInt r = SendReceiveResult(ELogStatus, pckg);
-	if (r != KErrNone)
-	{
-		// RTestFrameworkClientSession does not log - 
-		// we can however return 0 to indicate an error (no outputs)
-		res = 0;
-	}
-	else
-		res = pckg();
-	return res;
-	}
-
-/**
- *
  * Static constructor for CLog.
  *
  *
--- a/mmtestenv/mmtestfw/Source/TestFrameworkClient/TestStep.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/Source/TestFrameworkClient/TestStep.cpp	Mon May 03 13:56:28 2010 +0300
@@ -183,7 +183,7 @@
  * @xxxx
  *
  */
-void RTestStep::SetSuite(CTestSuite* aSuite)
+EXPORT_C void RTestStep::SetSuite(CTestSuite* aSuite)
 	{
 	iSuite = aSuite;
 	}
@@ -198,7 +198,7 @@
  * @xxxx
  *
  */
-void RTestStep::SetResult(TVerdict aResult)
+EXPORT_C void RTestStep::SetResult(TVerdict aResult)
 	{
 	iTestStepResult = aResult;
 	}
@@ -213,7 +213,7 @@
  * @xxxx
  *
  */
-TPtrC RTestStep::StepName() const
+EXPORT_C TPtrC RTestStep::StepName() const
 	{
 	return iTestStepName;
 	}
@@ -833,12 +833,12 @@
  * @xxxx
  *
  */
-TInt RTestStep::StackSize() const
+EXPORT_C TInt RTestStep::StackSize() const
 {
 	return iStackSize;
 }
 
-TInt RTestStep::HeapSize() const
+EXPORT_C TInt RTestStep::HeapSize() const
 {
 	return iHeapSize;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmtestenv/mmtestfw/Source/TestFrameworkClient/testfwclientsession.cpp	Mon May 03 13:56:28 2010 +0300
@@ -0,0 +1,266 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Client / server logging for Test Framework
+// NOTE : does NOT include secure API changes in EKA2
+// 
+//
+
+
+// Test system includes
+#include <testframework.h>
+
+/**
+ *
+ * Global : start a server
+ * NOTE. Function is global static as only one server will ever run at any time
+ * (there may be multiple client sessions)
+ *
+ * @return	"TInt"
+ *			Error code (KErrNone if successful)
+ *
+ * @xxxx
+ *
+ */
+GLDEF_C TInt StartServer()
+// Start the server process/thread which lives in an (EPOC)EXE object
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KTestFrameworkServerUid3);
+
+
+// EPOC is easy, we just create a new server process. Simultaneous launching
+// of two such processes should be detected when the second one attempts to
+// create the server object, failing with KErrAlreadyExists.
+
+	RProcess server;
+	TInt r = server.Create(KTestFrameworkServerImg, KNullDesC, serverUid);
+
+	if (r != KErrNone)
+		return r;
+
+	
+	TRequestStatus rendezvous;
+	server.Rendezvous(rendezvous);
+
+	if (rendezvous!=KRequestPending)
+		{
+		server.Kill(0);
+		}
+	else
+		{
+		server.Resume();
+		}
+
+
+	User::WaitForRequest(rendezvous);		// wait for start or death
+
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	if (rendezvous!=KErrNone)
+		{
+		server.Close();
+		}
+
+	// server started (at last). Cancel and consume the death-notification
+	// before reporting success
+	return rendezvous.Int();
+	}
+
+/**
+ *
+ * Constructor for RTestFrameworkClientSession
+ *
+ * @xxxx
+ *
+ */
+RTestFrameworkClientSession::RTestFrameworkClientSession()
+	{
+	}
+
+/**
+ *
+ * Client session : connect to server.
+ * Will start a new server session if no server exists
+ *
+ * @return	"TInt"
+ *			Error code (KErrNone if connect successful)
+ *
+ * @xxxx
+ *
+ */
+TInt RTestFrameworkClientSession::Connect()
+	{
+	// NOTE : this loop is ugly and can probably be rewritten to be more graceful
+	const TInt KNumRetries = 2;
+
+	TInt retry = KNumRetries;
+	for (;;)
+		{
+		TInt r = CreateSession(KTestFrameworkServerName, TVersion(KTestFrameworkServerMajorVersionNumber,
+																  KTestFrameworkServerMinorVersionNumber,
+																  KTestFrameworkServerBuildVersionNumber));
+		if (r == KErrNone)
+			{
+#ifdef __IPC_V2_PRESENT__
+			r = ShareAuto();
+#else
+			r = Share(RSessionBase::EAutoAttach);
+#endif
+			if (r!=KErrNone)
+				Close();
+			return r;
+			}
+		if (r != KErrNotFound && r != KErrServerTerminated)
+			{
+			return r;
+			}
+		if (--retry == 0)
+			return r;
+		r = StartServer();
+		if (r != KErrNone && r != KErrAlreadyExists)
+			return r;
+		}
+	}
+
+/**
+ *
+ * Request creation of an input window.
+ * NOTE. For initialisation of input console only - unlikely to
+ * be required by user
+ *
+ * @param	"TRectBuf& aAllocatedWindow"
+ *			Window dimensions
+ *
+ * @param	"TRequestStatus& aReqStat"
+ *			Request status
+ *
+ * @xxxx
+ *
+ */
+void RTestFrameworkClientSession::CreateInputWindow(TRectBuf& aAllocatedWindow, TRequestStatus& aReqStat)
+	{
+	SendReceiveResult(ECreateInputWindow, aAllocatedWindow, aReqStat);
+	}
+
+/**
+ *
+ * Request window change notifications
+ * NOTE. For initialisation of input console only - unlikely to
+ * be required by user
+ *
+ * @param	"TRectBuf& aNewWindow"
+ *			New window dimensions
+ *
+ * @param	"TRequestStatus& aReqStat"
+ *			Request status
+ *
+ * @xxxx
+ *
+ */
+void RTestFrameworkClientSession::NotifyIfWindowChange(TRectBuf& aNewWindow, TRequestStatus& aReqStat)
+	{
+	SendReceiveResult(ENotifyIfWindowChange, aNewWindow, aReqStat);
+	}
+
+/**
+ *
+ * Cancel window change notifications
+ * NOTE. For initialisation of input console only - unlikely to
+ * be required by user
+ *
+ * @return	"TInt"
+ *			SendReceive error code
+ *
+ * @xxxx
+ *
+ */
+TInt RTestFrameworkClientSession::CancelNotifyIfWindowChange()
+	{
+	return SendReceive(ECancelNotifyIfWindowChange);
+	}
+
+
+/**
+ *
+ * Open a log server session
+ *
+ * @param	"const TDesC& aLogName"
+ *			The log name
+ *
+ * @param	"TInt aLogMode"
+ *			The log mode (a bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+void RTestFrameworkClientSession::OpenLog(const TDesC& aLogName, TInt aLogMode)
+	{
+	(void) SendReceive(EOpenLog, aLogName, aLogMode);
+	}
+
+/**
+ *
+ * Write message string to log server session
+ *
+ * @param	"const TDesC& aMsg"
+ *			The message string
+ *
+ * @param	"TInt aLogMode"
+ *			The log mode (a bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+void RTestFrameworkClientSession::WriteLog(const TDesC& aMsg, TInt aLogMode)
+	{
+	(void) SendReceive(EWriteLog, aMsg, aLogMode);
+	}
+
+/**
+ *
+ * Send close log message to server
+ *
+ * @xxxx
+ *
+ */
+void RTestFrameworkClientSession::CloseLog()
+	{
+	SendReceive(ECloseLog);
+	}
+
+/**
+ *
+ * Retrieve log status from server
+ *
+ * @return	"TInt"
+ *			The log status (a bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+TInt RTestFrameworkClientSession::LogStatus()
+	{
+	TInt res = 0;
+	TPckgBuf<TInt> pckg;
+	TInt r = SendReceiveResult(ELogStatus, pckg);
+	if (r != KErrNone)
+	{
+		// RTestFrameworkClientSession does not log - 
+		// we can however return 0 to indicate an error (no outputs)
+		res = 0;
+	}
+	else
+		res = pckg();
+	return res;
+	}
--- a/mmtestenv/mmtestfw/bwins/TESTFRAMEWORKCLIENTU.DEF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/bwins/TESTFRAMEWORKCLIENTU.DEF	Mon May 03 13:56:28 2010 +0300
@@ -102,4 +102,7 @@
 	?Stop@CBusyTestUnit@@QAEXXZ @ 101 NONAME ; void CBusyTestUnit::Stop(void)
 	?Start@CBusyTestUnit@@QAEHVTTimeIntervalMicroSeconds32@@VTTimeIntervalMicroSeconds@@@Z @ 102 NONAME ; int CBusyTestUnit::Start(class TTimeIntervalMicroSeconds32, class TTimeIntervalMicroSeconds)
 	?GetHexFromConfig@RTestStep@@IAEHABVTDesC16@@0AAH@Z @ 103 NONAME ; int RTestStep::GetHexFromConfig(class TDesC16 const &, class TDesC16 const &, int &)
+	?SetResult@RTestStep@@QAEXW4TVerdict@@@Z @ 104 NONAME ; void RTestStep::SetResult(enum TVerdict)
+	?StepName@RTestStep@@QBE?AVTPtrC16@@XZ @ 105 NONAME ; class TPtrC16 RTestStep::StepName(void) const
+	?SetSuite@RTestStep@@QAEXPAVCTestSuite@@@Z @ 106 NONAME ; void RTestStep::SetSuite(class CTestSuite *)
 
--- a/mmtestenv/mmtestfw/eabi/TestFrameworkClientU.DEF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/eabi/TestFrameworkClientU.DEF	Mon May 03 13:56:28 2010 +0300
@@ -135,4 +135,9 @@
 	_ZN13CBusyTestUnit5StartEv @ 134 NONAME
 	_ZN13CBusyTestUnit5StartE27TTimeIntervalMicroSeconds3225TTimeIntervalMicroSeconds @ 135 NONAME
 	_ZN9RTestStep16GetHexFromConfigERK7TDesC16S2_Ri @ 136 NONAME
+	_ZNK9RTestStep8HeapSizeEv @ 137 NONAME
+	_ZNK9RTestStep9StackSizeEv @ 138 NONAME
+	_ZN9RTestStep8SetSuiteEP10CTestSuite @ 139 NONAME
+	_ZN9RTestStep9SetResultE8TVerdict @ 140 NONAME
+	_ZNK9RTestStep8StepNameEv @ 141 NONAME
 
--- a/mmtestenv/mmtestfw/include/TestFramework.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfw/include/TestFramework.h	Mon May 03 13:56:28 2010 +0300
@@ -28,14 +28,6 @@
 #endif
 #include <testframeworkipc.h>
 
-// do not export if Unit Testing
-#if defined (__TSU_TESTFRAMEWORK__)
-#undef IMPORT_C
-#define IMPORT_C
-#endif
-
-// Common includes
-
 /**
  *
  * Server name
@@ -533,10 +525,9 @@
     IMPORT_C TInt StackSize() const;
     IMPORT_C TInt HeapSize() const;
 
-    // accessors - not required to be exported
-    void SetSuite(CTestSuite* aSuite);
-    void SetResult(TVerdict aResult);
-    TPtrC StepName() const;
+    IMPORT_C void SetSuite(CTestSuite* aSuite);
+    IMPORT_C void SetResult(TVerdict aResult);
+    IMPORT_C TPtrC StepName() const;
     
     // param set - not required to be exported. Note assumes actual param is stable
     void SetDefaultParamSet(const TDesC& aParamSet);
--- a/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth10.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth10.mmp	Mon May 03 13:56:28 2010 +0300
@@ -38,7 +38,7 @@
 
 // code to be tested
 
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/Log.cpp
+SOURCE			../../mmtestfw/Source/TestFrameworkClient/testfwclientsession.cpp
 
 // required stubs
 
--- a/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth11.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth11.mmp	Mon May 03 13:56:28 2010 +0300
@@ -35,12 +35,6 @@
 SOURCE			tsu_mmtsth11/TSU_MmTsthStep11.cpp
 SOURCE			tsu_mmtsth11/TSU_MmTsth11.cpp
 
-// code to be tested
-
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/TestStep.cpp
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/asyncscheduler.cpp // to keep previous happy
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/Log.cpp
-
 // required stubs
 
 SOURCE			tsu_stubs/TestStepVirtualStub.cpp
--- a/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth12.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth12.mmp	Mon May 03 13:56:28 2010 +0300
@@ -35,17 +35,6 @@
 SOURCE			tsu_mmtsth12/TSU_MmTsthStep12.cpp
 SOURCE			tsu_mmtsth12/TSU_MmTsth12.cpp
 
-// code to be tested
-
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/TestSuite.cpp
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/Log.cpp
-
-// required for non-exported functions which need testing
-
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/TestStep.cpp
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/asyncscheduler.cpp // to keep previous happy
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/TestIniData.cpp
-
 // required stubs
 
 SOURCE			tsu_stubs/TestStepVirtualStub.cpp
--- a/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth13.mmp	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/MMPFiles/TSU_MmTsth13.mmp	Mon May 03 13:56:28 2010 +0300
@@ -35,10 +35,6 @@
 SOURCE			tsu_mmtsth13/TSU_MmTsthStep13.cpp
 SOURCE			tsu_mmtsth13/TSU_MmTsth13.cpp
 
-// code to be tested
-
-SOURCE			../../mmtestfw/Source/TestFrameworkClient/TestUtils.cpp
-
 // required stubs
 
 
--- a/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth10U.DEF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth10U.DEF	Mon May 03 13:56:28 2010 +0300
@@ -1,17 +1,13 @@
 EXPORTS
 	_Z20NewTSUMmTsthSuite10Lv @ 1 NONAME
-	_ZTI16RTestMmTsthU1001 @ 2 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1011 @ 3 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1012 @ 4 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1013 @ 5 NONAME ; #<TI>#
-	_ZTI17CTSUMmTsthSuite10 @ 6 NONAME ; #<TI>#
-	_ZTI29TIntegrationTestLog16Overflow @ 7 NONAME ; #<TI>#
-	_ZTI4CLog @ 8 NONAME ; #<TI>#
-	_ZTV16RTestMmTsthU1001 @ 9 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1011 @ 10 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1012 @ 11 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1013 @ 12 NONAME ; #<VT>#
-	_ZTV17CTSUMmTsthSuite10 @ 13 NONAME ; #<VT>#
-	_ZTV29TIntegrationTestLog16Overflow @ 14 NONAME ; #<VT>#
-	_ZTV4CLog @ 15 NONAME ; #<VT>#
+	_ZTI16RTestMmTsthU1001 @ 2 NONAME
+	_ZTI16RTestMmTsthU1011 @ 3 NONAME
+	_ZTI16RTestMmTsthU1012 @ 4 NONAME
+	_ZTI16RTestMmTsthU1013 @ 5 NONAME
+	_ZTI17CTSUMmTsthSuite10 @ 6 NONAME
+	_ZTV16RTestMmTsthU1001 @ 7 NONAME
+	_ZTV16RTestMmTsthU1011 @ 8 NONAME
+	_ZTV16RTestMmTsthU1012 @ 9 NONAME
+	_ZTV16RTestMmTsthU1013 @ 10 NONAME
+	_ZTV17CTSUMmTsthSuite10 @ 11 NONAME
 
--- a/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth11U.DEF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth11U.DEF	Mon May 03 13:56:28 2010 +0300
@@ -1,35 +1,25 @@
 EXPORTS
 	_Z20NewTSUMmTsthSuite11Lv @ 1 NONAME
-	_ZTI12CTestIniData @ 2 NONAME ; #<TI>#
-	_ZTI16RTSUMmTsthStep11 @ 3 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1101 @ 4 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1102 @ 5 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1103 @ 6 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1104 @ 7 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1105 @ 8 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1111 @ 9 NONAME ; #<TI>#
-	_ZTI17CTSUMmTsthSuite11 @ 10 NONAME ; #<TI>#
-	_ZTI20RTestStepVirtualStub @ 11 NONAME ; #<TI>#
-	_ZTI21CTestSuiteVirtualStub @ 12 NONAME ; #<TI>#
-	_ZTI29TIntegrationTestLog16Overflow @ 13 NONAME ; #<TI>#
-	_ZTI9CTestStep @ 14 NONAME ; #<TI>#
-	_ZTI9RTestStep @ 15 NONAME ; #<TI>#
-	_ZTV12CTestIniData @ 16 NONAME ; #<VT>#
-	_ZTV16RTSUMmTsthStep11 @ 17 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1101 @ 18 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1102 @ 19 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1103 @ 20 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1104 @ 21 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1105 @ 22 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1111 @ 23 NONAME ; #<VT>#
-	_ZTV17CTSUMmTsthSuite11 @ 24 NONAME ; #<VT>#
-	_ZTV20RTestStepVirtualStub @ 25 NONAME ; #<VT>#
-	_ZTV21CTestSuiteVirtualStub @ 26 NONAME ; #<VT>#
-	_ZTV29TIntegrationTestLog16Overflow @ 27 NONAME ; #<VT>#
-	_ZTV9CTestStep @ 28 NONAME ; #<VT>#
-	_ZTV9RTestStep @ 29 NONAME ; #<VT>#
-	_ZTI14RAsyncTestStep @ 30 NONAME
-	_ZTI4CLog @ 31 NONAME
-	_ZTV14RAsyncTestStep @ 32 NONAME
-	_ZTV4CLog @ 33 NONAME
+	_ZTI12CTestIniData @ 2 NONAME
+	_ZTI16RTSUMmTsthStep11 @ 3 NONAME
+	_ZTI16RTestMmTsthU1101 @ 4 NONAME
+	_ZTI16RTestMmTsthU1102 @ 5 NONAME
+	_ZTI16RTestMmTsthU1103 @ 6 NONAME
+	_ZTI16RTestMmTsthU1104 @ 7 NONAME
+	_ZTI16RTestMmTsthU1105 @ 8 NONAME
+	_ZTI16RTestMmTsthU1111 @ 9 NONAME
+	_ZTI17CTSUMmTsthSuite11 @ 10 NONAME
+	_ZTI20RTestStepVirtualStub @ 11 NONAME
+	_ZTI21CTestSuiteVirtualStub @ 12 NONAME
+	_ZTV12CTestIniData @ 13 NONAME
+	_ZTV16RTSUMmTsthStep11 @ 14 NONAME
+	_ZTV16RTestMmTsthU1101 @ 15 NONAME
+	_ZTV16RTestMmTsthU1102 @ 16 NONAME
+	_ZTV16RTestMmTsthU1103 @ 17 NONAME
+	_ZTV16RTestMmTsthU1104 @ 18 NONAME
+	_ZTV16RTestMmTsthU1105 @ 19 NONAME
+	_ZTV16RTestMmTsthU1111 @ 20 NONAME
+	_ZTV17CTSUMmTsthSuite11 @ 21 NONAME
+	_ZTV20RTestStepVirtualStub @ 22 NONAME
+	_ZTV21CTestSuiteVirtualStub @ 23 NONAME
 
--- a/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth12U.DEF	Fri Apr 16 16:34:49 2010 +0300
+++ b/mmtestenv/mmtestfwunittest/eabi/TSU_MmTsth12U.DEF	Mon May 03 13:56:28 2010 +0300
@@ -1,35 +1,21 @@
 EXPORTS
 	_Z20NewTSUMmTsthSuite12Lv @ 1 NONAME
-	_ZTI10CTestSuite @ 2 NONAME ; #<TI>#
-	_ZTI12CTestIniData @ 3 NONAME ; #<TI>#
-	_ZTI16RTSUMmTsthStep12 @ 4 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1201 @ 5 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1202 @ 6 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1203 @ 7 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1221 @ 8 NONAME ; #<TI>#
-	_ZTI16RTestMmTsthU1222 @ 9 NONAME ; #<TI>#
-	_ZTI17CTSUMmTsthSuite12 @ 10 NONAME ; #<TI>#
-	_ZTI20RTestStepVirtualStub @ 11 NONAME ; #<TI>#
-	_ZTI21CTestSuiteVirtualStub @ 12 NONAME ; #<TI>#
-	_ZTI29TIntegrationTestLog16Overflow @ 13 NONAME ; #<TI>#
-	_ZTI9CTestStep @ 14 NONAME ; #<TI>#
-	_ZTI9RTestStep @ 15 NONAME ; #<TI>#
-	_ZTV10CTestSuite @ 16 NONAME ; #<VT>#
-	_ZTV12CTestIniData @ 17 NONAME ; #<VT>#
-	_ZTV16RTSUMmTsthStep12 @ 18 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1201 @ 19 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1202 @ 20 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1203 @ 21 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1221 @ 22 NONAME ; #<VT>#
-	_ZTV16RTestMmTsthU1222 @ 23 NONAME ; #<VT>#
-	_ZTV17CTSUMmTsthSuite12 @ 24 NONAME ; #<VT>#
-	_ZTV20RTestStepVirtualStub @ 25 NONAME ; #<VT>#
-	_ZTV21CTestSuiteVirtualStub @ 26 NONAME ; #<VT>#
-	_ZTV29TIntegrationTestLog16Overflow @ 27 NONAME ; #<VT>#
-	_ZTV9CTestStep @ 28 NONAME ; #<VT>#
-	_ZTV9RTestStep @ 29 NONAME ; #<VT>#
-	_ZTI14RAsyncTestStep @ 30 NONAME
-	_ZTI4CLog @ 31 NONAME
-	_ZTV14RAsyncTestStep @ 32 NONAME
-	_ZTV4CLog @ 33 NONAME
+	_ZTI16RTSUMmTsthStep12 @ 2 NONAME
+	_ZTI16RTestMmTsthU1201 @ 3 NONAME
+	_ZTI16RTestMmTsthU1202 @ 4 NONAME
+	_ZTI16RTestMmTsthU1203 @ 5 NONAME
+	_ZTI16RTestMmTsthU1221 @ 6 NONAME
+	_ZTI16RTestMmTsthU1222 @ 7 NONAME
+	_ZTI17CTSUMmTsthSuite12 @ 8 NONAME
+	_ZTI20RTestStepVirtualStub @ 9 NONAME
+	_ZTI21CTestSuiteVirtualStub @ 10 NONAME
+	_ZTV16RTSUMmTsthStep12 @ 11 NONAME
+	_ZTV16RTestMmTsthU1201 @ 12 NONAME
+	_ZTV16RTestMmTsthU1202 @ 13 NONAME
+	_ZTV16RTestMmTsthU1203 @ 14 NONAME
+	_ZTV16RTestMmTsthU1221 @ 15 NONAME
+	_ZTV16RTestMmTsthU1222 @ 16 NONAME
+	_ZTV17CTSUMmTsthSuite12 @ 17 NONAME
+	_ZTV20RTestStepVirtualStub @ 18 NONAME
+	_ZTV21CTestSuiteVirtualStub @ 19 NONAME
 
--- a/omxil/omxilcomponentcommon/bwins/omxilcomponentcommon.def	Fri Apr 16 16:34:49 2010 +0300
+++ b/omxil/omxilcomponentcommon/bwins/omxilcomponentcommon.def	Mon May 03 13:56:28 2010 +0300
@@ -36,7 +36,7 @@
 	?HandleInsufficientResources@XOmxILCallbackManagerIfImpl@@MAEXXZ @ 35 NONAME ; void XOmxILCallbackManagerIfImpl::HandleInsufficientResources(void)
 	?DoRegisterILClientCallbacks@XOmxILCallbackManagerIfImpl@@MAE?AW4OMX_ERRORTYPE@@PBUOMX_CALLBACKTYPE@@PAX@Z @ 36 NONAME ; enum OMX_ERRORTYPE XOmxILCallbackManagerIfImpl::DoRegisterILClientCallbacks(struct OMX_CALLBACKTYPE const *, void *)
 	?Compare@TBufferInfo@COmxILPort@@SAHABV12@0@Z @ 37 NONAME ; int COmxILPort::TBufferInfo::Compare(class COmxILPort::TBufferInfo const &, class COmxILPort::TBufferInfo const &)
-	?RunL@COmxILCallbackManager@@UAEXXZ @ 38 NONAME ; void COmxILCallbackManager::RunL(void)
+	?RunL@COmxILCallbackManager@@UAEXXZ @ 38 NONAME ABSENT ; void COmxILCallbackManager::RunL(void)
 	?SetParameter@COmxILVideoPort@@UAE?AW4OMX_ERRORTYPE@@W4OMX_INDEXTYPE@@PBXAAH@Z @ 39 NONAME ; enum OMX_ERRORTYPE COmxILVideoPort::SetParameter(enum OMX_INDEXTYPE, void const *, int &)
 	?RegisterBufferMarkPropagationPort@COmxILInContextCallbackManager@@UAE?AW4OMX_ERRORTYPE@@KK@Z @ 40 NONAME ; enum OMX_ERRORTYPE COmxILInContextCallbackManager::RegisterBufferMarkPropagationPort(unsigned long, unsigned long)
 	?MediaTimeIndication@COmxILProcessingFunction@@UAE?AW4OMX_ERRORTYPE@@ABUOMX_TIME_MEDIATIMETYPE@@@Z @ 41 NONAME ; enum OMX_ERRORTYPE COmxILProcessingFunction::MediaTimeIndication(struct OMX_TIME_MEDIATIMETYPE const &)
@@ -58,7 +58,7 @@
 	?BufferDoneNotification@COmxILInContextCallbackManager@@UAE?AW4OMX_ERRORTYPE@@PAUOMX_BUFFERHEADERTYPE@@KW4OMX_DIRTYPE@@@Z @ 57 NONAME ; enum OMX_ERRORTYPE COmxILInContextCallbackManager::BufferDoneNotification(struct OMX_BUFFERHEADERTYPE *, unsigned long, enum OMX_DIRTYPE)
 	?GetComponentVersion@COmxILConfigManager@@UBE?AW4OMX_ERRORTYPE@@PADPATOMX_VERSIONTYPE@@1PAY0IA@E@Z @ 58 NONAME ; enum OMX_ERRORTYPE COmxILConfigManager::GetComponentVersion(char *, union OMX_VERSIONTYPE *, union OMX_VERSIONTYPE *, unsigned char [128] *) const
 	?DoEventNotification@XOmxILCallbackManagerIfImpl@@MAE?AW4OMX_ERRORTYPE@@W4OMX_EVENTTYPE@@KKPAD@Z @ 59 NONAME ; enum OMX_ERRORTYPE XOmxILCallbackManagerIfImpl::DoEventNotification(enum OMX_EVENTTYPE, unsigned long, unsigned long, char *)
-	?DoCancel@COmxILCallbackManager@@UAEXXZ @ 60 NONAME ; void COmxILCallbackManager::DoCancel(void)
+	?DoCancel@COmxILCallbackManager@@UAEXXZ @ 60 NONAME ABSENT ; void COmxILCallbackManager::DoCancel(void)
 	?SetParameter@COmxILOtherPort@@UAE?AW4OMX_ERRORTYPE@@W4OMX_INDEXTYPE@@PBXAAH@Z @ 61 NONAME ; enum OMX_ERRORTYPE COmxILOtherPort::SetParameter(enum OMX_INDEXTYPE, void const *, int &)
 	??1COmxILAudioPort@@UAE@XZ @ 62 NONAME ; COmxILAudioPort::~COmxILAudioPort(void)
 	?RegisterComponentHandle@COmxILInContextCallbackManager@@UAE?AW4OMX_ERRORTYPE@@PAX@Z @ 63 NONAME ; enum OMX_ERRORTYPE COmxILInContextCallbackManager::RegisterComponentHandle(void *)
--- a/omxil/omxilcomponentcommon/eabi/omxilcomponentcommon.def	Fri Apr 16 16:34:49 2010 +0300
+++ b/omxil/omxilcomponentcommon/eabi/omxilcomponentcommon.def	Mon May 03 13:56:28 2010 +0300
@@ -271,5 +271,4 @@
 	_ZThn4_N30COmxILInContextCallbackManagerD0Ev @ 270 NONAME
 	_ZThn4_N30COmxILInContextCallbackManagerD1Ev @ 271 NONAME
 	_ZThn8_N30COmxILInContextCallbackManagerD0Ev @ 272 NONAME
-	_ZThn8_N30COmxILInContextCallbackManagerD1Ev @ 273 NONAME
-
+	_ZThn8_N30COmxILInContextCallbackManagerD1Ev @ 273 NONAME
\ No newline at end of file
--- a/omxil/omxilcomponentcommon/src/common/omxilcallbackmanager.h	Fri Apr 16 16:34:49 2010 +0300
+++ b/omxil/omxilcomponentcommon/src/common/omxilcallbackmanager.h	Mon May 03 13:56:28 2010 +0300
@@ -157,8 +157,9 @@
 	//
 	// From CActive
 	//
-	IMPORT_C void RunL();
-	IMPORT_C void DoCancel();
+private:
+	void RunL();
+	void DoCancel();
 
 private:
 
--- a/omxil/omxilcore/src/omxilcoreclient/omxilcoreclientsession.cpp	Fri Apr 16 16:34:49 2010 +0300
+++ b/omxil/omxilcore/src/omxilcoreclient/omxilcoreclientsession.cpp	Mon May 03 13:56:28 2010 +0300
@@ -293,7 +293,12 @@
 	RHandleBase::Close();
 
 	// Release server handle so it will exit cleanly.
-	XGlobalILCoreCache::IlCoreCache()->SetServerHandle(KNullHandle);
+	XGlobalILCoreCache* pGlobalILCoreCache = XGlobalILCoreCache::IlCoreCache();
+
+	__ASSERT_ALWAYS(pGlobalILCoreCache != NULL,
+					User::Panic(KOmxILCoreClientPanic, KErrNotReady));
+
+	pGlobalILCoreCache->SetServerHandle(KNullHandle);
 	
 	RThread serverThread;
 	TInt ret = serverThread.Open(TThreadId(serverThreadId));