phoneplugins/csplugin/src/tmshandler.cpp
changeset 65 2a5d4ab426d3
parent 27 2f8f8080a020
child 76 cfea66083b62
--- a/phoneplugins/csplugin/src/tmshandler.cpp	Mon Aug 23 15:42:12 2010 +0300
+++ b/phoneplugins/csplugin/src/tmshandler.cpp	Fri Sep 03 13:33:36 2010 +0300
@@ -11,7 +11,7 @@
  *
  * Contributors:
  *
- * Description:  Starts and stops audio streams.
+ * Description: Activates TMS call audio control streams.
  *
  */
 
@@ -20,28 +20,19 @@
 #include <tmsstream.h>
 #include "tmshandler.h"
 #include "csplogger.h"
-#include "csptimer.h"
 #include "csppanic.pan"
+#include "mtmshandlerobserver.h"
 
-/**
- * Timeout initial value.
- */
-const TInt KTimeoutInitial = 200000; // 0.2s
-
-/**
- * Double the timeout for every retry.
- */
-const TInt KTimeoutMultiplier = 2;
-
-// ======== MEMBER FUNCTIONS ========
+const TInt KStreamInitRetry = 1000000; //1 sec
+const TInt KRetryForever = -1;
 
 // ---------------------------------------------------------------------------
 // Static constructor
 // ---------------------------------------------------------------------------
 //
-TmsHandler* TmsHandler::NewL()
+TmsHandler* TmsHandler::NewL(MTmsHandlerObserver& aObserver)
     {
-    TmsHandler* self = TmsHandler::NewLC();
+    TmsHandler* self = TmsHandler::NewLC(aObserver);
     CleanupStack::Pop(self);
     return self;
     }
@@ -50,11 +41,11 @@
 // Static constructor
 // ---------------------------------------------------------------------------
 //
-TmsHandler* TmsHandler::NewLC()
+TmsHandler* TmsHandler::NewLC(MTmsHandlerObserver& aObserver)
     {
     TmsHandler* self = new (ELeave) TmsHandler();
     CleanupStack::PushL(self);
-    self->ConstructL();
+    self->ConstructL(aObserver);
     return self;
     }
 
@@ -64,19 +55,12 @@
 //
 TmsHandler::~TmsHandler()
     {
-    if (iTimer)
-        {
-        iTimer->CancelNotify();
-        delete iTimer;
-        }
     if (iTmsUplink && iTmsCall)
         {
-        // CloseUplink();
         iTmsCall->DeleteStream(iTmsUplink);
         }
     if (iTmsDnlink && iTmsCall)
         {
-        // CloseDownlink();
         iTmsCall->DeleteStream(iTmsDnlink);
         }
     if (iFactory && iTmsCall)
@@ -99,70 +83,104 @@
         {
         iFactory->DeleteSink(iTmsModemSink);
         }
-
     delete iFactory;
-
     }
 
 // ---------------------------------------------------------------------------
-// From class MCSPAudioStream
-// Activates mic and speaker.
+// TmsHandler::StartStreams
+// Activates TMS call audio control streams. If called in the middle of an
+// ongoing stream initialization, the request is cashed in until both streams
+// transition to initialized state.
 // ---------------------------------------------------------------------------
 //
-void TmsHandler::StartStreams()
+TInt TmsHandler::StartStreams()
     {
     CSPLOGSTRING(CSPINT, "TmsHandler::StartStreams");
+    TInt status(TMS_RESULT_SUCCESS);
 
-    StartMicAndSpeaker();
+    if (iTmsUplink)
+        {
+        if (iTmsUplink->GetState() == TMS_STREAM_INITIALIZED)
+            {
+            status = iTmsUplink->Start(KRetryForever);
+            }
+        else if (iUplInitializing)
+            {
+            iStartAfterInitComplete = ETrue;
+            }
+        }
+
+    if (iTmsDnlink && status == TMS_RESULT_SUCCESS)
+        {
+        if (iTmsDnlink->GetState() == TMS_STREAM_INITIALIZED)
+            {
+            status = iTmsDnlink->Start(KRetryForever);
+            }
+        else if (iDnlInitializing)
+            {
+            iStartAfterInitComplete = ETrue;
+            }
+        }
+
+    CSPLOGSTRING2(CSPINT, "TmsHandler::StartStreams status %d", status);
+
+    if (status != TMS_RESULT_SUCCESS)
+        {
+        // Cancel any pending retry and cancel.
+        StopStreams();
+        status = KErrCancel;
+        }
+    return status;
     }
 
 // ---------------------------------------------------------------------------
