diff -r 000000000000 -r d6fe6244b863 htiui/HtiServicePlugins/HtiAudioServicePlugin/src/HtiAudioServicePlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htiui/HtiServicePlugins/HtiAudioServicePlugin/src/HtiAudioServicePlugin.cpp Tue Feb 02 00:17:27 2010 +0200 @@ -0,0 +1,1672 @@ +/* +* Copyright (c) 2009 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: Implements the ECom plugin for HTI audio playback control +* service. +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include + +#include "HtiAudioServicePlugin.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const static TInt KPlayToneCmdLength = 13; +const static TInt KStopCmdLength = 1; +const static TInt KSetVolCmdLength = 2; +const static TInt KListCmdMinLength = 4; +const static TInt KPlayDtmfCmdMinLength = 17; +const static TInt KPlayFileCmdMinLength = 21; +const static TInt KDurationCmdMinLength = 6; +const static TInt KMaxVolCmdMinLength = 6; + +const static TInt KTUintSize = sizeof( TUint ); + +// MACROS + +// LOCAL CONSTANTS AND MACROS +const static TUid KAudioServiceUid = { 0x10210CCB }; + +_LIT( KBackslash, "\\" ); +_LIT( KRngMimeType, "application/vnd.nokia.ringing-tone" ); +_LIT( KAudioMimeType, "audio/*" ); + +// NOTE: Max length for error description is defined +// in HtiDispatcherInterface.h (currently 118). +_LIT8( KErrorNoCmd, "ERROR: No command given" ); +_LIT8( KErrorUnknownCmd, "ERROR: Unknown Audio Service command" ); +_LIT8( KErrorInvalidParameters, + "ERROR: Invalid parameter data for this command" ); +_LIT8( KErrorInvalidPath, "ERROR: Invalid path" ); +_LIT8( KErrorToneInitFailed, "ERROR: Tone initialization failed" ); +_LIT8( KErrorTonePlayFailed, "ERROR: Tone playing failed" ); +_LIT8( KErrorFileInitFailed, "ERROR: File playing initialization failed" ); +_LIT8( KErrorFilePlayFailed, "ERROR: File playing failed" ); +_LIT8( KErrorBusyPlaying, "ERROR: Currently busy playing" ); +_LIT8( KErrorNothingPlaying, "ERROR: Nothing playing" ); +_LIT8( KErrorDurationFailed, "ERROR: Duration query failed" ); +_LIT8( KErrorMaxVolFailed, "ERROR: Max volume query failed" ); +_LIT8( KErrorPosition, "ERROR: Invalid start or end position value" ); + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::CHtiAudioServicePlugin +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CHtiAudioServicePlugin::CHtiAudioServicePlugin():iIsBusy( EFalse ), + iIsPlaying( EFalse ), + iCommandId( 0 ), + iPlayCommandId( 0 ), + iMessage( NULL ), + iErrorCode( 0 ), + iVolume( 0 ), + iRepeats( 0 ), + iTrailingSilence( 0 ), + iDtmfLength( 0 ), + iDtmfGapLength( 0 ), + iStartPos( 0 ), + iEndPos( 0 ) + { + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHtiAudioServicePlugin* CHtiAudioServicePlugin::NewL() + { + CHtiAudioServicePlugin* self = new (ELeave) CHtiAudioServicePlugin; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +// Destructor +CHtiAudioServicePlugin::~CHtiAudioServicePlugin() + { + delete iMessage; + iMessage = NULL; + delete iAudioPlayer; + iAudioPlayer = NULL; + delete iTonePlayer; + iTonePlayer = NULL; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::ProcessMessageL +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::ProcessMessageL( const TDesC8& aMessage, + THtiMessagePriority /*aPriority*/ ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::ProcessMessageL" ); + HTI_LOG_FORMAT( "Message length = %d", aMessage.Length() ); + + if ( iIsBusy ) + { + HTI_LOG_TEXT( "Plugin is busy - leaving" ); + User::Leave( KErrInUse ); + } + + // Will be set to EFalse in the SendResponseMsg or SendErrorResponseMsg + // methods when the response has been successfully sent and the plugin is + // ready for next message. + iIsBusy = ETrue; + + if ( aMessage.Length() < 1 ) + { + User::LeaveIfError( + SendErrorResponseMsg( KErrArgument, KErrorNoCmd ) ); + return; + } + + iCommandId = aMessage[0]; + HTI_LOG_FORMAT( "Command = %d", iCommandId ); + TInt err = KErrNone; + + if ( iCommandId == ECmdListAudioFiles ) + { + TRAP( err, HandleListAudioFilesCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdPlayFile ) + { + TRAP( err, HandlePlayFileCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdPlayTone ) + { + TRAP( err, HandlePlayToneCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdPlayDtmf ) + { + TRAP( err, HandlePlayDtmfCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdStop ) + { + TRAP( err, HandleStopCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdGetDuration ) + { + TRAP( err, HandleGetDurationCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdGetMaxVol ) + { + TRAP( err, HandleGetMaxVolCmdL( aMessage ) ); + } + + else if ( iCommandId == ECmdSetVol ) + { + TRAP( err, HandleSetVolCmdL( aMessage ) ); + } + + else + { + User::LeaveIfError( + SendErrorResponseMsg( KErrArgument, KErrorUnknownCmd ) ); + } + + if ( err != KErrNone ) + { + User::LeaveIfError( + SendErrorResponseMsg( err, KNullDesC8, iCommandId ) ); + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::ProcessMessageL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandleListAudioFilesCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandleListAudioFilesCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleListAudioFilesCmdL" ); + + RFs fsSession; + User::LeaveIfError( fsSession.Connect() ); + CleanupClosePushL( fsSession ); + + // Build a list of directories to scan + CDesCArraySeg* directories = new (ELeave) CDesCArraySeg( 5 ); + CleanupStack::PushL( directories ); + + if ( aMessage.Length() == 1 ) // Add default sound directories + { + TFileName directory; + + // ROM + directory.Append( PathInfo::RomRootPath() ); + directory.Append( PathInfo::SoundsPath() ); + if ( BaflUtils::PathExists( fsSession, directory ) ) + { + directories->AppendL( directory ); + AddSubdirsRecursivelyL( directories->MdcaPoint( + directories->Count() - 1 ), *directories, fsSession ); + } + + // Phone memory + directory.Zero(); + directory.Append( PathInfo::PhoneMemoryRootPath() ); + directory.Append( PathInfo::SoundsPath() ); + if ( BaflUtils::PathExists( fsSession, directory ) ) + { + directories->AppendL( directory ); + AddSubdirsRecursivelyL( directories->MdcaPoint( + directories->Count() - 1 ), *directories, fsSession ); + } + + // Memory card + directory.Zero(); + directory.Append( PathInfo::MemoryCardRootPath() ); + directory.Append( PathInfo::SoundsPath() ); + if ( BaflUtils::PathExists( fsSession, directory ) ) + { + directories->AppendL( directory ); + AddSubdirsRecursivelyL( directories->MdcaPoint( + directories->Count() - 1 ), *directories, fsSession ); + } + } + + else // Add given directory + { + if ( aMessage.Length() < KListCmdMinLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + CleanupStack::PopAndDestroy( 2 ); // directories, fsSession + return; + } + + TInt pathLength = aMessage[1]; + if ( ( aMessage.Length() - pathLength ) != KListCmdMinLength - 2 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + CleanupStack::PopAndDestroy( 2 ); // directories, fsSession + return; + } + + TFileName directory; + TInt nextOffset = ParseString( aMessage, 1, directory ); + TInt dirLength = directory.Length(); + if ( dirLength < 2 || nextOffset < 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + CleanupStack::PopAndDestroy( 2 ); // directories, fsSession + return; + } + + HTI_LOG_DES( directory ); + + if ( directory[dirLength - 1] != '\\' ) + { + HTI_LOG_TEXT( "Adding backslash to the end" ); + directory.Append( KBackslash ); + HTI_LOG_DES( directory ); + } + + if ( BaflUtils::PathExists( fsSession, directory ) ) + { + HTI_LOG_TEXT( "Given path exists" ); + directories->AppendL( directory ); + AddSubdirsRecursivelyL( directories->MdcaPoint( + directories->Count() - 1 ), *directories, fsSession ); + } + } + + // Buffer for the file list that is returned + CBufFlat* fileListBuf = CBufFlat::NewL( 256 ); + CleanupStack::PushL( fileListBuf ); + TInt bufPos = 0; + + TInt audioFileCount = 0; + TInt dirCount( directories->Count() ); + HTI_LOG_FORMAT( "Total directory count = %d", dirCount ); + + if ( dirCount == 0 ) + { + HTI_LOG_TEXT( "The given directory did not exist" ); + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidPath ) ); + CleanupStack::PopAndDestroy( 3 ); // fileListBuf, directories, fsSession + return; + } + + // Loop all the directories + for ( TInt i = 0; i < dirCount; i++ ) + { + HTI_LOG_TEXT( "Reading dir:" ); + HTI_LOG_DES( directories->MdcaPoint( i ) ); + CDir* dir; + TInt err = fsSession.GetDir( directories->MdcaPoint( i ), + KEntryAttNormal, ESortNone, dir ); + if ( err ) + { + delete dir; + dir = NULL; + continue; // This dir is skipped + } + CleanupStack::PushL( dir ); + + // Loop all the entries in this directory + TInt fileCount( dir->Count() ); + for ( TInt j = 0; j < fileCount; j++ ) + { + TFileName filePath; + filePath.Copy( directories->MdcaPoint( i ) ); + filePath.Append( ( *dir )[j].iName ); + + // Check MIME type match + if ( MatchMimeTypeL( filePath, KAudioMimeType ) || + MatchMimeTypeL( filePath, KRngMimeType ) ) + { + HBufC8* filePathBuf8 = HBufC8::NewLC( KMaxFileName ); + filePathBuf8->Des().Copy( filePath ); + TInt pathLength = filePathBuf8->Length(); + HTI_LOG_DES( *filePathBuf8 ); + fileListBuf->ExpandL( bufPos, pathLength + 1 ); + TBuf8<1> lengthBuf; + lengthBuf.Append( pathLength ); + fileListBuf->Write( bufPos, lengthBuf, 1 ); + bufPos++; + fileListBuf->Write( bufPos, filePathBuf8->Ptr(), pathLength ); + bufPos += pathLength; + CleanupStack::PopAndDestroy(); // filePathBuf8 + audioFileCount++; + } + + } // files loop + CleanupStack::PopAndDestroy(); // dir + } // directories loop + + HTI_LOG_FORMAT( "Total audio file count = %d", audioFileCount ); + + // All files added - write number of files to the beginning of buffer... + TBuf8<2> countBuf; + countBuf.Append( (TUint8*)(&audioFileCount), 2 ); + fileListBuf->InsertL( 0, countBuf, 2 ); + + // ...and send it away + TPtr8 ptr = fileListBuf->Ptr( 0 ); + User::LeaveIfError( SendResponseMsg( ptr ) ); + + CleanupStack::PopAndDestroy( 3 ); // fileListBuf, directories, fsSession + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleListAudioFilesCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandlePlayFileCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandlePlayFileCmdL( const TDesC8&aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayFileCmdL" ); + + if ( iIsPlaying ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrInUse, KErrorBusyPlaying ) ); + return; + } + + iPlayCommandId = ECmdPlayFile; + + /* + Message bytes: + 0 = command code + 1 = path length + 2 - n = full path to file + next 1 = volume + next 4 = start position + next 4 = end position + next 1 = repeats + next 4 = silence between repeats + next 1 = audio setting + */ + + if ( aMessage.Length() < KPlayFileCmdMinLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + // Parse parameter values from the message + const TUint8* ptr = aMessage.Ptr(); + TInt pathLength = aMessage[1]; + + if ( ( aMessage.Length() - pathLength ) != + ( KPlayFileCmdMinLength - 4 ) ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + TFileName filePath; + TInt nextOffset = ParseString( aMessage, 1, filePath ); + if ( filePath.Length() < 2 || nextOffset < 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + HTI_LOG_TEXT( "Full file path:" ); + HTI_LOG_DES( filePath ); + iVolume = aMessage[nextOffset]; + nextOffset++; + HTI_LOG_FORMAT( "Volume = %d", iVolume ); + iStartPos = ParseUint32( ptr + nextOffset ); + HTI_LOG_FORMAT( "Start position = %d", iStartPos ); + nextOffset += 4; + iEndPos = ParseUint32( ptr + nextOffset ); + HTI_LOG_FORMAT( "End position = %d", iEndPos ); + nextOffset += 4; + iRepeats = aMessage[nextOffset]; + nextOffset++; + HTI_LOG_FORMAT( "Repeats = %d", iRepeats ); + iTrailingSilence = ParseUint32( ptr + nextOffset ); + HTI_LOG_FORMAT( "Trailing silence = %d", iTrailingSilence ); + nextOffset += 4; + TInt audioSetting = aMessage[nextOffset]; + HTI_LOG_FORMAT( "Audio setting = %d", audioSetting ); + + // Set audio settings + if ( audioSetting > ERingTonePreview ) audioSetting = EDefault; + SetAudioSettings( ( TAudioSetting ) audioSetting ); + + // Check if file is rng ringtone, it has to be played using tone player - + // other formats are played with audio player. + + TInt err = KErrNone; + TBool isRng = EFalse; + TRAP( err, isRng = MatchMimeTypeL( filePath, KRngMimeType ) ); + + if ( err ) + { + User::LeaveIfError( SendErrorResponseMsg( err, KErrorFileInitFailed ) ); + return; + } + + if ( isRng ) + { + HTI_LOG_TEXT( "File is RNG - creating tone player" ); + TRAP( err, iTonePlayer = CMdaAudioToneUtility::NewL( + *this, NULL, iAudioPriority, iAudioPriorityPreference ) ); + } + + else + { + HTI_LOG_TEXT( "File is not RNG - creating audio player" ); + TRAP( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL( + filePath, *this, iAudioPriority, iAudioPriorityPreference ) ); + // MapcInitComplete callback function will be called + } + + if ( err ) + { + delete iAudioPlayer; + iAudioPlayer = NULL; + delete iTonePlayer; + iTonePlayer = NULL; + User::LeaveIfError( SendErrorResponseMsg( + err, KErrorFileInitFailed ) ); + } + + if ( iTonePlayer ) + { + iTonePlayer->PrepareToPlayFileSequence( filePath ); + // MatoPrepareComplete callback function will be called + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayFileCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandlePlayToneCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandlePlayToneCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayToneCmdL" ); + + if ( iIsPlaying ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrInUse, KErrorBusyPlaying ) ); + return; + } + + iPlayCommandId = ECmdPlayTone; + + /* + Message bytes: + 0 = command code + 1 - 2 = frequency value + 3 - 6 = duration value + 7 = volume value + 8 = repeat value + 9 - 12 = silence between repeats + */ + + if ( aMessage.Length() != KPlayToneCmdLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + // Parse parameter values from the message + const TUint8* ptr = aMessage.Ptr(); + TInt frequency = ParseUint16( ptr + 1 ); + HTI_LOG_FORMAT( "Freq = %d", frequency ); + TUint duration = ParseUint32( ptr + 3 ); + HTI_LOG_FORMAT( "Duration = %d", duration ); + iVolume = aMessage[7]; + HTI_LOG_FORMAT( "Volume = %d", iVolume ); + iRepeats = aMessage[8]; + HTI_LOG_FORMAT( "Repeats = %d", iRepeats ); + iTrailingSilence = ParseUint32( ptr + 9 ); + HTI_LOG_FORMAT( "Silence = %d", iTrailingSilence ); + + TRAPD( err, iTonePlayer = CMdaAudioToneUtility::NewL( *this ) ); + + if ( err ) + { + delete iTonePlayer; + iTonePlayer = NULL; + User::LeaveIfError( SendErrorResponseMsg( + err, KErrorToneInitFailed ) ); + } + + iTonePlayer->PrepareToPlayTone( frequency, + TTimeIntervalMicroSeconds( duration ) ); + // MatoPrepareComplete callback function will be called when ready to play + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayToneCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandlePlayDtmfCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandlePlayDtmfCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayDtmfCmdL" ); + + if ( iIsPlaying ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrInUse, KErrorBusyPlaying ) ); + return; + } + + iPlayCommandId = ECmdPlayDtmf; + + /* + Message bytes: + 0 = command code + 1 = DTMF string length + 2 - n = dtmf string + next 4 = tone length + next 4 = tone gap length + next 1 = volume + next 1 = repeats + next 4 = silence between repeats + */ + + if ( aMessage.Length() < KPlayDtmfCmdMinLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + // Parse parameter values from the message + const TUint8* ptr = aMessage.Ptr(); + TInt stringLength = aMessage[1]; + + if ( ( aMessage.Length() - stringLength ) != + ( KPlayDtmfCmdMinLength - 1 ) ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + TBuf<255> dtmfString; + TInt nextOffset = ParseString( aMessage, 1, dtmfString ); + if ( dtmfString.Length() < 1 || nextOffset < 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + HTI_LOG_TEXT( "DTMF string:" ); + HTI_LOG_DES( dtmfString ); + iDtmfLength = ParseUint32( ptr + nextOffset ); + nextOffset += 4; + HTI_LOG_FORMAT( "DTMF length = %d", iDtmfLength ); + iDtmfGapLength = ParseUint32( ptr + nextOffset ); + nextOffset += 4; + HTI_LOG_FORMAT( "DTMF gap length = %d", iDtmfGapLength ); + iVolume = aMessage[nextOffset]; + nextOffset++; + HTI_LOG_FORMAT( "Volume = %d", iVolume ); + iRepeats = aMessage[nextOffset]; + nextOffset++; + HTI_LOG_FORMAT( "Repeats = %d", iRepeats ); + iTrailingSilence = ParseUint32( ptr + nextOffset ); + HTI_LOG_FORMAT( "Trailing silence = %d", iTrailingSilence ); + + SetAudioSettings( EDtmfString ); + + TRAPD( err, iTonePlayer = CMdaAudioToneUtility::NewL( + *this, NULL, iAudioPriority, iAudioPriorityPreference ) ); + + if ( err ) + { + delete iTonePlayer; + iTonePlayer = NULL; + User::LeaveIfError( SendErrorResponseMsg( err, KErrorToneInitFailed ) ); + } + + iTonePlayer->PrepareToPlayDTMFString( dtmfString ); + // MatoPrepareComplete callback function will be called when ready to play + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayDtmfCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandleStopCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandleStopCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleStopCmdL" ); + + if ( aMessage.Length() != KStopCmdLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + if ( !iIsPlaying ) + { + HTI_LOG_TEXT( "Not playing - nothing to stop" ); + // Just send "OK" reply if nothing is currently playing + User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) ); + } + + else + { + if ( iAudioPlayer ) + { + HTI_LOG_TEXT( "Stopping audio player" ); + iAudioPlayer->Stop(); + iIsPlaying = EFalse; + delete iAudioPlayer; + iAudioPlayer = NULL; + // According to documentation should call MapcPlayComplete callback + // method but it doesn't, so sending reply here. + User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) ); + } + + else if ( iTonePlayer ) + { + HTI_LOG_TEXT( "Stopping tone player" ); + iTonePlayer->CancelPlay(); + iIsPlaying = EFalse; + delete iTonePlayer; + iTonePlayer = NULL; + // Callback method MatoPlayComplete is not called - + // sending reply here. + User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) ); + } + } + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleStopCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandleGetDurationCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandleGetDurationCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleGetDurationCmdL" ); + + if ( iIsPlaying ) + { + // If currently playing, no parameters allowed. Returns the duration + // of currently playing sound. + if ( aMessage.Length() != 1 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrInUse, KErrorBusyPlaying ) ); + return; + } + + if ( iAudioPlayer ) + { + TTimeIntervalMicroSeconds durationValue = + iAudioPlayer->Duration(); + + if ( I64HIGH( durationValue.Int64() ) > 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrOverflow, KErrorDurationFailed ) ); + return; + } + else + { + TUint duration = I64LOW( durationValue.Int64() ); + TBuf8 durationBuf; + durationBuf.Append( (TUint8*)(&duration), KTUintSize ); + User::LeaveIfError( SendResponseMsg( durationBuf ) ); + return; + } + } + + else // Duration supported only for audio player + { + User::LeaveIfError( SendErrorResponseMsg( + KErrNotSupported, KErrorDurationFailed ) ); + return; + } + } + + /* Command must have file path parameter if not currently playing. + Message bytes: + 0 = command code + 1 = path length + 2 - n = full path to file + */ + + if ( aMessage.Length() < KDurationCmdMinLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + TInt pathLength = aMessage[1]; + if ( ( aMessage.Length() - pathLength ) != + ( KDurationCmdMinLength - 4 ) ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + // Parse parameter values from the message + TFileName filePath; + TInt nextOffset = ParseString( aMessage, 1, filePath ); + if ( filePath.Length() < 2 || nextOffset < 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + HTI_LOG_TEXT( "Full file path:" ); + HTI_LOG_DES( filePath ); + + TRAPD( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL( + filePath, *this ) ); + if ( err ) + { + delete iAudioPlayer; + iAudioPlayer = NULL; + User::LeaveIfError( SendErrorResponseMsg( err, KErrorDurationFailed ) ); + } + + // MapcInitComplete callback function will be called + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleGetDurationCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandleGetMaxVolCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandleGetMaxVolCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleGetMaxVolCmdL" ); + + if ( iIsPlaying ) + { + // If currently playing, no parameters allowed. Returns the max volume + // of currently playing sound. + if ( aMessage.Length() != 1 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrInUse, KErrorBusyPlaying ) ); + return; + } + + TInt maxVol = -1; + + if ( iAudioPlayer ) + { + maxVol = iAudioPlayer->MaxVolume(); + } + + else if ( iTonePlayer ) + { + maxVol = iTonePlayer->MaxVolume(); + } + + HTI_LOG_FORMAT( "Max volume = %d", maxVol ); + + if ( maxVol < 0 ) + { + // Should not happen + User::LeaveIfError( SendErrorResponseMsg( + KErrGeneral, KErrorMaxVolFailed ) ); + return; + } + + if ( maxVol > 255 ) maxVol = 255; + TBuf8<1> maxVolBuf; + maxVolBuf.Append( maxVol ); + User::LeaveIfError( SendResponseMsg( maxVolBuf ) ); + return; + } + + /* + Message bytes: + 0 = command code + 1 = path length + 2 - n = full path to file + */ + + if ( aMessage.Length() < KMaxVolCmdMinLength ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + TInt pathLength = aMessage[1]; + if ( ( aMessage.Length() - pathLength ) != ( KMaxVolCmdMinLength - 4 ) ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + + // Parse parameter values from the message + TFileName filePath; + TInt nextOffset = ParseString( aMessage, 1, filePath ); + if ( filePath.Length() < 2 || nextOffset < 0 ) + { + User::LeaveIfError( SendErrorResponseMsg( + KErrArgument, KErrorInvalidParameters ) ); + return; + } + HTI_LOG_TEXT( "Full file path:" ); + HTI_LOG_DES( filePath ); + + TInt err = KErrNone; + TBool isRng = EFalse; + TRAP( err, isRng = MatchMimeTypeL( filePath, KRngMimeType ) ); + + if ( err ) + { + User::LeaveIfError( SendErrorResponseMsg( err, KErrorMaxVolFailed ) ); + return; + } + + if ( isRng ) + { + HTI_LOG_TEXT( "File is RNG - creating tone player" ); + TRAP( err, iTonePlayer = CMdaAudioToneUtility::NewL( *this ) ); + } + + else + { + HTI_LOG_TEXT( "File is not RNG - creating audio player" ); + TRAP( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL( + filePath, *this ) ); + // MapcInitComplete callback function will be called + } + + if ( err ) + { + delete iAudioPlayer; + iAudioPlayer = NULL; + delete iTonePlayer; + iTonePlayer = NULL; + User::LeaveIfError( SendErrorResponseMsg( err, KErrorMaxVolFailed ) ); + } + + if ( iTonePlayer ) + { + iTonePlayer->PrepareToPlayFileSequence( filePath ); + // MatoPrepareComplete callback function will be called + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleGetMaxVolCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::HandleSetVolCmdL() +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::HandleSetVolCmdL( const TDesC8& aMessage ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleSetVolCmdL" ); + + if ( aMessage.Length() != KSetVolCmdLength ) + { + User::LeaveIfError( SendErrorResponseMsg( KErrArgument, + KErrorInvalidParameters ) ); + } + + if ( !iIsPlaying ) + { + HTI_LOG_TEXT( "Nothing playing - not setting volume" ); + User::LeaveIfError( SendErrorResponseMsg( + KErrNotReady, KErrorNothingPlaying ) ); + } + + else + { + TInt volume = aMessage[1]; // [0] = command code, [1] = volume value + HTI_LOG_FORMAT( "requested volume = %d", volume ); + + if ( iAudioPlayer ) + { + HTI_LOG_TEXT( "Setting audio player volume" ); + TInt maxVol = iAudioPlayer->MaxVolume(); + HTI_LOG_FORMAT( "max volume = %d", maxVol ); + if ( volume > maxVol ) volume = maxVol; + iAudioPlayer->SetVolume( volume ); + TBuf8<1> volBuf; + volBuf.Append( volume ); + User::LeaveIfError( SendResponseMsg( volBuf ) ); + } + else if ( iTonePlayer ) + { + HTI_LOG_TEXT( "Setting tone player volume" ); + TInt maxVol = iTonePlayer->MaxVolume(); + HTI_LOG_FORMAT( "max volume = %d", maxVol ); + if ( volume > maxVol ) volume = maxVol; + iTonePlayer->SetVolume( volume ); + TBuf8<1> volBuf; + volBuf.Append( volume ); + User::LeaveIfError( SendResponseMsg( volBuf ) ); + } + } + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleSetVolCmdL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::MatoPrepareComplete() +// Tone player prepare complete +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::MatoPrepareComplete( TInt aError ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatoPrepareComplete" ); + + if ( iCommandId == ECmdGetMaxVol ) + { + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorMaxVolFailed ); + } + + else + { + TInt maxVol = iTonePlayer->MaxVolume(); + HTI_LOG_FORMAT( "Max volume = %d", maxVol ); + if ( maxVol > 255 ) maxVol = 255; + TBuf8<1> maxVolBuf; + maxVolBuf.Append( maxVol ); + SendResponseMsg( maxVolBuf ); + } + + delete iTonePlayer; + iTonePlayer = NULL; + return; + } + + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorToneInitFailed ); + delete iTonePlayer; + iTonePlayer = NULL; + } + + else + { + if ( iCommandId == ECmdPlayDtmf ) + { + iTonePlayer->SetDTMFLengths( + TTimeIntervalMicroSeconds32( iDtmfLength ), + TTimeIntervalMicroSeconds32( iDtmfGapLength ), + TTimeIntervalMicroSeconds32( 0 ) ); + } + + if ( iVolume > iTonePlayer->MaxVolume() ) + { + iVolume = iTonePlayer->MaxVolume(); + } + + iTonePlayer->SetVolume( iVolume ); + iTonePlayer->SetRepeats( iRepeats + 1, + TTimeIntervalMicroSeconds( iTrailingSilence ) ); + iIsPlaying = ETrue; + iTonePlayer->Play(); + iIsBusy = EFalse; + // MatoPlayComplete callback function will be called when playing ends. + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatoPrepareComplete" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::MatoPlayComplete() +// Tone play complete +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::MatoPlayComplete( TInt aError ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatoPlayComplete" ); + + iIsPlaying = EFalse; + iIsBusy = ETrue; // Busy dispatching the play complete message + + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorTonePlayFailed, iPlayCommandId ); + } + + else + { + SendResponseMsg( _L8( "OK" ), iPlayCommandId ); + } + + delete iTonePlayer; + iTonePlayer = NULL; + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatoPlayComplete" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::MapcInitComplete() +// Audio player init complete +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::MapcInitComplete( TInt aError, + const TTimeIntervalMicroSeconds& aDuration ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MapcInitComplete" ); + + if ( iCommandId == ECmdPlayFile ) + { + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorFileInitFailed ); + delete iAudioPlayer; + iAudioPlayer = NULL; + } + + else + { + if ( iEndPos < iStartPos || + TTimeIntervalMicroSeconds( iStartPos ) > aDuration ) + { + SendErrorResponseMsg( KErrArgument, KErrorPosition ); + delete iAudioPlayer; + iAudioPlayer = NULL; + return; + } + + if ( iEndPos > 0 ) + { + iAudioPlayer->SetPlayWindow( + TTimeIntervalMicroSeconds( iStartPos ), + TTimeIntervalMicroSeconds( iEndPos ) ); + } + + HTI_LOG_FORMAT( "Max volume = %d", iAudioPlayer->MaxVolume() ); + HTI_LOG_FORMAT( "Setting volume = %d", iVolume ); + if ( iVolume > iAudioPlayer->MaxVolume() ) + { + iVolume = iAudioPlayer->MaxVolume(); + } + + iAudioPlayer->SetVolume( iVolume ); + iAudioPlayer->SetRepeats( iRepeats, + TTimeIntervalMicroSeconds( iTrailingSilence ) ); + iIsPlaying = ETrue; + iAudioPlayer->Play(); + + // Have to do this after play command because + // volume setting before play seems to have no effect. + iAudioPlayer->SetVolume( 0 ); + iAudioPlayer->SetVolume( iVolume ); + + iIsBusy = EFalse; + // MapcPlayComplete callback function is called when playing ends + } + } + + else if ( iCommandId == ECmdGetDuration ) + { + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorDurationFailed ); + } + + else + { + if ( I64HIGH( aDuration.Int64() ) > 0 ) + { + SendErrorResponseMsg( KErrOverflow, KErrorDurationFailed ); + } + else + { + TUint duration = I64LOW( aDuration.Int64() ); + TBuf8 durationBuf; + durationBuf.Append( (TUint8*)(&duration), KTUintSize ); + SendResponseMsg( durationBuf ); + } + } + delete iAudioPlayer; + iAudioPlayer = NULL; + } + + else if ( iCommandId == ECmdGetMaxVol ) + { + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorMaxVolFailed ); + } + + else + { + TInt maxVol = iAudioPlayer->MaxVolume(); + HTI_LOG_FORMAT( "Max volume = %d", maxVol ); + if ( maxVol > 255 ) maxVol = 255; + TBuf8<1> maxVolBuf; + maxVolBuf.Append( maxVol ); + SendResponseMsg( maxVolBuf ); + } + delete iAudioPlayer; + iAudioPlayer = NULL; + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MapcInitComplete" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::MapcPlayComplete() +// Audio play complete +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::MapcPlayComplete( TInt aError ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MapcPlayComplete" ); + + iIsPlaying = EFalse; + iIsBusy = ETrue; // Busy dispatching the play complete message + + if ( aError ) + { + SendErrorResponseMsg( aError, KErrorFilePlayFailed, ECmdPlayFile ); + } + + else + { + SendResponseMsg( _L8( "OK" ), iPlayCommandId ); + } + + delete iAudioPlayer; + iAudioPlayer = NULL; + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MapcPlayComplete" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::NotifyMemoryChange +// Called when HTI Framework has dispatched a message forward and the amount +// of free memory in the message queue has changed. +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::NotifyMemoryChange( TInt aAvailableMemory ) + { + if ( iIsBusy && iMessage ) + { + if ( aAvailableMemory >= iMessage->Size() ) + { + if ( iErrorCode == 0 ) + { + TInt err = iDispatcher->DispatchOutgoingMessage( + iMessage, KAudioServiceUid ); + + if ( err == KErrNone ) + { + // Ownership of iMessage has been transferred + iMessage = NULL; + iIsBusy = EFalse; + iDispatcher->RemoveMemoryObserver( this ); + } + + else if ( err == KErrNoMemory ) + { + // Keep retrying. + } + + else // Give up on sending + { + delete iMessage; + iMessage = NULL; + iIsBusy = EFalse; + iDispatcher->RemoveMemoryObserver( this ); + } + } + + else + { + TInt err = iDispatcher->DispatchOutgoingErrorMessage( + iErrorCode, *iMessage, KAudioServiceUid ); + + // If it was success or some other error than KErrNoMemory + // we are done sending or trying to send this message. + if ( err != KErrNoMemory ) + { + delete iMessage; + iMessage = NULL; + iIsBusy = EFalse; + iDispatcher->RemoveMemoryObserver( this ); + } + + else + { + // Keep retrying. + } + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::IsBusy +// ----------------------------------------------------------------------------- +// +TBool CHtiAudioServicePlugin::IsBusy() + { + return iIsBusy; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::SendResponseMsg +// Sends a message out to the message dispatcher. +// ----------------------------------------------------------------------------- +// +TInt CHtiAudioServicePlugin::SendResponseMsg( const TDesC8& aMsg, + const TUint8 aCommandId ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SendResponseMsg" ); + + iErrorCode = 0; + + if ( iDispatcher == NULL ) + { + iIsBusy = EFalse; + return KErrGeneral; + } + + iDispatcher->RemoveMemoryObserver( this ); + + delete iMessage; + iMessage = NULL; + iMessage = HBufC8::New( aMsg.Length() + 1 ); + + if ( iMessage == NULL ) + { + iIsBusy = EFalse; + return KErrNoMemory; + } + + TPtr8 ptr8 = iMessage->Des(); + if ( aCommandId != 0 ) + { + ptr8.Append( aCommandId ); + } + else + { + ptr8.Append( iCommandId ); + } + + ptr8.Append( aMsg ); + + TInt err = KErrNone; + + err = iDispatcher->DispatchOutgoingMessage( iMessage, KAudioServiceUid ); + + if ( err == KErrNoMemory ) + { + HTI_LOG_TEXT( "Message queue memory full - waiting" ); + iIsBusy = ETrue; // Should already be true, but just in case + iDispatcher->AddMemoryObserver( this ); + // For the caller of this method all is OK, sending is just delayed + err = KErrNone; + } + + else if ( err == KErrNone ) + { + HTI_LOG_TEXT( "Message sent to dispatcher" ); + iMessage = NULL; // Ownership of iMessage has been transferred + iIsBusy = EFalse; + } + + else // give up on sending + { + HTI_LOG_FORMAT( "Other dispatcher error %d", err ); + delete iMessage; + iMessage = NULL; + iIsBusy = EFalse; + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SendResponseMsg" ); + return err; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::SendErrorResponseMsg +// Sends an error message out to the message dispatcher. +// ----------------------------------------------------------------------------- +// +TInt CHtiAudioServicePlugin::SendErrorResponseMsg( TInt aErrorCode, + const TDesC8& aErrorDescription, + const TUint8 aCommandId ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SendErrorResponseMsg" ); + + iErrorCode = aErrorCode; + + if ( iDispatcher == NULL ) + { + iIsBusy = EFalse; + return KErrGeneral; + } + + iDispatcher->RemoveMemoryObserver( this ); + + delete iMessage; + iMessage = NULL; + iMessage = HBufC8::New( aErrorDescription.Length() + 1 ); + + if ( iMessage == NULL ) + { + iIsBusy = EFalse; + return KErrNoMemory; + } + + TPtr8 ptr8 = iMessage->Des(); + if ( aCommandId != 0 ) + { + ptr8.Append( aCommandId ); + } + else + { + ptr8.Append( iCommandId ); + } + + ptr8.Append( aErrorDescription ); + + TInt err = KErrNone; + + err = iDispatcher->DispatchOutgoingErrorMessage( + aErrorCode, *iMessage, KAudioServiceUid ); + + if ( err == KErrNoMemory ) + { + HTI_LOG_TEXT( "Message queue memory full - waiting" ); + iIsBusy = ETrue; // Should already be true, but just in case + iDispatcher->AddMemoryObserver( this ); + // For the caller of this method all is OK, sending is just delayed + err = KErrNone; + } + + else if ( err == KErrNone ) + { + HTI_LOG_TEXT( "Error message sent to dispatcher" ); + delete iMessage; + iMessage = NULL; + iIsBusy = EFalse; + } + + else // give up on sending + { + HTI_LOG_FORMAT( "Other dispatcher error %d", err ); + delete iMessage; + iMessage = NULL; + iIsBusy = EFalse; + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SendErrorResponseMsg" ); + return err; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::ParseString() +// ----------------------------------------------------------------------------- +// +TInt CHtiAudioServicePlugin::ParseString( const TDesC8& aRequest, + TInt aOffset, + TDes& aResult ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::ParseString" ); + + // If offset outside the string return empty string + if ( aOffset >= aRequest.Size() ) + { + return aOffset; + } + + TInt length = aRequest[aOffset]; + HTI_LOG_FORMAT( "String length = %d", length ); + + // If length is zero return empty string + if ( length < 1 ) + { + return aOffset + 1; + } + + if ( length > aResult.MaxLength() ) + { + return KErrBadDescriptor; + } + + TInt nextOffset = length + aOffset + 1; + HTI_LOG_FORMAT( "Next offset = %d", nextOffset ); + HTI_LOG_FORMAT( "Request size = %d", aRequest.Size() ); + + if ( nextOffset > aRequest.Size() ) + { + return KErrArgument; + } + + aResult.Copy( aRequest.Mid( aOffset + 1, length ) ); + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::ParseString" ); + return nextOffset; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::AddSubdirsRecursivelyL +// Scan all subdirectories from the given path and add them to the aArray. +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::AddSubdirsRecursivelyL( const TDesC& aPath, + CDesCArraySeg& aArray, + RFs& aFs ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::AddSubdirsRecursivelyL" ); + + CDirScan* dirScan = CDirScan::NewL( aFs ); + CleanupStack::PushL( dirScan ); + + TFileName* path = new (ELeave) TFileName; + CleanupStack::PushL( path ); + + CDir* directory = NULL; + TPtrC currentPath; + + dirScan->SetScanDataL( aPath, KEntryAttMatchExclusive | KEntryAttDir, ESortNone ); + dirScan->NextL( directory ); + + while ( directory ) + { + CleanupStack::PushL( directory ); + currentPath.Set( dirScan->FullPath() ); + + TInt dirCount( directory->Count() ); + for ( TInt i = 0; i < dirCount ; ++i ) + { + path->Copy( currentPath ); + path->Append( ( *directory )[ i ].iName ); + path->Append( KBackslash ); + aArray.AppendL( *path ); + } + + CleanupStack::PopAndDestroy( directory ); + directory = NULL; + + dirScan->NextL( directory ); + } + + CleanupStack::PopAndDestroy( 2 ); // path, dirScan + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::AddSubdirsRecursivelyL" ); + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::MatchMimeTypeL +// Check if the MIME type of the given file matches to the given pattern. +// ----------------------------------------------------------------------------- +// +TBool CHtiAudioServicePlugin::MatchMimeTypeL( const TDesC& aFilePath, + const TDesC& aMimeTypeMatchPattern ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatchMimeTypeL" ); + + RApaLsSession apaSession; + User::LeaveIfError( apaSession.Connect() ); + CleanupClosePushL( apaSession ); + + TUid dummyUid( KNullUid ); + TDataType dataType; + User::LeaveIfError( apaSession.AppForDocument( aFilePath, + dummyUid, + dataType ) ); + CleanupStack::PopAndDestroy(); // apaSession + + if ( dataType.Des().MatchF( aMimeTypeMatchPattern ) >= 0 ) + { + HTI_LOG_TEXT( "Match" ); + return ETrue; + } + + HTI_LOG_TEXT( "Not match" ); + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatchMimeTypeL" ); + return EFalse; + } + + +// ----------------------------------------------------------------------------- +// CHtiAudioServicePlugin::SetAudioSettings +// Set the audio priority and priority preference values. +// ----------------------------------------------------------------------------- +// +void CHtiAudioServicePlugin::SetAudioSettings( TAudioSetting aSetting ) + { + HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SetAudioSettings" ); + HTI_LOG_FORMAT( "Setting values for audio setting %d", aSetting ); + + switch ( aSetting ) + { + case EGeneralMusic: + { + iAudioPriority = KAudioPriorityRealOnePlayer; + iAudioPriorityPreference = + ( TMdaPriorityPreference ) KAudioPrefRealOneLocalPlayback; + break; + } + + case ERingTonePreview: + { + iAudioPriority = KAudioPriorityRingingTonePreview; + iAudioPriorityPreference = + ( TMdaPriorityPreference ) KAudioPrefRingFilePreview; + break; + } +/* + case EIncomingCall: + { + iAudioPriority = KAudioPriorityPhoneCall; + iAudioPriorityPreference = + ( TMdaPriorityPreference ) KAudioPrefIncomingCall; + break; + } +*/ + case EDtmfString: + { + + iAudioPriority = KAudioPriorityDTMFString; + iAudioPriorityPreference = + ( TMdaPriorityPreference ) KAudioDTMFString; + break; + } + + default: + { + iAudioPriority = EMdaPriorityNormal; + iAudioPriorityPreference = EMdaPriorityPreferenceTimeAndQuality; + break; + } + } + + HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SetAudioSettings" ); + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File