diff -r 1eef62f5c541 -r 2a5d4ab426d3 phoneplugins/csplugin/src/tmshandler.cpp --- 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 #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(stream).GetStreamType(); + TMSStreamType strmType = const_cast (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 } } }