-// From class MCSPAudioStream
-// Deactivates mic and speaker if the streams are active or they are
-// activating.
+// TmsHandler::StopStreams
+// Deactivates TMS call audio control streams. If streams are not started yet,
+// any pending request on TMS streams will be canceled.
 // ---------------------------------------------------------------------------
 //
 void TmsHandler::StopStreams()
     {
     CSPLOGSTRING(CSPINT, "TmsHandler::StopStreams");
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTimer && IsMicAndSpeakerStarted())
+
+    if (iTmsUplink)
         {
-        CSPLOGSTRING(CSPINT, "TmsHandler::StopStreams Stopping");
-        iTimer->CancelNotify();
-        iTimeout = KTimeoutInitial;
-        status = iTmsUplink->Stop();
-        iUplinkStarted = FALSE;
-        status |= iTmsDnlink->Stop();
-        iDnlinkStarted = FALSE;
-
-        if (status != TMS_RESULT_SUCCESS)
-            {
-            status = TMS_RESULT_GENERAL_ERROR;
-            }
+        iTmsUplink->Stop();
         }
-    CSPLOGSTRING2(CSPINT, "TmsHandler::StopStreams status %d", status);
+    if (iTmsDnlink)
+        {
+        iTmsDnlink->Stop();
+        }
+    iUplInitializing = EFalse;
+    iDnlInitializing = EFalse;
+    iStartAfterInitComplete = EFalse;
     }
 
 // ---------------------------------------------------------------------------
-// From class MCSPTimerObserver
-// Notify from CSPTimer that timeout passed. Try to start mic and
-// speaker again.
+// TmsHandler::AreStreamsStarted
+// Indicates whether both audio control streams have been started.
 // ---------------------------------------------------------------------------
 //
-void TmsHandler::TimerEvent()
+TBool TmsHandler::AreStreamsStarted()
     {
-    CSPLOGSTRING(CSPINT, "TmsHandler.TimerEvent" );
-    iTimeout *= KTimeoutMultiplier;
-    StartMicAndSpeaker();
+    TBool status(EFalse);
+
+    if (iTmsUplink && iTmsDnlink)
+        {
+        if (iTmsUplink->GetState() == TMS_STREAM_STARTED &&
+                iTmsDnlink->GetState() == TMS_STREAM_STARTED)
+            {
+            status = ETrue;
+            }
+        }
+    return status;
     }
 
 // ---------------------------------------------------------------------------
 // Constructor
 // ---------------------------------------------------------------------------
 //
-TmsHandler::TmsHandler() :
-    iTimeout(KTimeoutInitial)
+TmsHandler::TmsHandler()
     {
     }
 
@@ -170,337 +188,184 @@
 // Second phase constructor
 // ---------------------------------------------------------------------------
 //
-void TmsHandler::ConstructL()
+void TmsHandler::ConstructL(MTmsHandlerObserver& aObserver)
     {
     CSPLOGSTRING(CSPINT, "TmsHandler::ConstructL");
-    iTimer = CSPTimer::NewL();
-
-    if (CreateTMSCallControl())
-        {
-        User::LeaveIfError(TMS_RESULT_UNINITIALIZED_OBJECT);
-        }
+    iObserver = &aObserver;
+    User::LeaveIfError(CreateTMSCallControl());
     }
 
 // ---------------------------------------------------------------------------
 // TmsHandler::CreateTMSCallControl()
+// Allocates and initializes all TMS resources needed for call audio control.
 // ---------------------------------------------------------------------------
 //
