devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp
changeset 15 c1e808730d6c
parent 13 efebd1779a59
child 24 2672ba96448e
--- 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