os/mm/devsound/sounddevbt/PlatSec/src/Server/AudioServer/MmfBtDevSoundSessionBody.inl
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/devsound/sounddevbt/PlatSec/src/Server/AudioServer/MmfBtDevSoundSessionBody.inl Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,551 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <mmfbtswcodecwrapper.h> //for SwCodecWrapper CustomInterfaces
1.20 +#include <mmfbtswcodecwrappercustominterfacesuids.hrh>
1.21 +#include <mmf/plugin/mmfbthwdeviceimplementationuids.hrh>
1.22 +// Test only
1.23 +#include <bttypes.h>
1.24 +#include <centralrepository.h> // for BT device address retrieval
1.25 +#include "MmfBtRoutingPrioritySettings.h" //for ESpeaker, EA2DPBluetoothHeadset etc
1.26 +
1.27 +/*
1.28 + * [TODO] this function is now too long to be inline
1.29 + * Initializes DevSound object for the mode aMode for processing audio data
1.30 + * with hardware device aHWDev.
1.31 + *
1.32 + * On completion of Initialization, the observer will be notified via call back
1.33 + * InitializeComplete().
1.34 + *
1.35 + * Leaves on failure.
1.36 + *
1.37 + * @param "MDevSoundObserver& aDevSoundObserver"
1.38 + * A reference to DevSound Observer instance.
1.39 + *
1.40 + * @param "TUid aHWDev"
1.41 + * CMMFHwDevice implementation identifier.
1.42 + *
1.43 + * @param "TMMFState aMode"
1.44 + * Mode for which this object will be used.
1.45 + *
1.46 + */
1.47 +inline void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TUid aHWDev, TMMFState aMode)
1.48 + {
1.49 + TInt initError = KErrNone;
1.50 + iDevSoundObserver = &aDevSoundObserver;
1.51 +
1.52 + if (aMode == EMMFStateIdle)
1.53 + {
1.54 + User::Leave(KErrNotSupported);
1.55 + }
1.56 + iMode = aMode;
1.57 +
1.58 + // Given the mode, update the iDevInfo with the audio's route
1.59 + if ((iMode == EMMFStateRecording)||(iMode == EMMFStatePlayingRecording))
1.60 + {//DEF037912 incase the recording capabilities differ from play
1.61 + User::LeaveIfError(InitializeFormat(iRecordFormatsSupported, iRecordFormat));
1.62 + iDevInfo.iInStream.iConnection.iType = EConnectionGpp;
1.63 + iDevInfo.iInStream.iConnection.iId = KDeviceUidMic.iUid;
1.64 + }
1.65 + if ((iMode == EMMFStatePlaying)||(iMode == EMMFStateTonePlaying)||(iMode == EMMFStatePlayingRecording))
1.66 + {
1.67 + iDevInfo.iOutStream.iConnection.iType = EConnectionGpp;
1.68 + // If the bit on the priority settings is set indicating
1.69 + // we are routing to the by headset then the HwDevice device id
1.70 + // needs setting for the bluetooth headset
1.71 + if (iAudioPolicyPrioritySettings.iPref & EA2DPBluetoothHeadset)
1.72 + {
1.73 + iDevInfo.iOutStream.iConnection.iId = KDeviceUidA2dpHeadset.iUid;
1.74 + CRepository* centralRepository = NULL;
1.75 + centralRepository = CRepository::NewL(KUidBTHeadsetRepository);
1.76 + CleanupStack::PushL(centralRepository);
1.77 + TInt64 btHeadsetAddress = 0;
1.78 + TBuf<16> btHeadsetAddressString;
1.79 + User::LeaveIfError(centralRepository->Get(0x01, btHeadsetAddressString));
1.80 + TLex stringConverter(btHeadsetAddressString.Ptr());
1.81 + User::LeaveIfError(stringConverter.Val(btHeadsetAddress,EHex));
1.82 + TBTDevAddr bTDevAddr(btHeadsetAddress);
1.83 + iDevInfo.iOutStream.iDeviceName = bTDevAddr.Des();
1.84 + CleanupStack::Pop(centralRepository);
1.85 + delete centralRepository;
1.86 + }
1.87 + else
1.88 + {
1.89 + iDevInfo.iOutStream.iConnection.iId = KDeviceUidSpeaker.iUid;
1.90 + }
1.91 + }
1.92 +
1.93 + iDevSoundObserver = &aDevSoundObserver;
1.94 + iHwDeviceID.iUid = aHWDev.iUid;
1.95 + if(iCMMFHwDevice)
1.96 + {
1.97 + delete iCMMFHwDevice;
1.98 + iHwDeviceBuffer = NULL; // buffer is deleted by HwDevice delete
1.99 + iPlayCustomInterface = NULL; //custom interfaces are also invalid
1.100 + iRecordCustomInterface = NULL;
1.101 + }
1.102 +
1.103 + iCMMFHwDevice = NULL;
1.104 +
1.105 + // Load the HwDevice implementation from ECom
1.106 + TRAP(initError, iCMMFHwDevice = CMMFHwDevice2::NewL(aHWDev));
1.107 +
1.108 + if (initError == KErrNone)
1.109 + {
1.110 + iDevInfo.iHwDeviceObserver = this;
1.111 +
1.112 + iCMMFHwDevice->Init(iDevInfo, iRSDHandler->iStatus);
1.113 + iRSDHandler->Start();
1.114 +
1.115 + TUid playCustomInterfaceUid;
1.116 + playCustomInterfaceUid.iUid = KMmfPlaySettingsCustomInterface;
1.117 + TUid recordCustomInterfaceUid;
1.118 + recordCustomInterfaceUid.iUid = KMmfRecordSettingsCustomInterface;
1.119 + iPlayCustomInterface =
1.120 + (MPlayCustomInterface*)iCMMFHwDevice->CustomInterface(playCustomInterfaceUid);
1.121 + if (!iPlayCustomInterface)
1.122 + {//DEF40443 need to check custom interface has been created
1.123 + initError = KErrNoMemory;//it won't if there is no memory
1.124 + }
1.125 + else
1.126 + {
1.127 + iRecordCustomInterface =
1.128 + (MRecordCustomInterface*)iCMMFHwDevice->CustomInterface(recordCustomInterfaceUid);
1.129 + if (!iRecordCustomInterface)
1.130 + {
1.131 + initError = KErrNoMemory;
1.132 + }
1.133 + }
1.134 + }
1.135 +
1.136 + if (initError)
1.137 + {
1.138 + iDevSoundObserver->InitializeComplete(initError);
1.139 + User::Leave(initError);
1.140 + }
1.141 + }
1.142 +
1.143 +/*
1.144 + *
1.145 + * Initializes DevSound object for the mode aMode for processing audio data
1.146 + * using an array of Hardware devices identified by aHWDevArray identifier
1.147 + * array. The hardware devices are chained together with data flow starting
1.148 + * with first array element.
1.149 + *
1.150 + * On completion of Initialization, the observer will be notified via call back
1.151 + * InitializeComplete().
1.152 + *
1.153 + * Leaves on failure.
1.154 + *
1.155 + * @param "MDevSoundObserver& aDevSoundObserver"
1.156 + * A reference to DevSound Observer instance.
1.157 + *
1.158 + * @param "CArrayPtr<TUid> aHWDevArray"
1.159 + * Array of CMMFHwDevice implementation identifiers.
1.160 + *
1.161 + * @param "TMMFState aMode"
1.162 + * Mode for which this object will be used.
1.163 + *
1.164 + */
1.165 +inline void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& /*aDevSoundObserver*/, CArrayPtr<TUid> /*aHWDevArray*/, TMMFState /*aMode*/)
1.166 + {
1.167 + User::Leave(KErrNotSupported);
1.168 + }
1.169 +
1.170 +/*
1.171 + *
1.172 + * Initializes DevSound object for the mode aMode for processing audio data
1.173 + * with hardware device supporting FourCC aDesiredFourCC.
1.174 + *
1.175 + * On completion of Initialization, the observer will be notified via call back
1.176 + * InitializeComplete().
1.177 + *
1.178 + * Leaves on failure.
1.179 + *
1.180 + * @param "MDevSoundObserver& aDevSoundObserver"
1.181 + * A reference to DevSound Observer instance.
1.182 + *
1.183 + * @param "TFourCC aDesiredFourCC"
1.184 + * CMMFHwDevice implementation FourCC.
1.185 + *
1.186 + * @param "TMMFState aMode"
1.187 + * Mode for which this object will be used.
1.188 + *
1.189 + */
1.190 +inline void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TFourCC aDesiredFourCC, TMMFState aMode)
1.191 + {
1.192 + // to get HW Uid from the FourCC
1.193 + RImplInfoPtrArray plugInArray;
1.194 + TFourCC KPCM16FourCC(' ','P','1','6');
1.195 + _LIT(KNullString, "");
1.196 +
1.197 + TUid hwDevicePluginInterface = {KMmfUidBtPluginInterfaceHwDevice};
1.198 + TUid implUid = {0};
1.199 +
1.200 + CleanupResetAndDestroyPushL( plugInArray );
1.201 + // Get the implementation UID based on the FourCC and mode.
1.202 + if (aMode == EMMFStatePlaying)
1.203 + {//destination four CC is pcm16
1.204 + iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, aDesiredFourCC, KPCM16FourCC, KNullString);
1.205 + }
1.206 + else if (aMode == EMMFStateRecording)
1.207 + {//source fourCC is pcm16
1.208 + iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, KPCM16FourCC, aDesiredFourCC, KNullString);
1.209 + }
1.210 + else User::Leave(KErrNotSupported);//invalid aMode cant set 4CC for tone
1.211 +
1.212 + if(plugInArray.Count() == 0)
1.213 + { // couldn't find Decoder only implementation, try to get Decoder/Encoder
1.214 + iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, aDesiredFourCC, aDesiredFourCC, KNullString);
1.215 + if(plugInArray.Count() == 0)
1.216 + User::Leave(KErrNotSupported);
1.217 + }
1.218 + implUid = plugInArray[0]->ImplementationUid(); // Just pick the first in the list
1.219 +
1.220 + // If we made it here, there we have found implementation UID
1.221 + InitializeL(aDevSoundObserver, implUid, aMode);
1.222 + CleanupStack::PopAndDestroy() ; //pluginArray
1.223 + }
1.224 +
1.225 +/*
1.226 + *
1.227 + * Returns the supported Audio settings.
1.228 + *
1.229 + * @return "TMMFCapabilities"
1.230 + * Device settings.
1.231 + *
1.232 + */
1.233 +inline TMMFCapabilities CMMFDevSoundSvrImp::Capabilities()
1.234 + {
1.235 + if ((iAudioPolicyPrioritySettings.iPref & EA2DPBluetoothHeadset) && (iPlayCustomInterface))
1.236 + {
1.237 + //then we need to get the caps from the HwDevice
1.238 + //actually we should get the Caps from the HwDevice in any case
1.239 + //but am being cautious so as not to cause test regressions
1.240 + TTaskConfig hwDeviceCaps = iPlayCustomInterface->Caps();
1.241 + iDeviceCapabilities.iRate = hwDeviceCaps.iRate; //the two structures use the same enums so this is ok
1.242 + if (hwDeviceCaps.iStereoMode & ETaskMono)
1.243 + {
1.244 + iDeviceCapabilities.iChannels = EMMFMono;
1.245 + }
1.246 + if (hwDeviceCaps.iStereoMode & ETaskInterleaved)
1.247 + {
1.248 + iDeviceCapabilities.iChannels |= EMMFStereo;
1.249 + }
1.250 + }
1.251 + return iDeviceCapabilities;
1.252 + }
1.253 +
1.254 +/*
1.255 + *
1.256 + * Returns the current audio settings.
1.257 + *
1.258 + * @return "TMMFCapabilities"
1.259 + * Device settings.
1.260 + *
1.261 + */
1.262 +inline TMMFCapabilities CMMFDevSoundSvrImp::Config() const
1.263 + {
1.264 + return iDeviceConfig;
1.265 + }
1.266 +
1.267 +/*
1.268 + *
1.269 + * Returns an integer representing the maximum volume.
1.270 + *
1.271 + * This is the maximum value which can be passed to CMMFDevSoundProxy::SetVolume.
1.272 + *
1.273 + * @return "TInt"
1.274 + * The maximum volume. This value is platform dependent but is always
1.275 + * greater than or equal to one.
1.276 + *
1.277 + */
1.278 +inline TInt CMMFDevSoundSvrImp::MaxVolume()
1.279 + {
1.280 + return iPlayFormatsSupported().iMaxVolume;
1.281 + }
1.282 +
1.283 +/*
1.284 + *
1.285 + * Returns an integer representing the current volume.
1.286 + *
1.287 + * @return "TInt"
1.288 + * The current volume level.
1.289 + *
1.290 + */
1.291 +inline TInt CMMFDevSoundSvrImp::Volume()
1.292 + {
1.293 + return iVolume;
1.294 + }
1.295 +
1.296 +/*
1.297 + *
1.298 + * Returns an integer representing the maximum gain.
1.299 + *
1.300 + * This is the maximum value which can be passed to CMMFDevSoundProxy::SetGain.
1.301 + *
1.302 + * @return "TInt"
1.303 + * The maximum gain. This value is platform dependent but is always
1.304 + * greater than or equal to one.
1.305 + *
1.306 + */
1.307 +inline TInt CMMFDevSoundSvrImp::MaxGain()
1.308 + {
1.309 + return iRecordFormatsSupported().iMaxVolume;//uses iMaxVolume for iMaxGain
1.310 + }
1.311 +
1.312 +/*
1.313 + *
1.314 + * Returns an integer representing the current gain.
1.315 + *
1.316 + * @return "TInt"
1.317 + * The current gain level.
1.318 + *
1.319 + */
1.320 +inline TInt CMMFDevSoundSvrImp::Gain()
1.321 + {
1.322 + return iGain;
1.323 + }
1.324 +
1.325 +/*
1.326 + *
1.327 + * Returns the speaker balance set for playing.
1.328 + *
1.329 + * Leaves on failure.
1.330 + *
1.331 + * @param "TInt& aLeftPrecentage"
1.332 + * On return contains the left speaker volume percentage.
1.333 + *
1.334 + * @param "TInt& aRightPercentage"
1.335 + * On return contains the right speaker volume percentage.
1.336 + *
1.337 + */
1.338 +inline void CMMFDevSoundSvrImp::GetPlayBalanceL(TInt& aLeftPercentage, TInt& aRightPercentage)
1.339 + {
1.340 + aLeftPercentage = iLeftPlayBalance;
1.341 + aRightPercentage = iRightPlayBalance;
1.342 + }
1.343 +
1.344 +/*
1.345 + *
1.346 + * Returns the microphone gain balance set for recording.
1.347 + *
1.348 + * Leaves on failure.
1.349 + *
1.350 + * @param "TInt& aLeftPercentage"
1.351 + * On return contains the left microphone gain percentage.
1.352 + *
1.353 + * @param "TInt& aRightPercentage"
1.354 + * On return contains the right microphone gain percentage.
1.355 + *
1.356 + */
1.357 +inline void CMMFDevSoundSvrImp::GetRecordBalanceL(TInt& aLeftPercentage, TInt& aRightPercentage)
1.358 + {
1.359 + aLeftPercentage = iLeftRecordBalance;
1.360 + aRightPercentage = iRightRecordBalance;
1.361 + }
1.362 +
1.363 +/*
1.364 + *
1.365 + * Contine the process of recording. Once the buffer is filled with recorded
1.366 + * data, the Observer gets reference to buffer along with callback
1.367 + * BufferToBeEmptied(). After processing the buffer (copying over to a
1.368 + * different buffer or writing to file) the client should call this
1.369 + * method to continue recording process.
1.370 + *
1.371 + */
1.372 +inline void CMMFDevSoundSvrImp::RecordData(const RMmfIpcMessage& aMessage)
1.373 + {
1.374 + ASSERT(iDevSoundObserver);
1.375 +
1.376 + // Checkes if the client has a UserEnvironment capability
1.377 + if (!aMessage.HasCapability(ECapabilityUserEnvironment))
1.378 + {
1.379 + iDevSoundObserver->RecordError(KErrPermissionDenied);
1.380 + return;
1.381 + }
1.382 +
1.383 + if(iCMMFHwDevice)
1.384 + {
1.385 + if(iMode== EMMFStateRecording)
1.386 + {
1.387 + iHwDeviceBuffer->Data().SetLength(iHwDeviceBuffer->RequestSize());
1.388 + iCMMFHwDevice->ThisHwBufferEmptied(*iHwDeviceBuffer);
1.389 + }
1.390 + }
1.391 + }
1.392 +
1.393 +/*
1.394 + *
1.395 + * Defines the number of times the audio is to be repeated during the tone
1.396 + * playback operation.
1.397 + *
1.398 + * A period of silence can follow each playing of tone. The tone playing can
1.399 + * be repeated indefinitely.
1.400 + *
1.401 + * @param "TInt aRepeatCount"
1.402 + * The number of times the tone, together with the trailing silence,
1.403 + * is to be repeated. If this is set to KMdaRepeatForever, then the
1.404 + * tone, together with the trailing silence, is repeated indefinitely
1.405 + * or until Stop() is called. If this is set to zero, then the tone is
1.406 + * not repeated.
1.407 + *
1.408 + * Supported only during tone playing.
1.409 + *
1.410 + */
1.411 +inline void CMMFDevSoundSvrImp::SetToneRepeats(TInt aRepeatCount,
1.412 + const TTimeIntervalMicroSeconds& aRepeatTrailingSilence)
1.413 + {
1.414 + iRepeatCount = aRepeatCount;
1.415 + iRepeatTrailingSilence = aRepeatTrailingSilence;
1.416 + }
1.417 +
1.418 +/*
1.419 + *
1.420 + * Defines the priority settings that should be used for this instance.
1.421 + *
1.422 + * @param "const TMMFPrioritySettings& aPrioritySettings"
1.423 + * An class type representing the client's priority, priority
1.424 + * preference and state.
1.425 + *
1.426 + */
1.427 +inline void CMMFDevSoundSvrImp::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
1.428 + {
1.429 + iAudioPolicyPrioritySettings.iPref = aPrioritySettings.iPref;
1.430 + iAudioPolicyPrioritySettings.iPriority = aPrioritySettings.iPriority;
1.431 + }
1.432 +
1.433 +/*
1.434 + *
1.435 + * Initializes and starts conversion process. Once the process is initiated,
1.436 + * observer's call back method BufferToBeFilled() is called with reference to
1.437 + * the buffer into which source format data is to be read.
1.438 + *
1.439 + * The maximum size of data (in bytes) that can be converted is specified in
1.440 + * CMMFBuffer::RequestSize(). Any data that is read into buffer beyond this
1.441 + * size will be ignored.
1.442 + *
1.443 + * Leaves on failure.
1.444 + * @prototype
1.445 + */
1.446 +inline void CMMFDevSoundSvrImp::ConvertInitL()
1.447 + {
1.448 + User::Leave(KErrNotSupported);
1.449 + }
1.450 +
1.451 +/*
1.452 + *
1.453 + * Converts the data in the buffer from source format to destination format.
1.454 + * After the data is converted to destination format, a reference to the buffer
1.455 + * containing data in destination format is passed in the observer call back
1.456 + * method BufferToBeEmptied().
1.457 + *
1.458 + * The amount of data contained in buffer is specified in
1.459 + * CMMFBuffer::RequestSize().
1.460 + * @prototype
1.461 + */
1.462 +inline void CMMFDevSoundSvrImp::ConvertData()
1.463 + {
1.464 + // No implementation
1.465 + }
1.466 +
1.467 +// No custom interfaces are supported so return NULL.
1.468 +inline TAny* CMMFDevSoundSvrImp::CustomInterface(TUid /*aInterfaceId*/)
1.469 + {
1.470 + return NULL;
1.471 + }
1.472 +
1.473 +/*
1.474 + *
1.475 + * Returns the number of available pre-defined tone sequences.
1.476 + *
1.477 + * This is the number of fixed sequence supported by DevSound by default.
1.478 + *
1.479 + * @return "TInt"
1.480 + * The fixed sequence count. This value is implementation dependent
1.481 + * but is always greater than or equal to zero.
1.482 + *
1.483 + */
1.484 +inline TInt CMMFDevSoundSvrImp::FixedSequenceCount()
1.485 + {
1.486 + return iFixedSequences->Count();
1.487 + }
1.488 +
1.489 +/*
1.490 + *
1.491 + * Returns the name assigned to a specific pre-defined tone sequence.
1.492 + *
1.493 + * This is the number of fixed sequence supported by DevSound by default.
1.494 + *
1.495 + * The function raises a panic if sequence number specified invalid.
1.496 + *
1.497 + * @return "TDesC&"
1.498 + * A reference to a Descriptor containing the fixed sequence
1.499 + * name indexed by aSequenceNumber.
1.500 + *
1.501 + * @param "TInt aSequenceNumber"
1.502 + * The index identifying the specific pre-defined tone sequence. Index
1.503 + * values are relative to zero.
1.504 + * This can be any value from zero to the value returned by a call to
1.505 + * CMdaAudioPlayerUtility::FixedSequenceCount() - 1.
1.506 + * The function raises a panic if sequence number is not within this
1.507 + * range.
1.508 + *
1.509 + */
1.510 +inline const TDesC& CMMFDevSoundSvrImp::FixedSequenceName(TInt aSequenceNumber)
1.511 + {
1.512 + ASSERT((aSequenceNumber >= 0)&&(aSequenceNumber < iFixedSequences->Count()));
1.513 + return iDevSoundUtil->FixedSequenceName(aSequenceNumber);
1.514 + }
1.515 +
1.516 +/*
1.517 + *
1.518 + * Sets Id for this instance of DevSound
1.519 + *
1.520 + * @param "TInt aDevSoundId"
1.521 + * Integer value assigned by Audio Policy Server
1.522 + *
1.523 + */
1.524 +inline void CMMFDevSoundSvrImp::SetDevSoundId(TInt aDevSoundId)
1.525 + {
1.526 + iDevSoundInfo.iDevSoundId = aDevSoundId;
1.527 + }
1.528 +
1.529 +/*
1.530 + *
1.531 + * Returns information about this DevSound instance.
1.532 + *
1.533 + * This method is used by Audio Policy Server to make audio policy decisions.
1.534 + *
1.535 + * @return "TMMFDevSoundinfo"
1.536 + * A reference to TMMFDevSoundinfo object holding the current settings
1.537 + * of this DevSound instance.
1.538 + *
1.539 + */
1.540 +inline TMMFDevSoundInfo CMMFDevSoundSvrImp::DevSoundInfo()
1.541 + {
1.542 + return iDevSoundInfo;
1.543 + }
1.544 +
1.545 +
1.546 +/*
1.547 + * Updates the total bytes played.
1.548 + *
1.549 + */
1.550 +inline void CMMFDevSoundSvrImp::UpdateBytesPlayed()
1.551 + {
1.552 + if (iPlayCustomInterface)
1.553 + iPlayedBytesCount = iPlayCustomInterface->BytesPlayed();
1.554 + }