-gint TmsHandler::CreateTMSCallControl()
+TInt TmsHandler::CreateTMSCallControl()
     {
+    CSPLOGSTRING(CSPINT, "TmsHandler::CreateTMSCallControl");
     TMSVer* v = NULL;
     TInt status;
     status = TMSFactory::CreateFactory(iFactory, *v);
 
-    __ASSERT_ALWAYS(iFactory, Panic( ECSPPanicBadHandle));
+    __ASSERT_ALWAYS(iFactory, Panic(ECSPPanicBadHandle));
 
     status = iFactory->CreateCall(TMS_CALL_CS, iTmsCall, 0);
 
-    status |= CreateUplink();
-    status |= CreateDownlink();
-    status |= CreateMicSource();
-    status |= AddMicSourceToStream();
-    status |= CreateModemSink();
-    status |= AddModemSinkToStream();
-    status |= CreateModemSource();
-    status |= AddModemSourceToStream();
-    status |= CreateSpeakerSink();
-    status |= AddSpeakerSinkToStream();
-    status |= OpenDownlink();
-
-    return status;
-    }
-
-// ---------------------------------------------------------------------------
-// Resets timer
-// ---------------------------------------------------------------------------
-//
-void TmsHandler::AudioStreamsStarted()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::AudioStreamsStarted" );
-    iTimeout = KTimeoutInitial;
-    iTimer->CancelNotify();
-    }
-
-// ---------------------------------------------------------------------------
-// Starts timer
-// ---------------------------------------------------------------------------
-//
-void TmsHandler::StartTimer()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::StartTimer" );
-    iTimer->NotifyAfter(iTimeout, *this);
-    }
-
-// ---------------------------------------------------------------------------
-// Starts mic and speaker
-// ---------------------------------------------------------------------------
-//
-void TmsHandler::StartMicAndSpeaker()
-    {
-    // if speaker and mic is active then activation does not cause any actions.
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iTmsUplink)
-        {
-        status = iTmsUplink->Start();
-        }
-    CSPLOGSTRING2( CSPINT, "TmsHandler::StartMicAndSpeaker status %d", status );
-    }
-
-// ---------------------------------------------------------------------------
-// Indicated if mic and speaker are started or starting up.
-// ---------------------------------------------------------------------------
-//
-TBool TmsHandler::IsMicAndSpeakerStarted()
-    {
-    return (iUplinkStarted || iDnlinkStarted);
-    }
-
-// ----------------------------------------------------------------------------
-// CreateUplink
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::CreateUplink()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::CreateUplink");
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTmsCall)
+    if (iTmsCall && status == TMS_RESULT_SUCCESS)
         {
         status = iTmsCall->CreateStream(TMS_STREAM_UPLINK, iTmsUplink);
+        status |= iTmsCall->CreateStream(TMS_STREAM_DOWNLINK, iTmsDnlink);
+        status |= iFactory->CreateSource(TMS_SOURCE_MIC, iTmsMicSource);
+        status |= iFactory->CreateSink(TMS_SINK_MODEM, iTmsModemSink);
+        status |= iFactory->CreateSource(TMS_SOURCE_MODEM, iTmsModemSource);
+        status |= iFactory->CreateSink(TMS_SINK_SPEAKER, iTmsSpeakerSink);
         }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// CreateDownlink
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::CreateDownlink()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::CreateDownlink");
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iTmsCall)
+    if (iTmsUplink && iTmsMicSource && iTmsModemSink &&
+            status == TMS_RESULT_SUCCESS)
+        {
+        status = iTmsUplink->AddSource(iTmsMicSource);
+        status |= iTmsUplink->AddSink(iTmsModemSink);
+        status |= iTmsUplink->AddObserver(*this, NULL);
+        status |= iTmsUplink->Init(KStreamInitRetry);
+        }
+    if (iTmsDnlink && iTmsModemSource && iTmsSpeakerSink &&
+            status == TMS_RESULT_SUCCESS)
         {
-        status = iTmsCall->CreateStream(TMS_STREAM_DOWNLINK, iTmsDnlink);
+        status = iTmsDnlink->AddSource(iTmsModemSource);
+        status |= iTmsDnlink->AddSink(iTmsSpeakerSink);
+        status |= iTmsDnlink->AddObserver(*this, NULL);
+        status |= iTmsDnlink->Init(KStreamInitRetry);
+        }
+    if (status == TMS_RESULT_SUCCESS)
+        {
+        iUplInitializing = ETrue;
+        iDnlInitializing = ETrue;
+        }
+    else
+        {
+        status = KErrCancel; // Convert to Symbian error and cancel
         }
     return status;
     }
 
 // ----------------------------------------------------------------------------
