diff -r 000000000000 -r 71ca22bcf22a mmserv/callaudiocontrol/src/CallAudioControlImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmserv/callaudiocontrol/src/CallAudioControlImpl.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,1138 @@ +/* +* Copyright (c) 2007 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: This is the implementation of the CCallAudioControlImpl class. +* +*/ + +// INCLUDE FILES +#include "CallAudioControlImpl.h" +#include "CallAudioControlUtility.h" +#include "CallAudioControlProperty.h" +#include "CallAudioControlRepository.h" +#include "CallAudioControlCommon.h" + + +#ifdef __SERIES60_31__ +#include +#include +#include +#include +#include +_LIT(KPhoneCltExDllName, "PhoneClientExt.dll"); +#endif + +// ----------------------------------------------------------------------------- +// CCCallAudioControlImpl::NewL +// +// ----------------------------------------------------------------------------- +// +CCallAudioControlImpl* CCallAudioControlImpl::NewL() + { + CCallAudioControlImpl* self = new (ELeave) CCallAudioControlImpl(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::CCallAudioControlImpl +// C++ constructor. +// ----------------------------------------------------------------------------- +// +CCallAudioControlImpl::CCallAudioControlImpl() + { + } + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCallAudioControlImpl::ConstructL() +{ + CAC_TRACE1(_L("CCallAudioControlImpl::ConstructL enter")); +#ifdef __WINS__ + iWinsTesting = ETrue; +#endif + //Create objects for data base access (both Central Repository and Publish and Subscribe): + iCsNotifier = CCallAudioControlProperty::NewL(this, KUidCallInfo, KTelephonyCallState, ECallState ); +#ifdef __SERIES60_31__ + CAC_TRACE1(_L("CCallAudioControlImpl::ConstructL Creating CMediatorCommandInitiator for 3.1 ")); + iCommandInitiator = CMediatorCommandInitiator::NewL( this ); + iMuteNotifier = CCallAudioControlProperty::NewL(this,KUidSystemCategory, KUidMute.iUid, EMute); +#else + CAC_TRACE1(_L("CCallAudioControlImpl::ConstructL Creating CPhoneClient for non 3.1 ")); + iPhoneClient = CPhCltCommandHandler::NewL(); + iMuteNotifier = CCallAudioControlProperty::NewL(this,KUidMute, KTelephonyMute, EMute); +#endif + iIhfVolumeNotifier = CCallAudioControlRepository::NewL(this,KUidVolume, KTelephonyIHFVolume, EIHFVolume); + iEpVolumeNotifier = CCallAudioControlRepository::NewL(this, KUidVolume, KTelephonyEPVolume, EEPVolume); + // Get current call state and is it active: + TBool active = IsCallActive(); + CAC_TRACE2(_L("CCallAudioControl: Current Call State: %d"),iCallState); + // If in active call create TAR, get current audio output routing and + // get volume (based on audio routing) and set iVolume: + if (active) + { + CAC_TRACE1(_L("CCallAudioControl: Active Call: Setting iVolume, etc...")); + iTelephonyAudioRouting = CTelephonyAudioRouting::NewL(*this); + iCurrentAudioOutput = (CCallAudioControl::TAudioOutput)iTelephonyAudioRouting->Output(); + TInt error = GetVolume(); + } + else // Otherwise, get EP volume and set iVolume = EPVolume + { + TInt error = iEpVolumeNotifier->Get(iVolume); + CAC_TRACE2(_L("CCallAudioControl: Not active call, setting iVolume to EPVolume = %d"),iVolume); + } + // Subscribe for call state changes: + // if CAC is created before an active call, then we need to subscribe to Telephony notifications whenever the + // the call is active, so that CAC can create TAR for audio routing + iCsNotifier->Subscribe(); + CAC_TRACE1(_L("CCallAudioControlImpl::ConstructL exit")); +} + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::DestructL +// Destructor +// ----------------------------------------------------------------------------- +// +CCallAudioControlImpl::~CCallAudioControlImpl() + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::~AudioOutputControlImpl enter"),this); + // Empty arrays: + iRoutingObservers.Reset(); + iDownlinkVolumeObservers.Reset(); + iUplinkGainObservers.Reset(); + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting Volume Notifiers..."),this); + delete iEpVolumeNotifier; + delete iIhfVolumeNotifier; + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting Call State Notifier..."),this); + delete iCsNotifier; + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting Mute Notifier..."),this); + delete iMuteNotifier; + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting TAR..."),this); + delete iTelephonyAudioRouting; +#ifdef __SERIES60_31__ + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting iCommandInitiator (3.1 ONLY)..."),this); + delete iCommandInitiator; +#else + CAC_TRACE2(_L("~CAudioOutputControlImpl: Deleting iPhoneClient..."),this); + delete iPhoneClient; +#endif + + + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::~AudioOutputControlImpl exit"),this); + + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::AppendRoutingObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::AppendRoutingObserver(CRoutingObserver& aObserver) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::AppendRoutingObserver enter"),this); + // Return with error if it's already in list: + for( TInt i = 0; i < iRoutingObservers.Count(); i++ ) + { + if ( iRoutingObservers[i] == &aObserver ) + { + CAC_TRACE1(_L("AppendRoutingObserver ERROR: Already Exists")); + return KErrAlreadyExists; + } + } + iRoutingObservers.Append(&aObserver); + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::AppendRoutingObserver exit"),this); + return KErrNone; + + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::RemoveRoutingObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::RemoveRoutingObserver(CRoutingObserver& aObserver) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::RemoveRoutingObserver enter"),this); + TInt error(KErrNotFound); + for( TInt i = 0; i < iRoutingObservers.Count(); i++ ) + { + if ( iRoutingObservers[i] == &aObserver ) + { + iRoutingObservers.Remove(i); + error = KErrNone; + break; + } + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::RemoveRoutingObserver exit with error: %d"),this, error); + return error; + + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::AppendDownlinkVolumeObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::AppendDownlinkVolumeObserver(CDownlinkVolumeObserver& aObserver) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::AppendDownlinkVolumeObserver enter"),this); + // Return with error if it's already in list: + for( TInt i = 0; i < iDownlinkVolumeObservers.Count(); i++ ) + { + if ( iDownlinkVolumeObservers[i] == &aObserver ) + { + CAC_TRACE1(_L("AppendDownlinkVolumeObserver ERROR: Already Exists")); + return KErrAlreadyExists; + } + } + iDownlinkVolumeObservers.Append(&aObserver); + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::AppendDownlinkVolumeObserver exit"),this); + return KErrNone; + +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::RemoveDownlinkVolumeObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::RemoveDownlinkVolumeObserver(CDownlinkVolumeObserver& aObserver) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::RemoveDownlinkVolumeObserver enter"),this); + TInt error(KErrNotFound); + for( TInt i = 0; i < iDownlinkVolumeObservers.Count(); i++ ) + { + if ( iDownlinkVolumeObservers[i] == &aObserver ) + { + iDownlinkVolumeObservers.Remove(i); + error = KErrNone; + } + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::RemoveDownlinkVolumeObserver exit with error: %d"),this, error); + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::AppendUplinkGainObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::AppendUplinkGainObserver(CUplinkGainObserver& aObserver) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::AppendUplinkGainObserver enter"),this); + TInt error(KErrNone); + // Return with error if it's already in list: + for( TInt i = 0; i < iUplinkGainObservers.Count(); i++ ) + { + if ( iUplinkGainObservers[i] == &aObserver ) + { + CAC_TRACE1(_L("AppendUplinkGainObserver ERROR: Already Exists")); + return KErrAlreadyExists; + } + } + error = iUplinkGainObservers.Append(&aObserver); + if (error == KErrNone) + { + iMuteNotifier->Subscribe(); + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::AppendUplinkGainObserver Error [%d] exit"),this, error); + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::RemoveUplinkGainObserver +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::RemoveUplinkGainObserver(CUplinkGainObserver& aObserver) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]RemoveUplinkGainObserver enter"),this); + TInt error(KErrNotFound); + for( TInt i = 0; i < iUplinkGainObservers.Count(); i++ ) + { + if ( iUplinkGainObservers[i] == &aObserver ) + { + iUplinkGainObservers.Remove(i); + error = KErrNone; + } + } + // Unsubscribe for mute updates if list is empty and currently subscribed + if ( !iUplinkGainObservers.Count() ) + { + iMuteNotifier->Unsubscribe(); + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::RemoveUplinkGainObserver exit with error: %d"),this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetAvaliableOutputs +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetAvailableOutputs(RArray& aAvailableOutputs) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetAvailableOutputs enter"),this); + TInt error(KErrNone); + CCallAudioControl::TAudioOutput arrayElement; + TBool active = IsCallActive(); + if (active) + { + if (!iTelephonyAudioRouting) + { + CAC_TRACE1(_L("CCallAudioControlImpl[%x]::GetAvailableOutputs TAR not available ")); + return KErrCompletion; + } + TArray availableOutputArray = iTelephonyAudioRouting->AvailableOutputs(); + TInt arrayCount = availableOutputArray.Count(); + for (TInt i = 0; i < arrayCount; i++) + { + CAC_TRACE3(_L("AvailableOutput[%d] = %d"), i, availableOutputArray[i]); + arrayElement = (CCallAudioControl::TAudioOutput)(availableOutputArray[i]); + aAvailableOutputs.Append(arrayElement); + } + } + else + error = KErrPermissionDenied; + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::GetAvailableOutputs exit with error: %d"),this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetOutput +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetOutput(CCallAudioControl::TAudioOutput& aOutput) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetOutput enter"),this); + TInt error(KErrNone); + TBool active = IsCallActive(); + if (active) + { + if (!iTelephonyAudioRouting) + { + CAC_TRACE1(_L("CCallAudioControlImpl[%x]::GetOutput TAR not available ")); + return KErrCompletion; + } + aOutput = (CCallAudioControl::TAudioOutput)(iTelephonyAudioRouting->Output()); + iCurrentAudioOutput = aOutput; + CAC_TRACE2(_L("GetOutput: Output retrieved: %d"),aOutput); + } + else + error = KErrPermissionDenied; + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::GetOutput exit with error: %d"),this, error); + + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::::SetOutput +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::SetOutput(CCallAudioControl::TAudioOutput aOutput) +{ + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetOutput with: %d"),this, aOutput); + TInt error(KErrNone); + TBool active = IsCallActive(); + if (active) + { + if (!iTelephonyAudioRouting) + { + CAC_TRACE1(_L("CCallAudioControlImpl[%x]::SetOutput TAR not available ")); + return KErrCompletion; + } + + if ((aOutput == CTelephonyAudioRouting::ENone) || (aOutput == CTelephonyAudioRouting::ENotActive)) + { + return (KErrArgument); + } + TRAP(error,iTelephonyAudioRouting->SetOutputL((CTelephonyAudioRouting::TAudioOutput)aOutput)); + } + else + { + error = KErrPermissionDenied; + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetOutput exit with error: %d"),this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::::PreviousOutput +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::PreviousOutput(CCallAudioControl::TAudioOutput& aPreviousOutput) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::PreviousOutput enter"),this); + TInt error(KErrNone); + TBool active = IsCallActive(); + if (active) + { + if (!iTelephonyAudioRouting) + { + CAC_TRACE1(_L("CCallAudioControlImpl[%x]::PreviousOutput TAR not available ")); + return KErrCompletion; + } + aPreviousOutput = (CCallAudioControl::TAudioOutput)iTelephonyAudioRouting->PreviousOutput(); + } + else + { + error = KErrPermissionDenied; + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::PreviousOutput exit with error: %d"),this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetMinDownlinkVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetMinDownlinkVolume(TUint& aVolume) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetMinDownlinkVolume"),this); + // Hard-coded to 0: + aVolume = KMinVolume; + return KErrNone; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetDownlinkVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetDownlinkVolume(TUint& aVolume) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::GetDownlinkVolume will return: iVolume"),this, iVolume); + TInt error(KErrNone); + if (iVolume < 0) // An error occurred while getting iVolume form DBase prior + { + error = iVolume; // return error to client + } + else + { + aVolume = iVolume; + } + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetMaxDownlinkVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetMaxDownlinkVolume(TUint& aVolume) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetMaxDownlinkVolume"),this); + // Hard-coded to 10: + aVolume = KMaxVolume; + return KErrNone; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::SetDownlinkVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::SetDownlinkVolume(TUint aVolume) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetDownlinkVolume to: %d"),this, aVolume); + TInt newVolume = 0; + // Verify OK to set volume, which is only allowed during an + // active call and if audio routing is appropriate: + TInt error = CheckIfOkToSetVolume(); + if (error != KErrNone) + { + CAC_TRACE2(_L("SetDownlinkVolume: ERROR: %d"), error); + return error; + } + // Make sure aVolume range is valid and set newVolume: + newVolume = VerifyAndSetVolume(aVolume); + TUint currVol; + RETURN_IF_ERROR(GetDownlinkVolume(currVol)); + if (currVol != aVolume) + { + // Update correct volume key, based on current audio routing: + if ( (iCurrentAudioOutput == CTelephonyAudioRouting::EHandset) || (iCurrentAudioOutput == CTelephonyAudioRouting::EWiredAudioAccessory)) + { + error = iEpVolumeNotifier->Set(newVolume); + iPendingEpVolLevelOp = ETrue; + iRequestedEpVolLevel = aVolume; + } + else if (iCurrentAudioOutput == CTelephonyAudioRouting::ELoudspeaker) + { + error = iIhfVolumeNotifier->Set(newVolume); + iPendingIhfVolLevelOp = ETrue; + iRequestedIhfVolLevel = aVolume; + } + else + error = KErrArgument; // invalid iCurrentAudioOutput value + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetDownlinkVolume exit with error: %d"),this, error); + return error; + + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::GetUplinkMute +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetUplinkMute(TBool& aMute) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetUplinkMute enter"),this); + TInt error = iMuteNotifier->Get(aMute); + RETURN_IF_ERROR(error); +#ifdef __SERIES60_31__ + if (aMute == EPSMicMuteOn) + aMute = ETrue; + else if ((aMute == EPSMicMuteOff) || (aMute == EPSMicMuteStateUninitialized)) + aMute = EFalse; + else + error = KErrUnknown; +#else + /* 3.2 and beyond: */ + /* 3.2 also appears to be an enum defined in s60/app/telephony/inc/KPhEngConstants.h + * Check with component owner */ + #ifndef __SERIES60_32__ /* 5.0 and beyond */ + if (aMute == EPSTelMicMuteOn) + aMute = ETrue; + else if ((aMute == EPSTelMicMuteOff) || (aMute == EPSTelMicMuteStateUninitialized)) + aMute = EFalse; + else + error = KErrUnknown; + #endif /*#ifndef __SERIES60_32__*/ +#endif /*#ifdef __SERIES60_31__*/ + + CAC_TRACE2(_L("GetUplinkMute: aMute: %d"),aMute); + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::GetUplinkMute exit with error: %d"),this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::SetUplinkMute +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::SetUplinkMute(TBool aMute) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetUplinkMute with %d"),this, aMute); + // Set only if active call: + TInt error(KErrNone); + TBool active = IsCallActive(); + if (active) + { + if (iWinsTesting) + { + error = KErrPermissionDenied; + } + else + { + TBool curMuteState; + RETURN_IF_ERROR(GetUplinkMute(curMuteState)); + if (aMute != curMuteState) + { + error = SetMute(aMute); // Mute audio + iPendingMuteSetOp = ETrue; + iRequestedMuteState = aMute; + } + } + } + else + { + error = KErrPermissionDenied; + } + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetUplinkMute exit with error: %d"),this, error); + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::SetMute +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::SetMute(TBool aMute) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetMute Enter with %d"),this, aMute); + TInt error(KErrNone); +#ifdef __SERIES60_31__ + TBool coverUIPresent = EFalse; + FeatureManager::InitializeLibL(); + coverUIPresent = FeatureManager::FeatureSupported( KFeatureIdCoverDisplay ); + FeatureManager::UnInitializeLib(); + if ( coverUIPresent ) + { + TSESetMicrophonePckg pckg(aMute); + error = iCommandInitiator->IssueCommand( KMediatorSecondaryDisplayDomain, + KTSECategory, ECmdMuteOrUnmuteMicrophone, TVersion( KVersioMajor, KVersioMinor, KVersioBuild ), pckg ); + } + else + { + TRequestStatus status; + TInt libEntry; + // In S60 3.1 CPhCltCommandHandler cannot be directly used. From 3.2 onwards it can be used directly. + CPhCltExtFactory* phCltExtFactory = NULL; + CPhCltCommandHandler* phCommandHandler = NULL; + User::LeaveIfError( iPhoneClientServer.Connect() ); + User::LeaveIfError( iLibrary.Load( KPhoneCltExDllName ) ); + libEntry = iLibrary.Lookup(1)(); + phCltExtFactory = reinterpret_cast( libEntry ); + if (phCltExtFactory) + { + phCommandHandler = phCltExtFactory->CPhCltCommandHandlerLD(); + User::LeaveIfError( phCommandHandler->Open( iPhoneClientServer ) ); + if (aMute) + { + phCommandHandler->MuteMicrophone(status, ETrue); + } + else + { + phCommandHandler->MuteMicrophone(status, EFalse); + } + User::WaitForRequest( status ); + if (status.Int() != KErrNone) + { + error = KErrGeneral; + } + } + phCommandHandler = NULL; + phCltExtFactory = NULL; + iLibrary.Close(); + iPhoneClientServer.Close(); + } +#else + TRequestStatus status; + if (aMute) + iPhoneClient->MuteMicrophone(status, ETrue); + else + iPhoneClient->MuteMicrophone(status, EFalse); + User::WaitForRequest( status ); + if (status.Int() != KErrNone) + { + CAC_TRACE2(_L("SetMute: ERROR from PhoneClient->MuteMic: %d"),status.Int()); + error = KErrGeneral; + } +#endif /*#ifdef __SERIES60_31__*/ + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetMute exit with error: %d"),this, error); + return error; + } +// --------------------------------------------------------- +// CCallAudioControlImpl::GetVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::GetVolume() + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::GetVolume enter"),this); + CAC_TRACE2(_L("GetVolume: current audio output = %d"),iCurrentAudioOutput); + TInt error(KErrNone); + switch (iCurrentAudioOutput) + { + case CTelephonyAudioRouting::ENotActive: + case CTelephonyAudioRouting::ENone: + case CTelephonyAudioRouting::EBTAudioAccessory: + case CTelephonyAudioRouting::ETTY: + CAC_TRACE1(_L("GetVolume: Audio Routing = Not Active, None, BT or TTY. iVolume set to -19")); + iVolume = KErrUnknown; + iEpVolumeNotifier->NotifyCancel(); + iIhfVolumeNotifier->NotifyCancel(); + break; + case CTelephonyAudioRouting::EHandset: + case CTelephonyAudioRouting::EWiredAudioAccessory: + // iVolume = EP Volume, cancel IHF subscription, subscribe to EP + CAC_TRACE1(_L("GetVolume: Audio Routing = Handset or Wired accessory: Get EPVolume")); + error = iEpVolumeNotifier->Get(iVolume); + if (error != KErrNone) + { + CAC_TRACE2(_L("GetVolume: Error returned from EP Volume Get: %d"),error); + } + iIhfVolumeNotifier->NotifyCancel(); + iEpVolumeNotifier->NotifyRequest(); + break; + case CTelephonyAudioRouting::ELoudspeaker: + // iVolume = IHF volume, cancel EP subscription, subscribe to IHF + CAC_TRACE1(_L("GetVolume: Audio Routing = Loudspeaker: Get IHF Volume")); + error = iIhfVolumeNotifier->Get( iVolume ); + if (error != KErrNone) + { + CAC_TRACE2(_L("GetVolume: Error returned from IHFVolume Get: %d"),error); + } + iEpVolumeNotifier->NotifyCancel(); + iIhfVolumeNotifier->NotifyRequest(); + break; + default: + break; + } // End Switch + + if (error != KErrNone) // Set iVolume to error code in case there was an error getting it + { + CAC_TRACE2(_L("GetVolume: ERROR, so iVolume = error = %d"), error); + iVolume = error; + } + CAC_TRACE4(_L("CCallAudioControlImpl[%x]::GetVolume exit with error: %d, and iVolume = %d"),this, error, iVolume); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::CheckIfOkToSetVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::CheckIfOkToSetVolume() +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::CheckIfOkToSetVolume enter"),this); + // if WINS, it's ok to set volume: + if (iWinsTesting) + return KErrNone; + TBool active = IsCallActive(); + if (!active) + { + CAC_TRACE2(_L("CheckIfOkToSetVolume NOT OK, Not active call. iCallState: %d"), iCallState); + return KErrPermissionDenied; + } + // IF device is BT/TTY/ENone/EActive return KErrNotSupported: + if ((iCurrentAudioOutput == CTelephonyAudioRouting::ENotActive) || + (iCurrentAudioOutput == CTelephonyAudioRouting::ENone) || + (iCurrentAudioOutput == CTelephonyAudioRouting::EBTAudioAccessory) || + (iCurrentAudioOutput == CTelephonyAudioRouting::ETTY) ) + { + CAC_TRACE2(_L("CheckIfOkToSetVolume NOT OK, Audio Output: %d"), iCurrentAudioOutput); + return KErrNotSupported; + } + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::CheckIfOkToSetVolume exit"),this); + return KErrNone; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::VerifyAndSetVolume +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::VerifyAndSetVolume(TInt aVolume) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::VerifyAndSetVolume for: %d "),this, aVolume); + TInt newVolume; + if (aVolume > KMaxVolume) + newVolume = KMaxVolume; + else if (aVolume < KMinVolume) + newVolume = KMinVolume; + else + newVolume = aVolume; + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::VerifyAndSetVolume: newVolume = %d "),this, newVolume); + return newVolume; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::HandleCallStateChange +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::HandleCallStateChange() +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::HandleCallStateChange enter"), this); + TInt error(KErrNone); + TBool active = IsCallActive(); + if (active ) // Active call or WINS + { + if (!iTelephonyAudioRouting) + { + TRAP(error,iTelephonyAudioRouting = CTelephonyAudioRouting::NewL(*this)); + if (error != KErrNone) + return error; + } + iCurrentAudioOutput = (CCallAudioControl::TAudioOutput)iTelephonyAudioRouting->Output(); + error = GetVolume(); + if (error != KErrNone) + { + CAC_TRACE2(_L("HandleCallStateChange: Error trying to get Volume: %d "), error); + return error; + } + } // end if + else // Not active, delete TAR if it exists, and set iVolume = EPVolume + { + if (iTelephonyAudioRouting) + { + delete iTelephonyAudioRouting; + iTelephonyAudioRouting = NULL; + } + error = iEpVolumeNotifier->Get(iVolume); + if (error != KErrNone) + { + CAC_TRACE2(_L("HandleCallStateChange: Error trying to get EPVolume: %d "), error); + iVolume = error; // set iVolume with error code instead of dBase garbage + } + } // end else + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::HandleCallStateChange exit with error: %d"), this, error); + return error; +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::HandleEPVolumeChange +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::HandleEPVolumeChange(TInt aVolume) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::HandleEPVolumeChange for: %d"),this, aVolume); + TInt error(KErrPermissionDenied); + // Ignore volume update unless active call and routing is earpiece or wired accessory: + TBool active = IsCallActive(); + if (active) + { + error = KErrNone; + if ((iCurrentAudioOutput == CTelephonyAudioRouting::EHandset) || (iCurrentAudioOutput == CTelephonyAudioRouting::EWiredAudioAccessory) ) + { + if (iPendingEpVolLevelOp && (iRequestedEpVolLevel == aVolume)) + { + return error; + } + else + { + iPendingEpVolLevelOp = EFalse; + iVolume = aVolume; + //Notify clients: + NotifyVolumeObservers(); + } + } + } + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::HandleIHFVolumeChange +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::HandleIHFVolumeChange(TInt aVolume) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::HandleIHFVolumeChange for: %d "),this, aVolume); + TInt error(KErrPermissionDenied); + // Ignore volume update unless active call and routing is Loudspeaker: + TBool active = IsCallActive(); + if (active) + { + error = KErrNone; + if (iCurrentAudioOutput == CTelephonyAudioRouting::ELoudspeaker) + { + if (iPendingIhfVolLevelOp && (iRequestedIhfVolLevel == aVolume)) + { + return error; + } + else + { + iPendingIhfVolLevelOp = EFalse; + iVolume = aVolume; + //Notify clients: + NotifyVolumeObservers(); + } + } + } + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::HandleMuteChange +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCallAudioControlImpl::HandleMuteChange(TBool aMute) + { + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::HandleMuteChange for: %d "),this, aMute); + TInt error(KErrPermissionDenied); + TBool active = IsCallActive(); + // Ignore mute update unless active call and mute state has changed + if (active) + { + error = KErrNone; + if (iPendingMuteSetOp && + ( iRequestedMuteState == aMute)) + { + return error; + } + else + { + iPendingMuteSetOp = EFalse; + //Notify clients: + NotifyGainObservers(); + } + } + return error; + } + +// --------------------------------------------------------- +// CCallAudioControlImpl::NotifyVolumeObservers +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCallAudioControlImpl::NotifyVolumeObservers() +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::NotifyVolumeObservers "),this); + for( TInt i = 0; i < iDownlinkVolumeObservers.Count(); i++ ) + { + CAC_TRACE2(_L("NotifyVolumeObservers[%d] "), i); + iDownlinkVolumeObservers[i]->DownlinkVolumeEvent(*(CCallAudioControl*)this, CDownlinkVolumeObserver::KDownlinkVolumeChanged); + } +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::NotifyGainObservers +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCallAudioControlImpl::NotifyGainObservers() +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::NotifyGainObservers "),this); + for( TInt i = 0; i < iUplinkGainObservers.Count(); i++ ) + { + CAC_TRACE2(_L("NotifyGainObservers[%d] "), i); + iUplinkGainObservers[i]->UplinkGainEvent(*(CCallAudioControl*)this, CUplinkGainObserver::KUplinkMuteStateChanged); + } +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::NotifyRoutingObservers +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCallAudioControlImpl::NotifyRoutingObservers(TUint aEvent, TInt aError) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::NotifyRoutingObservers "),this); + for( TInt i = 0; i < iRoutingObservers.Count(); i++ ) + { + CAC_TRACE2(_L("NotifyRoutingObservers[%d] "), i); + iRoutingObservers[i]->RoutingEvent(*(CCallAudioControl*)this, aEvent, aError); + } +} + +// --------------------------------------------------------- +// CCallAudioControlImpl::NotifyRoutingObservers +// ?implementation_description +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCallAudioControlImpl::NotifyRoutingObservers(TUint aEvent) +{ + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::NotifyRoutingObservers "),this); + for( TInt i = 0; i < iRoutingObservers.Count(); i++ ) + { + CAC_TRACE2(_L("NotifyRoutingObservers[%d] "), i); + iRoutingObservers[i]->RoutingEvent(*(CCallAudioControl*)this, aEvent); + } +} + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::AvailableOutputsChanged +// The following methods are required for MTelephonyAudioRoutingObserver +// ----------------------------------------------------------------------------- +// +void CCallAudioControlImpl::AvailableOutputsChanged( CTelephonyAudioRouting& /*aTelephonyAudioRouting*/) +{ + CAC_TRACE1(_L("CCallAudioControlImpl::AvailableOutputsChanged")); + // ignore callback unless this condition is true + TBool active = IsCallActive(); + if (active) + { + // Perform AvailableOutputsChanged callback to all existing CRoutingObservers: + NotifyRoutingObservers(CRoutingObserver::KAvailableOutputsChanged); + } +} + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::OutputChanged +// ----------------------------------------------------------------------------- +// + void CCallAudioControlImpl::OutputChanged( CTelephonyAudioRouting& aTelephonyAudioRouting) + { + CAC_TRACE1(_L("CCallAudioControlImpl[%x]::OutputChanged Enter")); + // Get and save previous and current audio output values: + iCurrentAudioOutput = (CCallAudioControl::TAudioOutput)aTelephonyAudioRouting.Output(); + iPreviousAudioOutput = (CCallAudioControl::TAudioOutput)aTelephonyAudioRouting.PreviousOutput(); + // ignore callback unless this condition is true + TBool active = IsCallActive(); + if (active) + { + TInt tempVol = iVolume; // save off iVolume + // get volume from keys, based on new audio output, and set iVolume: + GetVolume(); + // Perform OutputChanged callback to all existing CRoutingObservers: + NotifyRoutingObservers(CRoutingObserver::KOutputChanged); + // If there's a volume change, notify all existing CDownlinkVolumeObservers: + if (tempVol != iVolume) + { + NotifyVolumeObservers(); + } + } + CAC_TRACE1(_L("CCallAudioControlImpl::OutputChanged Exit")); + } + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::SetOutputComplete +// ----------------------------------------------------------------------------- +// + void CCallAudioControlImpl::SetOutputComplete( CTelephonyAudioRouting& aTelephonyAudioRouting, TInt aErr) + { + + CAC_TRACE3(_L("CCallAudioControlImpl[%x]::SetOutputComplete With Error Code: %d"), this, aErr); + iCurrentAudioOutput = (CCallAudioControl::TAudioOutput)aTelephonyAudioRouting.Output(); + iPreviousAudioOutput = (CCallAudioControl::TAudioOutput)aTelephonyAudioRouting.PreviousOutput(); + // ignore callback unless this condition is true + TBool active = IsCallActive(); + if (active) + { + TInt tempVol = iVolume; // save off iVolume + // get volume from keys, based on new audio output, and set iVolume: + GetVolume(); + // Perform OutputChanged callback to all existing CRoutingObservers: + NotifyRoutingObservers(CRoutingObserver::KSetOutputComplete, aErr); + // If there's a volume change, notify all existing CDownlinkVolumeObservers: + if (tempVol != iVolume) + { + NotifyVolumeObservers(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::NotifyL +// ----------------------------------------------------------------------------- +// +void CCallAudioControlImpl::NotifyL(TAction aAction, TInt aError, TInt aValue) + { + CAC_TRACE5(_L("CCallAudioControlImpl[%x]::NotifyL for Action: %d, Error: %d and Value: %d"),this, aAction, aError, aValue); + switch (aAction) + { + case ECallState: // Call state change notification + { + CAC_TRACE1(_L("NotifyL: Call State Change Notification")); + iCallState = aValue; + HandleCallStateChange(); + } + break; + case EEPVolume: // EP Volume change notification + { + CAC_TRACE1(_L("NotifyL: EP VOlume Change Notification")); + TInt tempVol = aValue; + HandleEPVolumeChange(tempVol); + } + break; + case EIHFVolume: // Handle IHF volume change Notification + { + CAC_TRACE1(_L("NotifyL: IHF Volume Change Notification")); + TInt tempVol = aValue; + HandleIHFVolumeChange(tempVol); + } + break; + + case EMute: // Handle mute change Notification + { + CAC_TRACE1(_L("NotifyL: Uplink Mute Change Notification")); + TBool tempMute = aValue; +#ifdef __SERIES60_31__ + if (aValue == EPSMicMuteOn) + tempMute = ETrue; + else + tempMute = EFalse; +#endif + HandleMuteChange(tempMute); + } + break; + default: + CAC_TRACE1(_L("NotifyL: UNKNOWN Notification")); + break; + } // End switch + } + +// ----------------------------------------------------------------------------- +// CCallAudioControlImpl::CommandResponseL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +#ifdef __SERIES60_31__ +void CCallAudioControlImpl::CommandResponseL( TUid /*aKMediatorSecondaryDisplayDomain*/, + TUid /*aKTSECategory*/, + TInt aCommandId, + TInt aStatus, + const TDesC8& /*aData*/ ) + { + CAC_TRACE2(_L("CCallAudioControlImpl[%x]::CommandResponseL "),this); + if ( aStatus != KErrNone) + { + CAC_TRACE2(_L("CommandResponseL: Command error [%d] "), aStatus); + } + else + { + switch ( aCommandId ) + { + case ECmdMuteOrUnmuteMicrophone: + CAC_TRACE1(_L("CommandResponseL: Mute Unmute microphone succeeded ")); + break; + default: + CAC_TRACE1(_L("CommandResponseL: ERROR: Unknown Command Response Received")); + break; + } + } // End else + } +#endif + +// ----------------------------------------------------------------------------- +// +// +// +// ----------------------------------------------------------------------------- +// +TBool CCallAudioControlImpl::IsCallActive() +{ + CAC_TRACE1(_L("CCallAudioControlImpl::IsCallActive")); + iCsNotifier->Get(iCallState); + if ((iCallState == ECallStateConnected) || (iCallState == ECallStateHold) || iWinsTesting ) + { + return ETrue; + } + return EFalse; +} +// End of file