-// OpenUplink
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::OpenUplink()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::OpenUplink");
-    gint status = TMS_RESULT_SUCCESS;
-
-    if (iTmsUplink)
-        {
-        status = iTmsUplink->AddObserver(*this, NULL);
-        if (status == TMS_RESULT_SUCCESS)
-            {
-            status = iTmsUplink->Init();
-            }
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// OpenDownlink
+// TmsHandler::ProcessUplinkStreamChangeEvent
+// Processes Uplink stream state change events.
 // ----------------------------------------------------------------------------
 //
-gint TmsHandler::OpenDownlink()
-    {
-    CSPLOGSTRING(CSPINT, "TmsHandler::OpenDownlink");
-    gint status = TMS_RESULT_SUCCESS;
-
-    if (iTmsDnlink)
-        {
-        status = iTmsDnlink->AddObserver(*this, NULL);
-        if (status == TMS_RESULT_SUCCESS)
-            {
-            status = iTmsDnlink->Init();
-            }
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// CreateModemSource
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::CreateModemSource()
+void TmsHandler::ProcessUplinkStreamChangeEvent(TInt aState)
     {
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iFactory && !iTmsModemSource)
+    CSPLOGSTRING(CSPINT, "TmsHandler::ProcessUplinkStreamChangeEvent");
+    switch (aState)
         {
-        status = iFactory->CreateSource(TMS_SOURCE_MODEM, iTmsModemSource);
+        case TMS_STREAM_INITIALIZED:
+            iUplInitializing = EFalse;
+            if (iStartAfterInitComplete)
+                {
+                iStartAfterInitComplete = EFalse;
+                TInt status = StartStreams();
+                if (status != TMS_RESULT_SUCCESS)
+                    {
+                    iObserver->AudioStreamsError(status);
+                    }
+                }
+            break;
+        case TMS_STREAM_UNINITIALIZED:
+            // As result of Deinit() or error
+            iUplInitializing = EFalse;
+            iStartAfterInitComplete = EFalse;
+            break;
+        case TMS_STREAM_PAUSED:
+            break;
+        case TMS_STREAM_STARTED:
+            if (AreStreamsStarted())
+                {
+                iObserver->AudioStreamsStarted();
+                }
+            break;
+        default:
+            break;
         }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// AddModemSourceToStream
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::AddModemSourceToStream()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTmsDnlink && iTmsModemSource)
-        {
-        status = iTmsDnlink->AddSource(iTmsModemSource);
-        }
-    return status;
     }
 
 // ----------------------------------------------------------------------------
-// CreateModemSink
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::CreateModemSink()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iFactory && !iTmsModemSink)
-        {
-        status = iFactory->CreateSink(TMS_SINK_MODEM, iTmsModemSink);
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// AddModemSinkToStream
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::AddModemSinkToStream()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTmsUplink && iTmsModemSink)
-        {
-        status = iTmsUplink->AddSink(iTmsModemSink);
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// CreateMicSource
+// TmsHandler::ProcessDownlinkStreamChangeEvent
+// Processes Downlink stream state change events.
 // ----------------------------------------------------------------------------
 //
-gint TmsHandler::CreateMicSource()
+void TmsHandler::ProcessDownlinkStreamChangeEvent(TInt aState)
     {
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iFactory && !iTmsMicSource)
+    CSPLOGSTRING(CSPINT, "TmsHandler::ProcessDownlinkStreamChangeEvent");
+    switch (aState)
         {
-        status = iFactory->CreateSource(TMS_SOURCE_MIC, iTmsMicSource);
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// AddMicSourceToStream
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::AddMicSourceToStream()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTmsUplink && iTmsMicSource)
-        {
-        status = iTmsUplink->AddSource(iTmsMicSource);
+        case TMS_STREAM_INITIALIZED:
+            iDnlInitializing = EFalse;
+            if (iStartAfterInitComplete)
+                {
+                iStartAfterInitComplete = EFalse;
+                TInt status = StartStreams();
+                if (status != TMS_RESULT_SUCCESS)
+                    {
+                    iObserver->AudioStreamsError(status);
+                    }
+                }
+            break;
+        case TMS_STREAM_UNINITIALIZED:
+            // As result of Deinit() or error
+            iDnlInitializing = EFalse;
+            iStartAfterInitComplete = EFalse;
+            break;
+        case TMS_STREAM_PAUSED:
+            break;
+        case TMS_STREAM_STARTED:
+            if (AreStreamsStarted())
+                {
+                iObserver->AudioStreamsStarted();
+                }
+            break;
+        default:
+            break;
         }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// CreateSpeakerSink
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::CreateSpeakerSink()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-
-    if (iFactory && !iTmsSpeakerSink)
-        {
-        status = iFactory->CreateSink(TMS_SINK_SPEAKER, iTmsSpeakerSink);
-        }
-    return status;
-    }
-
-// ----------------------------------------------------------------------------
-// AddSpeakerSinkToStream
-// ----------------------------------------------------------------------------
-//
-gint TmsHandler::AddSpeakerSinkToStream()
-    {
-    gint status(TMS_RESULT_SUCCESS);
-    if (iTmsDnlink && iTmsSpeakerSink)
-        {
-        status = iTmsDnlink->AddSink(iTmsSpeakerSink);
-        }
-    return status;
     }
 
 // TMS CALLBACKS
 
 // ----------------------------------------------------------------------------
 // TmsHandler::TMSStreamEvent
+// From TMSStreamObserver
+// TMS call audio stream control event handler.
 // ----------------------------------------------------------------------------
 //
 void TmsHandler::TMSStreamEvent(const TMSStream& stream, TMSSignalEvent event)
     {
     CSPLOGSTRING2(CSPINT, "TmsHandler::TMSStreamEvent status %d", event.reason);
 
-    TMSStreamType strmType = const_cast<TMSStream&>(stream).GetStreamType();
+    TMSStreamType strmType = const_cast<TMSStream&> (stream).GetStreamType();
 
-    if (strmType == TMS_STREAM_UPLINK &&
-            event.type == TMS_EVENT_STREAM_STATE_CHANGED)
+    if (strmType == TMS_STREAM_UPLINK)
         {
-        switch (event.curr_state)
+        if (event.type == TMS_EVENT_STREAM_STATE_CHANGED)
             {
-            case TMS_STREAM_INITIALIZED:
-                //notify stream ready state
-                break;
-            case TMS_STREAM_UNINITIALIZED:
-                //notify initialization error
-                break;
-            case TMS_STREAM_PAUSED:
-                break;
-            case TMS_STREAM_STARTED:
-                iUplinkStarted = TRUE;
-                iTmsDnlink->Start();
-                break;
-            default:
-                break;
+            ProcessUplinkStreamChangeEvent(event.curr_state);
+            }
+        else if (event.type == TMS_EVENT_STREAM_STATE_CHANGE_ERROR)
+            {
+#ifndef __WINS__
+            Panic( ECSPPanicAudioStreamInitFailure );
+#endif
             }
         }
-    else if (strmType == TMS_STREAM_DOWNLINK &&
-            event.type == TMS_EVENT_STREAM_STATE_CHANGED)
+    else if (strmType == TMS_STREAM_DOWNLINK)
         {
-        switch (event.curr_state)
+        if (event.type == TMS_EVENT_STREAM_STATE_CHANGED)
             {
-            case TMS_STREAM_INITIALIZED:
-                {
-                if ((iTmsCall->GetCallType() == TMS_CALL_CS)
-                        && (!iUplinkStarted))
-                    {
-                    OpenUplink();
-                    }
-                //notify stream ready state
-                }
-                break;
-            case TMS_STREAM_UNINITIALIZED:
-                //notify initialization error
-                break;
-            case TMS_STREAM_PAUSED:
-                break;
-            case TMS_STREAM_STARTED:
-                iDnlinkStarted = TRUE;
-                break;
-            default:
-                break;
+            ProcessDownlinkStreamChangeEvent(event.curr_state);
+            }
+        else if (event.type == TMS_EVENT_STREAM_STATE_CHANGE_ERROR)
+            {
+#ifndef __WINS__
+            Panic( ECSPPanicAudioStreamInitFailure );
+#endif
             }
         }
     }