htiui/HtiServicePlugins/HtiAudioServicePlugin/src/HtiAudioServicePlugin.cpp
changeset 0 d6fe6244b863
child 3 2703485a934c
equal deleted inserted replaced
-1:000000000000 0:d6fe6244b863
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implements the ECom plugin for HTI audio playback control
       
    15 *                service.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <apgcli.h>
       
    23 #include <audiopreference.h>
       
    24 #include <bautils.h>
       
    25 #include <e32std.h>
       
    26 #include <HtiDispatcherInterface.h>
       
    27 #include <HTILogging.h>
       
    28 #include <PathInfo.h>
       
    29 
       
    30 #include "HtiAudioServicePlugin.h"
       
    31 
       
    32 // EXTERNAL DATA STRUCTURES
       
    33 
       
    34 // EXTERNAL FUNCTION PROTOTYPES
       
    35 
       
    36 // CONSTANTS
       
    37 const static TInt KPlayToneCmdLength    = 13;
       
    38 const static TInt KStopCmdLength        = 1;
       
    39 const static TInt KSetVolCmdLength      = 2;
       
    40 const static TInt KListCmdMinLength     = 4;
       
    41 const static TInt KPlayDtmfCmdMinLength = 17;
       
    42 const static TInt KPlayFileCmdMinLength = 21;
       
    43 const static TInt KDurationCmdMinLength = 6;
       
    44 const static TInt KMaxVolCmdMinLength   = 6;
       
    45 
       
    46 const static TInt KTUintSize = sizeof( TUint );
       
    47 
       
    48 // MACROS
       
    49 
       
    50 // LOCAL CONSTANTS AND MACROS
       
    51 const static TUid KAudioServiceUid = { 0x10210CCB };
       
    52 
       
    53 _LIT( KBackslash, "\\" );
       
    54 _LIT( KRngMimeType, "application/vnd.nokia.ringing-tone" );
       
    55 _LIT( KAudioMimeType, "audio/*" );
       
    56 
       
    57 // NOTE: Max length for error description is defined
       
    58 // in HtiDispatcherInterface.h (currently 118).
       
    59 _LIT8( KErrorNoCmd, "ERROR: No command given" );
       
    60 _LIT8( KErrorUnknownCmd, "ERROR: Unknown Audio Service command" );
       
    61 _LIT8( KErrorInvalidParameters,
       
    62     "ERROR: Invalid parameter data for this command" );
       
    63 _LIT8( KErrorInvalidPath, "ERROR: Invalid path" );
       
    64 _LIT8( KErrorToneInitFailed, "ERROR: Tone initialization failed" );
       
    65 _LIT8( KErrorTonePlayFailed, "ERROR: Tone playing failed" );
       
    66 _LIT8( KErrorFileInitFailed, "ERROR: File playing initialization failed" );
       
    67 _LIT8( KErrorFilePlayFailed, "ERROR: File playing failed" );
       
    68 _LIT8( KErrorBusyPlaying, "ERROR: Currently busy playing" );
       
    69 _LIT8( KErrorNothingPlaying, "ERROR: Nothing playing" );
       
    70 _LIT8( KErrorDurationFailed, "ERROR: Duration query failed" );
       
    71 _LIT8( KErrorMaxVolFailed, "ERROR: Max volume query failed" );
       
    72 _LIT8( KErrorPosition, "ERROR: Invalid start or end position value" );
       
    73 
       
    74 // MODULE DATA STRUCTURES
       
    75 
       
    76 // LOCAL FUNCTION PROTOTYPES
       
    77 
       
    78 // FORWARD DECLARATIONS
       
    79 
       
    80 // ============================= LOCAL FUNCTIONS ===============================
       
    81 
       
    82 // ============================ MEMBER FUNCTIONS ===============================
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CHtiAudioServicePlugin::CHtiAudioServicePlugin
       
    86 // C++ default constructor can NOT contain any code, that might leave.
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 CHtiAudioServicePlugin::CHtiAudioServicePlugin():iIsBusy( EFalse ),
       
    90                                                  iIsPlaying( EFalse ),
       
    91                                                  iCommandId( 0 ),
       
    92                                                  iPlayCommandId( 0 ),
       
    93                                                  iMessage( NULL ),
       
    94                                                  iErrorCode( 0 ),
       
    95                                                  iVolume( 0 ),
       
    96                                                  iRepeats( 0 ),
       
    97                                                  iTrailingSilence( 0 ),
       
    98                                                  iDtmfLength( 0 ),
       
    99                                                  iDtmfGapLength( 0 ),
       
   100                                                  iStartPos( 0 ),
       
   101                                                  iEndPos( 0 )
       
   102     {
       
   103     }
       
   104 
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CHtiAudioServicePlugin::ConstructL
       
   108 // Symbian 2nd phase constructor can leave.
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 void CHtiAudioServicePlugin::ConstructL()
       
   112     {
       
   113     }
       
   114 
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CHtiAudioServicePlugin::NewL
       
   118 // Two-phased constructor.
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 CHtiAudioServicePlugin* CHtiAudioServicePlugin::NewL()
       
   122     {
       
   123     CHtiAudioServicePlugin* self = new (ELeave) CHtiAudioServicePlugin;
       
   124     CleanupStack::PushL( self );
       
   125     self->ConstructL();
       
   126     CleanupStack::Pop();
       
   127     return self;
       
   128     }
       
   129 
       
   130 
       
   131 // Destructor
       
   132 CHtiAudioServicePlugin::~CHtiAudioServicePlugin()
       
   133     {
       
   134     delete iMessage;
       
   135     iMessage = NULL;
       
   136     delete iAudioPlayer;
       
   137     iAudioPlayer = NULL;
       
   138     delete iTonePlayer;
       
   139     iTonePlayer = NULL;
       
   140     }
       
   141 
       
   142 
       
   143 // -----------------------------------------------------------------------------
       
   144 // CHtiAudioServicePlugin::ProcessMessageL
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 void CHtiAudioServicePlugin::ProcessMessageL( const TDesC8& aMessage,
       
   148                                         THtiMessagePriority /*aPriority*/ )
       
   149     {
       
   150     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::ProcessMessageL" );
       
   151     HTI_LOG_FORMAT( "Message length = %d", aMessage.Length() );
       
   152 
       
   153     if ( iIsBusy )
       
   154         {
       
   155         HTI_LOG_TEXT( "Plugin is busy - leaving" );
       
   156         User::Leave( KErrInUse );
       
   157         }
       
   158 
       
   159     // Will be set to EFalse in the SendResponseMsg or SendErrorResponseMsg
       
   160     // methods when the response has been successfully sent and the plugin is
       
   161     // ready for next message.
       
   162     iIsBusy = ETrue;
       
   163 
       
   164     if ( aMessage.Length() < 1 )
       
   165         {
       
   166         User::LeaveIfError(
       
   167             SendErrorResponseMsg( KErrArgument, KErrorNoCmd ) );
       
   168         return;
       
   169         }
       
   170 
       
   171     iCommandId = aMessage[0];
       
   172     HTI_LOG_FORMAT( "Command = %d", iCommandId );
       
   173     TInt err = KErrNone;
       
   174 
       
   175     if ( iCommandId == ECmdListAudioFiles )
       
   176         {
       
   177         TRAP( err, HandleListAudioFilesCmdL( aMessage ) );
       
   178         }
       
   179 
       
   180     else if ( iCommandId == ECmdPlayFile )
       
   181         {
       
   182         TRAP( err, HandlePlayFileCmdL( aMessage ) );
       
   183         }
       
   184 
       
   185     else if ( iCommandId == ECmdPlayTone )
       
   186         {
       
   187         TRAP( err, HandlePlayToneCmdL( aMessage ) );
       
   188         }
       
   189 
       
   190     else if ( iCommandId == ECmdPlayDtmf )
       
   191         {
       
   192         TRAP( err, HandlePlayDtmfCmdL( aMessage ) );
       
   193         }
       
   194 
       
   195     else if ( iCommandId == ECmdStop )
       
   196         {
       
   197         TRAP( err, HandleStopCmdL( aMessage ) );
       
   198         }
       
   199 
       
   200     else if ( iCommandId == ECmdGetDuration )
       
   201         {
       
   202         TRAP( err, HandleGetDurationCmdL( aMessage ) );
       
   203         }
       
   204 
       
   205     else if ( iCommandId == ECmdGetMaxVol )
       
   206         {
       
   207         TRAP( err, HandleGetMaxVolCmdL( aMessage ) );
       
   208         }
       
   209 
       
   210     else if ( iCommandId == ECmdSetVol )
       
   211         {
       
   212         TRAP( err, HandleSetVolCmdL( aMessage ) );
       
   213         }
       
   214 
       
   215     else
       
   216         {
       
   217         User::LeaveIfError(
       
   218             SendErrorResponseMsg( KErrArgument, KErrorUnknownCmd ) );
       
   219         }
       
   220 
       
   221     if ( err != KErrNone )
       
   222         {
       
   223         User::LeaveIfError(
       
   224                 SendErrorResponseMsg( err, KNullDesC8, iCommandId ) );
       
   225         }
       
   226 
       
   227     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::ProcessMessageL" );
       
   228     }
       
   229 
       
   230 
       
   231 // -----------------------------------------------------------------------------
       
   232 // CHtiAudioServicePlugin::HandleListAudioFilesCmdL()
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 void CHtiAudioServicePlugin::HandleListAudioFilesCmdL( const TDesC8& aMessage )
       
   236     {
       
   237     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleListAudioFilesCmdL" );
       
   238 
       
   239     RFs fsSession;
       
   240     User::LeaveIfError( fsSession.Connect() );
       
   241     CleanupClosePushL( fsSession );
       
   242 
       
   243     // Build a list of directories to scan
       
   244     CDesCArraySeg* directories = new (ELeave) CDesCArraySeg( 5 );
       
   245     CleanupStack::PushL( directories );
       
   246 
       
   247     if ( aMessage.Length() == 1 )  // Add default sound directories
       
   248         {
       
   249         TFileName directory;
       
   250 
       
   251         // ROM
       
   252         directory.Append( PathInfo::RomRootPath() );
       
   253         directory.Append( PathInfo::SoundsPath() );
       
   254         if ( BaflUtils::PathExists( fsSession, directory ) )
       
   255             {
       
   256             directories->AppendL( directory );
       
   257             AddSubdirsRecursivelyL( directories->MdcaPoint(
       
   258                 directories->Count() - 1 ), *directories, fsSession );
       
   259             }
       
   260 
       
   261         // Phone memory
       
   262         directory.Zero();
       
   263         directory.Append( PathInfo::PhoneMemoryRootPath() );
       
   264         directory.Append( PathInfo::SoundsPath() );
       
   265         if ( BaflUtils::PathExists( fsSession, directory ) )
       
   266             {
       
   267             directories->AppendL( directory );
       
   268             AddSubdirsRecursivelyL( directories->MdcaPoint(
       
   269                 directories->Count() - 1 ), *directories, fsSession );
       
   270             }
       
   271 
       
   272         // Memory card
       
   273         directory.Zero();
       
   274         directory.Append( PathInfo::MemoryCardRootPath() );
       
   275         directory.Append( PathInfo::SoundsPath() );
       
   276         if ( BaflUtils::PathExists( fsSession, directory ) )
       
   277             {
       
   278             directories->AppendL( directory );
       
   279             AddSubdirsRecursivelyL( directories->MdcaPoint(
       
   280                 directories->Count() - 1 ), *directories, fsSession );
       
   281             }
       
   282         }
       
   283 
       
   284     else  // Add given directory
       
   285         {
       
   286         if ( aMessage.Length() < KListCmdMinLength )
       
   287             {
       
   288             User::LeaveIfError( SendErrorResponseMsg(
       
   289                                     KErrArgument, KErrorInvalidParameters ) );
       
   290             CleanupStack::PopAndDestroy( 2 ); // directories, fsSession
       
   291             return;
       
   292             }
       
   293 
       
   294         TInt pathLength = aMessage[1];
       
   295         if ( ( aMessage.Length() - pathLength ) != KListCmdMinLength - 2 )
       
   296             {
       
   297             User::LeaveIfError( SendErrorResponseMsg(
       
   298                                     KErrArgument, KErrorInvalidParameters ) );
       
   299             CleanupStack::PopAndDestroy( 2 ); // directories, fsSession
       
   300             return;
       
   301             }
       
   302 
       
   303         TFileName directory;
       
   304         TInt nextOffset = ParseString( aMessage, 1, directory );
       
   305         TInt dirLength = directory.Length();
       
   306         if ( dirLength < 2 || nextOffset < 0 )
       
   307             {
       
   308             User::LeaveIfError( SendErrorResponseMsg(
       
   309                                     KErrArgument, KErrorInvalidParameters ) );
       
   310             CleanupStack::PopAndDestroy( 2 ); // directories, fsSession
       
   311             return;
       
   312             }
       
   313 
       
   314         HTI_LOG_DES( directory );
       
   315 
       
   316         if ( directory[dirLength - 1] != '\\' )
       
   317             {
       
   318             HTI_LOG_TEXT( "Adding backslash to the end" );
       
   319             directory.Append( KBackslash );
       
   320             HTI_LOG_DES( directory );
       
   321             }
       
   322 
       
   323         if ( BaflUtils::PathExists( fsSession, directory ) )
       
   324             {
       
   325             HTI_LOG_TEXT( "Given path exists" );
       
   326             directories->AppendL( directory );
       
   327             AddSubdirsRecursivelyL( directories->MdcaPoint(
       
   328                 directories->Count() - 1 ), *directories, fsSession );
       
   329             }
       
   330         }
       
   331 
       
   332     // Buffer for the file list that is returned
       
   333     CBufFlat* fileListBuf = CBufFlat::NewL( 256 );
       
   334     CleanupStack::PushL( fileListBuf );
       
   335     TInt bufPos = 0;
       
   336 
       
   337     TInt audioFileCount = 0;
       
   338     TInt dirCount( directories->Count() );
       
   339     HTI_LOG_FORMAT( "Total directory count = %d", dirCount );
       
   340 
       
   341     if ( dirCount == 0 )
       
   342         {
       
   343         HTI_LOG_TEXT( "The given directory did not exist" );
       
   344         User::LeaveIfError( SendErrorResponseMsg(
       
   345                                 KErrArgument, KErrorInvalidPath ) );
       
   346         CleanupStack::PopAndDestroy( 3 ); // fileListBuf, directories, fsSession
       
   347         return;
       
   348         }
       
   349 
       
   350     // Loop all the directories
       
   351     for ( TInt i = 0; i < dirCount; i++ )
       
   352         {
       
   353         HTI_LOG_TEXT( "Reading dir:" );
       
   354         HTI_LOG_DES( directories->MdcaPoint( i ) );
       
   355         CDir* dir;
       
   356         TInt err = fsSession.GetDir( directories->MdcaPoint( i ),
       
   357             KEntryAttNormal, ESortNone, dir );
       
   358         if ( err )
       
   359             {
       
   360             delete dir;
       
   361             dir = NULL;
       
   362             continue; // This dir is skipped
       
   363             }
       
   364         CleanupStack::PushL( dir );
       
   365 
       
   366         // Loop all the entries in this directory
       
   367         TInt fileCount( dir->Count() );
       
   368         for ( TInt j = 0; j < fileCount; j++ )
       
   369             {
       
   370             TFileName filePath;
       
   371             filePath.Copy( directories->MdcaPoint( i ) );
       
   372             filePath.Append( ( *dir )[j].iName );
       
   373 
       
   374             // Check MIME type match
       
   375             if ( MatchMimeTypeL( filePath, KAudioMimeType ) ||
       
   376                  MatchMimeTypeL( filePath, KRngMimeType ) )
       
   377                 {
       
   378                 HBufC8* filePathBuf8 = HBufC8::NewLC( KMaxFileName );
       
   379                 filePathBuf8->Des().Copy( filePath );
       
   380                 TInt pathLength = filePathBuf8->Length();
       
   381                 HTI_LOG_DES( *filePathBuf8 );
       
   382                 fileListBuf->ExpandL( bufPos, pathLength + 1 );
       
   383                 TBuf8<1> lengthBuf;
       
   384                 lengthBuf.Append( pathLength );
       
   385                 fileListBuf->Write( bufPos, lengthBuf, 1 );
       
   386                 bufPos++;
       
   387                 fileListBuf->Write( bufPos, filePathBuf8->Ptr(), pathLength );
       
   388                 bufPos += pathLength;
       
   389                 CleanupStack::PopAndDestroy(); // filePathBuf8
       
   390                 audioFileCount++;
       
   391                 }
       
   392 
       
   393             } // files loop
       
   394         CleanupStack::PopAndDestroy(); // dir
       
   395         } // directories loop
       
   396 
       
   397     HTI_LOG_FORMAT( "Total audio file count = %d", audioFileCount );
       
   398 
       
   399     // All files added - write number of files to the beginning of buffer...
       
   400     TBuf8<2> countBuf;
       
   401     countBuf.Append( (TUint8*)(&audioFileCount), 2 );
       
   402     fileListBuf->InsertL( 0, countBuf, 2 );
       
   403 
       
   404     // ...and send it away
       
   405     TPtr8 ptr = fileListBuf->Ptr( 0 );
       
   406     User::LeaveIfError( SendResponseMsg( ptr ) );
       
   407 
       
   408     CleanupStack::PopAndDestroy( 3 ); // fileListBuf, directories, fsSession
       
   409 
       
   410     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleListAudioFilesCmdL" );
       
   411     }
       
   412 
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CHtiAudioServicePlugin::HandlePlayFileCmdL()
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 void CHtiAudioServicePlugin::HandlePlayFileCmdL( const TDesC8&aMessage )
       
   419     {
       
   420     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayFileCmdL" );
       
   421 
       
   422     if ( iIsPlaying )
       
   423         {
       
   424         User::LeaveIfError( SendErrorResponseMsg(
       
   425                                 KErrInUse, KErrorBusyPlaying ) );
       
   426         return;
       
   427         }
       
   428 
       
   429     iPlayCommandId = ECmdPlayFile;
       
   430 
       
   431     /*
       
   432     Message bytes:
       
   433              0 = command code
       
   434              1 = path length
       
   435          2 - n = full path to file
       
   436         next 1 = volume
       
   437         next 4 = start position
       
   438         next 4 = end position
       
   439         next 1 = repeats
       
   440         next 4 = silence between repeats
       
   441         next 1 = audio setting
       
   442     */
       
   443 
       
   444     if ( aMessage.Length() < KPlayFileCmdMinLength )
       
   445         {
       
   446         User::LeaveIfError( SendErrorResponseMsg(
       
   447                                 KErrArgument, KErrorInvalidParameters ) );
       
   448         return;
       
   449         }
       
   450 
       
   451     // Parse parameter values from the message
       
   452     const TUint8* ptr = aMessage.Ptr();
       
   453     TInt pathLength = aMessage[1];
       
   454 
       
   455     if ( ( aMessage.Length() - pathLength ) !=
       
   456          ( KPlayFileCmdMinLength - 4 ) )
       
   457         {
       
   458         User::LeaveIfError( SendErrorResponseMsg(
       
   459                                 KErrArgument, KErrorInvalidParameters ) );
       
   460         return;
       
   461         }
       
   462 
       
   463     TFileName filePath;
       
   464     TInt nextOffset = ParseString( aMessage, 1, filePath );
       
   465     if ( filePath.Length() < 2 || nextOffset < 0 )
       
   466         {
       
   467         User::LeaveIfError( SendErrorResponseMsg(
       
   468                                 KErrArgument, KErrorInvalidParameters ) );
       
   469         return;
       
   470         }
       
   471     HTI_LOG_TEXT( "Full file path:" );
       
   472     HTI_LOG_DES( filePath );
       
   473     iVolume = aMessage[nextOffset];
       
   474     nextOffset++;
       
   475     HTI_LOG_FORMAT( "Volume = %d", iVolume );
       
   476     iStartPos = ParseUint32( ptr + nextOffset );
       
   477     HTI_LOG_FORMAT( "Start position = %d", iStartPos );
       
   478     nextOffset += 4;
       
   479     iEndPos = ParseUint32( ptr + nextOffset );
       
   480     HTI_LOG_FORMAT( "End position = %d", iEndPos );
       
   481     nextOffset += 4;
       
   482     iRepeats = aMessage[nextOffset];
       
   483     nextOffset++;
       
   484     HTI_LOG_FORMAT( "Repeats = %d", iRepeats );
       
   485     iTrailingSilence = ParseUint32( ptr + nextOffset );
       
   486     HTI_LOG_FORMAT( "Trailing silence = %d", iTrailingSilence );
       
   487     nextOffset += 4;
       
   488     TInt audioSetting = aMessage[nextOffset];
       
   489     HTI_LOG_FORMAT( "Audio setting = %d", audioSetting );
       
   490 
       
   491     // Set audio settings
       
   492     if ( audioSetting > ERingTonePreview ) audioSetting = EDefault;
       
   493     SetAudioSettings( ( TAudioSetting ) audioSetting );
       
   494 
       
   495     // Check if file is rng ringtone, it has to be played using tone player -
       
   496     // other formats are played with audio player.
       
   497 
       
   498     TInt err = KErrNone;
       
   499     TBool isRng = EFalse;
       
   500     TRAP( err, isRng = MatchMimeTypeL( filePath, KRngMimeType ) );
       
   501 
       
   502     if ( err )
       
   503         {
       
   504         User::LeaveIfError( SendErrorResponseMsg( err, KErrorFileInitFailed ) );
       
   505         return;
       
   506         }
       
   507 
       
   508     if ( isRng )
       
   509         {
       
   510         HTI_LOG_TEXT( "File is RNG - creating tone player" );
       
   511         TRAP( err, iTonePlayer = CMdaAudioToneUtility::NewL(
       
   512                 *this, NULL, iAudioPriority, iAudioPriorityPreference ) );
       
   513         }
       
   514 
       
   515     else
       
   516         {
       
   517         HTI_LOG_TEXT( "File is not RNG - creating audio player" );
       
   518         TRAP( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL(
       
   519                 filePath, *this, iAudioPriority, iAudioPriorityPreference ) );
       
   520         // MapcInitComplete callback function will be called
       
   521         }
       
   522 
       
   523     if ( err )
       
   524         {
       
   525         delete iAudioPlayer;
       
   526         iAudioPlayer = NULL;
       
   527         delete iTonePlayer;
       
   528         iTonePlayer = NULL;
       
   529         User::LeaveIfError( SendErrorResponseMsg(
       
   530                                 err, KErrorFileInitFailed ) );
       
   531         }
       
   532 
       
   533     if ( iTonePlayer )
       
   534         {
       
   535         iTonePlayer->PrepareToPlayFileSequence( filePath );
       
   536         // MatoPrepareComplete callback function will be called
       
   537         }
       
   538 
       
   539     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayFileCmdL" );
       
   540     }
       
   541 
       
   542 
       
   543 // -----------------------------------------------------------------------------
       
   544 // CHtiAudioServicePlugin::HandlePlayToneCmdL()
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 void CHtiAudioServicePlugin::HandlePlayToneCmdL( const TDesC8& aMessage )
       
   548     {
       
   549     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayToneCmdL" );
       
   550 
       
   551     if ( iIsPlaying )
       
   552         {
       
   553         User::LeaveIfError( SendErrorResponseMsg(
       
   554                                 KErrInUse, KErrorBusyPlaying ) );
       
   555         return;
       
   556         }
       
   557 
       
   558     iPlayCommandId = ECmdPlayTone;
       
   559 
       
   560     /*
       
   561     Message bytes:
       
   562             0  = command code
       
   563         1 - 2  = frequency value
       
   564         3 - 6  = duration value
       
   565             7  = volume value
       
   566             8  = repeat value
       
   567         9 - 12 = silence between repeats
       
   568     */
       
   569 
       
   570     if ( aMessage.Length() != KPlayToneCmdLength )
       
   571         {
       
   572         User::LeaveIfError( SendErrorResponseMsg(
       
   573                                 KErrArgument, KErrorInvalidParameters ) );
       
   574         return;
       
   575         }
       
   576 
       
   577     // Parse parameter values from the message
       
   578     const TUint8* ptr = aMessage.Ptr();
       
   579     TInt frequency = ParseUint16( ptr + 1 );
       
   580     HTI_LOG_FORMAT( "Freq = %d", frequency );
       
   581     TUint duration = ParseUint32( ptr + 3 );
       
   582     HTI_LOG_FORMAT( "Duration = %d", duration );
       
   583     iVolume = aMessage[7];
       
   584     HTI_LOG_FORMAT( "Volume = %d", iVolume );
       
   585     iRepeats = aMessage[8];
       
   586     HTI_LOG_FORMAT( "Repeats = %d", iRepeats );
       
   587     iTrailingSilence = ParseUint32( ptr + 9 );
       
   588     HTI_LOG_FORMAT( "Silence = %d", iTrailingSilence );
       
   589 
       
   590     TRAPD( err, iTonePlayer = CMdaAudioToneUtility::NewL( *this ) );
       
   591 
       
   592     if ( err )
       
   593         {
       
   594         delete iTonePlayer;
       
   595         iTonePlayer = NULL;
       
   596         User::LeaveIfError( SendErrorResponseMsg(
       
   597                                 err, KErrorToneInitFailed ) );
       
   598         }
       
   599 
       
   600     iTonePlayer->PrepareToPlayTone( frequency,
       
   601                               TTimeIntervalMicroSeconds( duration ) );
       
   602     // MatoPrepareComplete callback function will be called when ready to play
       
   603     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayToneCmdL" );
       
   604     }
       
   605 
       
   606 
       
   607 // -----------------------------------------------------------------------------
       
   608 // CHtiAudioServicePlugin::HandlePlayDtmfCmdL()
       
   609 // -----------------------------------------------------------------------------
       
   610 //
       
   611 void CHtiAudioServicePlugin::HandlePlayDtmfCmdL( const TDesC8& aMessage )
       
   612     {
       
   613     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandlePlayDtmfCmdL" );
       
   614 
       
   615     if ( iIsPlaying )
       
   616         {
       
   617         User::LeaveIfError( SendErrorResponseMsg(
       
   618                                 KErrInUse, KErrorBusyPlaying ) );
       
   619         return;
       
   620         }
       
   621 
       
   622     iPlayCommandId = ECmdPlayDtmf;
       
   623 
       
   624     /*
       
   625     Message bytes:
       
   626              0 = command code
       
   627              1 = DTMF string length
       
   628          2 - n = dtmf string
       
   629         next 4 = tone length
       
   630         next 4 = tone gap length
       
   631         next 1 = volume
       
   632         next 1 = repeats
       
   633         next 4 = silence between repeats
       
   634     */
       
   635 
       
   636     if ( aMessage.Length() < KPlayDtmfCmdMinLength )
       
   637         {
       
   638         User::LeaveIfError( SendErrorResponseMsg(
       
   639                                 KErrArgument, KErrorInvalidParameters ) );
       
   640         return;
       
   641         }
       
   642 
       
   643     // Parse parameter values from the message
       
   644     const TUint8* ptr = aMessage.Ptr();
       
   645     TInt stringLength = aMessage[1];
       
   646 
       
   647     if ( ( aMessage.Length() - stringLength ) !=
       
   648          ( KPlayDtmfCmdMinLength - 1 ) )
       
   649         {
       
   650         User::LeaveIfError( SendErrorResponseMsg(
       
   651                                 KErrArgument, KErrorInvalidParameters ) );
       
   652         return;
       
   653         }
       
   654 
       
   655     TBuf<255> dtmfString;
       
   656     TInt nextOffset = ParseString( aMessage, 1, dtmfString );
       
   657     if ( dtmfString.Length() < 1 || nextOffset < 0 )
       
   658         {
       
   659         User::LeaveIfError( SendErrorResponseMsg(
       
   660                                 KErrArgument, KErrorInvalidParameters ) );
       
   661         return;
       
   662         }
       
   663     HTI_LOG_TEXT( "DTMF string:" );
       
   664     HTI_LOG_DES( dtmfString );
       
   665     iDtmfLength = ParseUint32( ptr + nextOffset );
       
   666     nextOffset += 4;
       
   667     HTI_LOG_FORMAT( "DTMF length = %d", iDtmfLength );
       
   668     iDtmfGapLength = ParseUint32( ptr + nextOffset );
       
   669     nextOffset += 4;
       
   670     HTI_LOG_FORMAT( "DTMF gap length = %d", iDtmfGapLength );
       
   671     iVolume = aMessage[nextOffset];
       
   672     nextOffset++;
       
   673     HTI_LOG_FORMAT( "Volume = %d", iVolume );
       
   674     iRepeats = aMessage[nextOffset];
       
   675     nextOffset++;
       
   676     HTI_LOG_FORMAT( "Repeats = %d", iRepeats );
       
   677     iTrailingSilence = ParseUint32( ptr + nextOffset );
       
   678     HTI_LOG_FORMAT( "Trailing silence = %d", iTrailingSilence );
       
   679 
       
   680     SetAudioSettings( EDtmfString );
       
   681 
       
   682     TRAPD( err, iTonePlayer = CMdaAudioToneUtility::NewL(
       
   683             *this, NULL, iAudioPriority, iAudioPriorityPreference ) );
       
   684 
       
   685     if ( err )
       
   686         {
       
   687         delete iTonePlayer;
       
   688         iTonePlayer = NULL;
       
   689         User::LeaveIfError( SendErrorResponseMsg( err, KErrorToneInitFailed ) );
       
   690         }
       
   691 
       
   692     iTonePlayer->PrepareToPlayDTMFString( dtmfString );
       
   693     // MatoPrepareComplete callback function will be called when ready to play
       
   694     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandlePlayDtmfCmdL" );
       
   695     }
       
   696 
       
   697 
       
   698 // -----------------------------------------------------------------------------
       
   699 // CHtiAudioServicePlugin::HandleStopCmdL()
       
   700 // -----------------------------------------------------------------------------
       
   701 //
       
   702 void CHtiAudioServicePlugin::HandleStopCmdL( const TDesC8& aMessage )
       
   703     {
       
   704     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleStopCmdL" );
       
   705 
       
   706     if ( aMessage.Length() != KStopCmdLength )
       
   707         {
       
   708         User::LeaveIfError( SendErrorResponseMsg(
       
   709                                 KErrArgument, KErrorInvalidParameters ) );
       
   710         return;
       
   711         }
       
   712 
       
   713     if ( !iIsPlaying )
       
   714         {
       
   715         HTI_LOG_TEXT( "Not playing - nothing to stop" );
       
   716         // Just send "OK" reply if nothing is currently playing
       
   717         User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) );
       
   718         }
       
   719 
       
   720     else
       
   721         {
       
   722         if ( iAudioPlayer )
       
   723             {
       
   724             HTI_LOG_TEXT( "Stopping audio player" );
       
   725             iAudioPlayer->Stop();
       
   726             iIsPlaying = EFalse;
       
   727             delete iAudioPlayer;
       
   728             iAudioPlayer = NULL;
       
   729             // According to documentation should call MapcPlayComplete callback
       
   730             // method but it doesn't, so sending reply here.
       
   731             User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) );
       
   732             }
       
   733 
       
   734         else if ( iTonePlayer )
       
   735             {
       
   736             HTI_LOG_TEXT( "Stopping tone player" );
       
   737             iTonePlayer->CancelPlay();
       
   738             iIsPlaying = EFalse;
       
   739             delete iTonePlayer;
       
   740             iTonePlayer = NULL;
       
   741             // Callback method MatoPlayComplete is not called -
       
   742             // sending reply here.
       
   743             User::LeaveIfError( SendResponseMsg( _L8( "OK" ) ) );
       
   744             }
       
   745         }
       
   746     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleStopCmdL" );
       
   747     }
       
   748 
       
   749 
       
   750 // -----------------------------------------------------------------------------
       
   751 // CHtiAudioServicePlugin::HandleGetDurationCmdL()
       
   752 // -----------------------------------------------------------------------------
       
   753 //
       
   754 void CHtiAudioServicePlugin::HandleGetDurationCmdL( const TDesC8& aMessage )
       
   755     {
       
   756     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleGetDurationCmdL" );
       
   757 
       
   758     if ( iIsPlaying )
       
   759         {
       
   760          // If currently playing, no parameters allowed. Returns the duration
       
   761          // of currently playing sound.
       
   762         if ( aMessage.Length() != 1 )
       
   763             {
       
   764             User::LeaveIfError( SendErrorResponseMsg(
       
   765                                     KErrInUse, KErrorBusyPlaying ) );
       
   766             return;
       
   767             }
       
   768 
       
   769         if ( iAudioPlayer )
       
   770             {
       
   771             TTimeIntervalMicroSeconds durationValue =
       
   772                                 iAudioPlayer->Duration();
       
   773 
       
   774             if ( I64HIGH( durationValue.Int64() ) > 0 )
       
   775                 {
       
   776                 User::LeaveIfError( SendErrorResponseMsg(
       
   777                                         KErrOverflow, KErrorDurationFailed ) );
       
   778                 return;
       
   779                 }
       
   780             else
       
   781                 {
       
   782                 TUint duration = I64LOW( durationValue.Int64() );
       
   783                 TBuf8<KTUintSize> durationBuf;
       
   784                 durationBuf.Append( (TUint8*)(&duration), KTUintSize );
       
   785                 User::LeaveIfError( SendResponseMsg( durationBuf ) );
       
   786                 return;
       
   787                 }
       
   788             }
       
   789 
       
   790         else  // Duration supported only for audio player
       
   791             {
       
   792             User::LeaveIfError( SendErrorResponseMsg(
       
   793                                     KErrNotSupported, KErrorDurationFailed ) );
       
   794             return;
       
   795             }
       
   796         }
       
   797 
       
   798     /* Command must have file path parameter if not currently playing.
       
   799     Message bytes:
       
   800              0 = command code
       
   801              1 = path length
       
   802          2 - n = full path to file
       
   803     */
       
   804 
       
   805     if ( aMessage.Length() < KDurationCmdMinLength )
       
   806         {
       
   807         User::LeaveIfError( SendErrorResponseMsg(
       
   808                                 KErrArgument, KErrorInvalidParameters ) );
       
   809         return;
       
   810         }
       
   811 
       
   812     TInt pathLength = aMessage[1];
       
   813     if ( ( aMessage.Length() - pathLength ) !=
       
   814          ( KDurationCmdMinLength - 4 ) )
       
   815         {
       
   816         User::LeaveIfError( SendErrorResponseMsg(
       
   817                                 KErrArgument, KErrorInvalidParameters ) );
       
   818         return;
       
   819         }
       
   820 
       
   821     // Parse parameter values from the message
       
   822     TFileName filePath;
       
   823     TInt nextOffset = ParseString( aMessage, 1, filePath );
       
   824     if ( filePath.Length() < 2 || nextOffset < 0 )
       
   825         {
       
   826         User::LeaveIfError( SendErrorResponseMsg(
       
   827                                 KErrArgument, KErrorInvalidParameters ) );
       
   828         return;
       
   829         }
       
   830     HTI_LOG_TEXT( "Full file path:" );
       
   831     HTI_LOG_DES( filePath );
       
   832 
       
   833     TRAPD( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL(
       
   834                                                         filePath, *this ) );
       
   835     if ( err )
       
   836         {
       
   837         delete iAudioPlayer;
       
   838         iAudioPlayer = NULL;
       
   839         User::LeaveIfError( SendErrorResponseMsg( err, KErrorDurationFailed ) );
       
   840         }
       
   841 
       
   842     // MapcInitComplete callback function will be called
       
   843     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleGetDurationCmdL" );
       
   844     }
       
   845 
       
   846 
       
   847 // -----------------------------------------------------------------------------
       
   848 // CHtiAudioServicePlugin::HandleGetMaxVolCmdL()
       
   849 // -----------------------------------------------------------------------------
       
   850 //
       
   851 void CHtiAudioServicePlugin::HandleGetMaxVolCmdL( const TDesC8& aMessage )
       
   852     {
       
   853     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleGetMaxVolCmdL" );
       
   854 
       
   855     if ( iIsPlaying )
       
   856         {
       
   857          // If currently playing, no parameters allowed. Returns the max volume
       
   858          // of currently playing sound.
       
   859         if ( aMessage.Length() != 1 )
       
   860             {
       
   861             User::LeaveIfError( SendErrorResponseMsg(
       
   862                                     KErrInUse, KErrorBusyPlaying ) );
       
   863             return;
       
   864             }
       
   865 
       
   866         TInt maxVol = -1;
       
   867 
       
   868         if ( iAudioPlayer )
       
   869             {
       
   870             maxVol = iAudioPlayer->MaxVolume();
       
   871             }
       
   872 
       
   873         else if ( iTonePlayer )
       
   874             {
       
   875             maxVol = iTonePlayer->MaxVolume();
       
   876             }
       
   877 
       
   878         HTI_LOG_FORMAT( "Max volume = %d", maxVol );
       
   879 
       
   880         if ( maxVol < 0 )
       
   881             {
       
   882             // Should not happen
       
   883             User::LeaveIfError( SendErrorResponseMsg(
       
   884                                     KErrGeneral, KErrorMaxVolFailed ) );
       
   885             return;
       
   886             }
       
   887 
       
   888         if ( maxVol > 255 ) maxVol = 255;
       
   889         TBuf8<1> maxVolBuf;
       
   890         maxVolBuf.Append( maxVol );
       
   891         User::LeaveIfError( SendResponseMsg( maxVolBuf ) );
       
   892         return;
       
   893         }
       
   894 
       
   895     /*
       
   896     Message bytes:
       
   897              0 = command code
       
   898              1 = path length
       
   899          2 - n = full path to file
       
   900     */
       
   901 
       
   902     if ( aMessage.Length() < KMaxVolCmdMinLength )
       
   903         {
       
   904         User::LeaveIfError( SendErrorResponseMsg(
       
   905                                 KErrArgument, KErrorInvalidParameters ) );
       
   906         return;
       
   907         }
       
   908 
       
   909     TInt pathLength = aMessage[1];
       
   910     if ( ( aMessage.Length() - pathLength ) != ( KMaxVolCmdMinLength - 4 ) )
       
   911         {
       
   912         User::LeaveIfError( SendErrorResponseMsg(
       
   913                                 KErrArgument, KErrorInvalidParameters ) );
       
   914         return;
       
   915         }
       
   916 
       
   917     // Parse parameter values from the message
       
   918     TFileName filePath;
       
   919     TInt nextOffset = ParseString( aMessage, 1, filePath );
       
   920     if ( filePath.Length() < 2 || nextOffset < 0 )
       
   921         {
       
   922         User::LeaveIfError( SendErrorResponseMsg(
       
   923                                 KErrArgument, KErrorInvalidParameters ) );
       
   924         return;
       
   925         }
       
   926     HTI_LOG_TEXT( "Full file path:" );
       
   927     HTI_LOG_DES( filePath );
       
   928 
       
   929     TInt err = KErrNone;
       
   930     TBool isRng = EFalse;
       
   931     TRAP( err, isRng = MatchMimeTypeL( filePath, KRngMimeType ) );
       
   932 
       
   933     if ( err )
       
   934         {
       
   935         User::LeaveIfError( SendErrorResponseMsg( err, KErrorMaxVolFailed ) );
       
   936         return;
       
   937         }
       
   938 
       
   939     if ( isRng )
       
   940         {
       
   941         HTI_LOG_TEXT( "File is RNG - creating tone player" );
       
   942         TRAP( err, iTonePlayer = CMdaAudioToneUtility::NewL( *this ) );
       
   943         }
       
   944 
       
   945     else
       
   946         {
       
   947         HTI_LOG_TEXT( "File is not RNG - creating audio player" );
       
   948         TRAP( err, iAudioPlayer = CMdaAudioPlayerUtility::NewFilePlayerL(
       
   949                                                         filePath, *this ) );
       
   950         // MapcInitComplete callback function will be called
       
   951         }
       
   952 
       
   953     if ( err )
       
   954         {
       
   955         delete iAudioPlayer;
       
   956         iAudioPlayer = NULL;
       
   957         delete iTonePlayer;
       
   958         iTonePlayer = NULL;
       
   959         User::LeaveIfError( SendErrorResponseMsg( err, KErrorMaxVolFailed ) );
       
   960         }
       
   961 
       
   962     if ( iTonePlayer )
       
   963         {
       
   964         iTonePlayer->PrepareToPlayFileSequence( filePath );
       
   965         // MatoPrepareComplete callback function will be called
       
   966         }
       
   967 
       
   968     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleGetMaxVolCmdL" );
       
   969     }
       
   970 
       
   971 
       
   972 // -----------------------------------------------------------------------------
       
   973 // CHtiAudioServicePlugin::HandleSetVolCmdL()
       
   974 // -----------------------------------------------------------------------------
       
   975 //
       
   976 void CHtiAudioServicePlugin::HandleSetVolCmdL( const TDesC8& aMessage )
       
   977     {
       
   978     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::HandleSetVolCmdL" );
       
   979 
       
   980     if ( aMessage.Length() != KSetVolCmdLength )
       
   981         {
       
   982         User::LeaveIfError( SendErrorResponseMsg( KErrArgument,
       
   983                                                   KErrorInvalidParameters ) );
       
   984         }
       
   985 
       
   986     if ( !iIsPlaying )
       
   987         {
       
   988         HTI_LOG_TEXT( "Nothing playing - not setting volume" );
       
   989         User::LeaveIfError( SendErrorResponseMsg(
       
   990                                 KErrNotReady, KErrorNothingPlaying ) );
       
   991         }
       
   992 
       
   993     else
       
   994         {
       
   995         TInt volume = aMessage[1]; // [0] = command code, [1] = volume value
       
   996         HTI_LOG_FORMAT( "requested volume = %d", volume );
       
   997 
       
   998         if ( iAudioPlayer )
       
   999             {
       
  1000             HTI_LOG_TEXT( "Setting audio player volume" );
       
  1001             TInt maxVol = iAudioPlayer->MaxVolume();
       
  1002             HTI_LOG_FORMAT( "max volume = %d", maxVol );
       
  1003             if ( volume > maxVol ) volume = maxVol;
       
  1004             iAudioPlayer->SetVolume( volume );
       
  1005             TBuf8<1> volBuf;
       
  1006             volBuf.Append( volume );
       
  1007             User::LeaveIfError( SendResponseMsg( volBuf ) );
       
  1008             }
       
  1009         else if ( iTonePlayer )
       
  1010             {
       
  1011             HTI_LOG_TEXT( "Setting tone player volume" );
       
  1012             TInt maxVol = iTonePlayer->MaxVolume();
       
  1013             HTI_LOG_FORMAT( "max volume = %d", maxVol );
       
  1014             if ( volume > maxVol ) volume = maxVol;
       
  1015             iTonePlayer->SetVolume( volume );
       
  1016             TBuf8<1> volBuf;
       
  1017             volBuf.Append( volume );
       
  1018             User::LeaveIfError( SendResponseMsg( volBuf ) );
       
  1019             }
       
  1020         }
       
  1021     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::HandleSetVolCmdL" );
       
  1022     }
       
  1023 
       
  1024 
       
  1025 // -----------------------------------------------------------------------------
       
  1026 // CHtiAudioServicePlugin::MatoPrepareComplete()
       
  1027 // Tone player prepare complete
       
  1028 // -----------------------------------------------------------------------------
       
  1029 //
       
  1030 void CHtiAudioServicePlugin::MatoPrepareComplete( TInt aError )
       
  1031     {
       
  1032     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatoPrepareComplete" );
       
  1033 
       
  1034     if ( iCommandId == ECmdGetMaxVol )
       
  1035         {
       
  1036         if ( aError )
       
  1037             {
       
  1038             SendErrorResponseMsg( aError, KErrorMaxVolFailed );
       
  1039             }
       
  1040 
       
  1041         else
       
  1042             {
       
  1043             TInt maxVol = iTonePlayer->MaxVolume();
       
  1044             HTI_LOG_FORMAT( "Max volume = %d", maxVol );
       
  1045             if ( maxVol > 255 ) maxVol = 255;
       
  1046             TBuf8<1> maxVolBuf;
       
  1047             maxVolBuf.Append( maxVol );
       
  1048             SendResponseMsg( maxVolBuf );
       
  1049             }
       
  1050 
       
  1051         delete iTonePlayer;
       
  1052         iTonePlayer = NULL;
       
  1053         return;
       
  1054         }
       
  1055 
       
  1056     if ( aError )
       
  1057         {
       
  1058         SendErrorResponseMsg( aError, KErrorToneInitFailed );
       
  1059         delete iTonePlayer;
       
  1060         iTonePlayer = NULL;
       
  1061         }
       
  1062 
       
  1063     else
       
  1064         {
       
  1065         if ( iCommandId == ECmdPlayDtmf )
       
  1066             {
       
  1067             iTonePlayer->SetDTMFLengths(
       
  1068                 TTimeIntervalMicroSeconds32( iDtmfLength ),
       
  1069                 TTimeIntervalMicroSeconds32( iDtmfGapLength ),
       
  1070                 TTimeIntervalMicroSeconds32( 0 ) );
       
  1071             }
       
  1072 
       
  1073         if ( iVolume > iTonePlayer->MaxVolume() )
       
  1074             {
       
  1075             iVolume = iTonePlayer->MaxVolume();
       
  1076             }
       
  1077 
       
  1078         iTonePlayer->SetVolume( iVolume );
       
  1079         iTonePlayer->SetRepeats( iRepeats + 1,
       
  1080                         TTimeIntervalMicroSeconds( iTrailingSilence ) );
       
  1081         iIsPlaying = ETrue;
       
  1082         iTonePlayer->Play();
       
  1083         iIsBusy = EFalse;
       
  1084         // MatoPlayComplete callback function will be called when playing ends.
       
  1085         }
       
  1086 
       
  1087     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatoPrepareComplete" );
       
  1088     }
       
  1089 
       
  1090 
       
  1091 // -----------------------------------------------------------------------------
       
  1092 // CHtiAudioServicePlugin::MatoPlayComplete()
       
  1093 // Tone play complete
       
  1094 // -----------------------------------------------------------------------------
       
  1095 //
       
  1096 void CHtiAudioServicePlugin::MatoPlayComplete( TInt aError )
       
  1097     {
       
  1098     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatoPlayComplete" );
       
  1099 
       
  1100     iIsPlaying = EFalse;
       
  1101     iIsBusy = ETrue; // Busy dispatching the play complete message
       
  1102 
       
  1103     if ( aError )
       
  1104         {
       
  1105         SendErrorResponseMsg( aError, KErrorTonePlayFailed, iPlayCommandId );
       
  1106         }
       
  1107 
       
  1108     else
       
  1109         {
       
  1110         SendResponseMsg( _L8( "OK" ), iPlayCommandId );
       
  1111         }
       
  1112 
       
  1113     delete iTonePlayer;
       
  1114     iTonePlayer = NULL;
       
  1115 
       
  1116     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatoPlayComplete" );
       
  1117     }
       
  1118 
       
  1119 
       
  1120 // -----------------------------------------------------------------------------
       
  1121 // CHtiAudioServicePlugin::MapcInitComplete()
       
  1122 // Audio player init complete
       
  1123 // -----------------------------------------------------------------------------
       
  1124 //
       
  1125 void CHtiAudioServicePlugin::MapcInitComplete( TInt aError,
       
  1126                                  const TTimeIntervalMicroSeconds& aDuration )
       
  1127     {
       
  1128     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MapcInitComplete" );
       
  1129 
       
  1130     if ( iCommandId == ECmdPlayFile )
       
  1131         {
       
  1132         if ( aError )
       
  1133             {
       
  1134             SendErrorResponseMsg( aError, KErrorFileInitFailed );
       
  1135             delete iAudioPlayer;
       
  1136             iAudioPlayer = NULL;
       
  1137             }
       
  1138 
       
  1139         else
       
  1140             {
       
  1141             if ( iEndPos < iStartPos ||
       
  1142                         TTimeIntervalMicroSeconds( iStartPos ) > aDuration )
       
  1143                 {
       
  1144                 SendErrorResponseMsg( KErrArgument, KErrorPosition );
       
  1145                 delete iAudioPlayer;
       
  1146                 iAudioPlayer = NULL;
       
  1147                 return;
       
  1148                 }
       
  1149 
       
  1150             if ( iEndPos > 0 )
       
  1151                 {
       
  1152                 iAudioPlayer->SetPlayWindow(
       
  1153                     TTimeIntervalMicroSeconds( iStartPos ),
       
  1154                     TTimeIntervalMicroSeconds( iEndPos ) );
       
  1155                 }
       
  1156 
       
  1157             HTI_LOG_FORMAT( "Max volume = %d", iAudioPlayer->MaxVolume() );
       
  1158             HTI_LOG_FORMAT( "Setting volume = %d", iVolume );
       
  1159             if ( iVolume > iAudioPlayer->MaxVolume() )
       
  1160                 {
       
  1161                 iVolume = iAudioPlayer->MaxVolume();
       
  1162                 }
       
  1163 
       
  1164             iAudioPlayer->SetVolume( iVolume );
       
  1165             iAudioPlayer->SetRepeats( iRepeats,
       
  1166                             TTimeIntervalMicroSeconds( iTrailingSilence ) );
       
  1167             iIsPlaying = ETrue;
       
  1168             iAudioPlayer->Play();
       
  1169 
       
  1170             // Have to do this after play command because
       
  1171             // volume setting before play seems to have no effect.
       
  1172             iAudioPlayer->SetVolume( 0 );
       
  1173             iAudioPlayer->SetVolume( iVolume );
       
  1174 
       
  1175             iIsBusy = EFalse;
       
  1176             // MapcPlayComplete callback function is called when playing ends
       
  1177             }
       
  1178         }
       
  1179 
       
  1180     else if ( iCommandId == ECmdGetDuration )
       
  1181         {
       
  1182         if ( aError )
       
  1183             {
       
  1184             SendErrorResponseMsg( aError, KErrorDurationFailed );
       
  1185             }
       
  1186 
       
  1187         else
       
  1188             {
       
  1189             if ( I64HIGH( aDuration.Int64() ) > 0 )
       
  1190                 {
       
  1191                 SendErrorResponseMsg( KErrOverflow, KErrorDurationFailed );
       
  1192                 }
       
  1193             else
       
  1194                 {
       
  1195                 TUint duration = I64LOW( aDuration.Int64() );
       
  1196                 TBuf8<KTUintSize> durationBuf;
       
  1197                 durationBuf.Append( (TUint8*)(&duration), KTUintSize );
       
  1198                 SendResponseMsg( durationBuf );
       
  1199                 }
       
  1200             }
       
  1201         delete iAudioPlayer;
       
  1202         iAudioPlayer = NULL;
       
  1203         }
       
  1204 
       
  1205     else if ( iCommandId == ECmdGetMaxVol )
       
  1206         {
       
  1207         if ( aError )
       
  1208             {
       
  1209             SendErrorResponseMsg( aError, KErrorMaxVolFailed );
       
  1210             }
       
  1211 
       
  1212         else
       
  1213             {
       
  1214             TInt maxVol = iAudioPlayer->MaxVolume();
       
  1215             HTI_LOG_FORMAT( "Max volume = %d", maxVol );
       
  1216             if ( maxVol > 255 ) maxVol = 255;
       
  1217             TBuf8<1> maxVolBuf;
       
  1218             maxVolBuf.Append( maxVol );
       
  1219             SendResponseMsg( maxVolBuf );
       
  1220             }
       
  1221         delete iAudioPlayer;
       
  1222         iAudioPlayer = NULL;
       
  1223         }
       
  1224 
       
  1225     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MapcInitComplete" );
       
  1226     }
       
  1227 
       
  1228 
       
  1229 // -----------------------------------------------------------------------------
       
  1230 // CHtiAudioServicePlugin::MapcPlayComplete()
       
  1231 // Audio play complete
       
  1232 // -----------------------------------------------------------------------------
       
  1233 //
       
  1234 void CHtiAudioServicePlugin::MapcPlayComplete( TInt aError )
       
  1235     {
       
  1236     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MapcPlayComplete" );
       
  1237 
       
  1238     iIsPlaying = EFalse;
       
  1239     iIsBusy = ETrue; // Busy dispatching the play complete message
       
  1240 
       
  1241     if ( aError )
       
  1242         {
       
  1243         SendErrorResponseMsg( aError, KErrorFilePlayFailed, ECmdPlayFile );
       
  1244         }
       
  1245 
       
  1246     else
       
  1247         {
       
  1248         SendResponseMsg( _L8( "OK" ), iPlayCommandId );
       
  1249         }
       
  1250 
       
  1251     delete iAudioPlayer;
       
  1252     iAudioPlayer = NULL;
       
  1253 
       
  1254     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MapcPlayComplete" );
       
  1255     }
       
  1256 
       
  1257 
       
  1258 // -----------------------------------------------------------------------------
       
  1259 // CHtiAudioServicePlugin::NotifyMemoryChange
       
  1260 // Called when HTI Framework has dispatched a message forward and the amount
       
  1261 // of free memory in the message queue has changed.
       
  1262 // -----------------------------------------------------------------------------
       
  1263 //
       
  1264 void CHtiAudioServicePlugin::NotifyMemoryChange( TInt aAvailableMemory )
       
  1265     {
       
  1266     if ( iIsBusy && iMessage )
       
  1267         {
       
  1268         if ( aAvailableMemory >= iMessage->Size() )
       
  1269             {
       
  1270             if ( iErrorCode == 0 )
       
  1271                 {
       
  1272                 TInt err = iDispatcher->DispatchOutgoingMessage(
       
  1273                     iMessage, KAudioServiceUid );
       
  1274 
       
  1275                 if ( err == KErrNone )
       
  1276                     {
       
  1277                     // Ownership of iMessage has been transferred
       
  1278                     iMessage = NULL;
       
  1279                     iIsBusy = EFalse;
       
  1280                     iDispatcher->RemoveMemoryObserver( this );
       
  1281                     }
       
  1282 
       
  1283                 else if ( err == KErrNoMemory )
       
  1284                     {
       
  1285                     // Keep retrying.
       
  1286                     }
       
  1287 
       
  1288                 else // Give up on sending
       
  1289                     {
       
  1290                     delete iMessage;
       
  1291                     iMessage = NULL;
       
  1292                     iIsBusy = EFalse;
       
  1293                     iDispatcher->RemoveMemoryObserver( this );
       
  1294                     }
       
  1295                 }
       
  1296 
       
  1297             else
       
  1298                 {
       
  1299                 TInt err = iDispatcher->DispatchOutgoingErrorMessage(
       
  1300                     iErrorCode, *iMessage, KAudioServiceUid );
       
  1301 
       
  1302                 // If it was success or some other error than KErrNoMemory
       
  1303                 // we are done sending or trying to send this message.
       
  1304                 if ( err != KErrNoMemory )
       
  1305                     {
       
  1306                     delete iMessage;
       
  1307                     iMessage = NULL;
       
  1308                     iIsBusy = EFalse;
       
  1309                     iDispatcher->RemoveMemoryObserver( this );
       
  1310                     }
       
  1311 
       
  1312                 else
       
  1313                     {
       
  1314                     // Keep retrying.
       
  1315                     }
       
  1316                 }
       
  1317             }
       
  1318         }
       
  1319     }
       
  1320 
       
  1321 
       
  1322 // -----------------------------------------------------------------------------
       
  1323 // CHtiAudioServicePlugin::IsBusy
       
  1324 // -----------------------------------------------------------------------------
       
  1325 //
       
  1326 TBool CHtiAudioServicePlugin::IsBusy()
       
  1327     {
       
  1328     return iIsBusy;
       
  1329     }
       
  1330 
       
  1331 
       
  1332 // -----------------------------------------------------------------------------
       
  1333 // CHtiAudioServicePlugin::SendResponseMsg
       
  1334 // Sends a message out to the message dispatcher.
       
  1335 // -----------------------------------------------------------------------------
       
  1336 //
       
  1337 TInt CHtiAudioServicePlugin::SendResponseMsg( const TDesC8& aMsg,
       
  1338                                               const TUint8 aCommandId )
       
  1339     {
       
  1340     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SendResponseMsg" );
       
  1341 
       
  1342     iErrorCode = 0;
       
  1343 
       
  1344     if ( iDispatcher == NULL )
       
  1345         {
       
  1346         iIsBusy = EFalse;
       
  1347         return KErrGeneral;
       
  1348         }
       
  1349 
       
  1350     iDispatcher->RemoveMemoryObserver( this );
       
  1351 
       
  1352     delete iMessage;
       
  1353     iMessage = NULL;
       
  1354     iMessage = HBufC8::New( aMsg.Length() + 1 );
       
  1355 
       
  1356     if ( iMessage == NULL )
       
  1357         {
       
  1358         iIsBusy = EFalse;
       
  1359         return KErrNoMemory;
       
  1360         }
       
  1361 
       
  1362     TPtr8 ptr8 = iMessage->Des();
       
  1363     if ( aCommandId != 0 )
       
  1364         {
       
  1365         ptr8.Append( aCommandId );
       
  1366         }
       
  1367     else
       
  1368         {
       
  1369         ptr8.Append( iCommandId );
       
  1370         }
       
  1371 
       
  1372     ptr8.Append( aMsg );
       
  1373 
       
  1374     TInt err = KErrNone;
       
  1375 
       
  1376     err = iDispatcher->DispatchOutgoingMessage( iMessage, KAudioServiceUid );
       
  1377 
       
  1378     if ( err == KErrNoMemory )
       
  1379         {
       
  1380         HTI_LOG_TEXT( "Message queue memory full - waiting" );
       
  1381         iIsBusy = ETrue; // Should already be true, but just in case
       
  1382         iDispatcher->AddMemoryObserver( this );
       
  1383         // For the caller of this method all is OK, sending is just delayed
       
  1384         err = KErrNone;
       
  1385         }
       
  1386 
       
  1387     else if ( err == KErrNone )
       
  1388         {
       
  1389         HTI_LOG_TEXT( "Message sent to dispatcher" );
       
  1390         iMessage = NULL; // Ownership of iMessage has been transferred
       
  1391         iIsBusy = EFalse;
       
  1392         }
       
  1393 
       
  1394     else // give up on sending
       
  1395         {
       
  1396         HTI_LOG_FORMAT( "Other dispatcher error %d", err );
       
  1397         delete iMessage;
       
  1398         iMessage = NULL;
       
  1399         iIsBusy = EFalse;
       
  1400         }
       
  1401 
       
  1402     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SendResponseMsg" );
       
  1403     return err;
       
  1404     }
       
  1405 
       
  1406 
       
  1407 // -----------------------------------------------------------------------------
       
  1408 // CHtiAudioServicePlugin::SendErrorResponseMsg
       
  1409 // Sends an error message out to the message dispatcher.
       
  1410 // -----------------------------------------------------------------------------
       
  1411 //
       
  1412 TInt CHtiAudioServicePlugin::SendErrorResponseMsg( TInt aErrorCode,
       
  1413                         const TDesC8& aErrorDescription,
       
  1414                         const TUint8 aCommandId )
       
  1415     {
       
  1416     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SendErrorResponseMsg" );
       
  1417 
       
  1418     iErrorCode = aErrorCode;
       
  1419 
       
  1420     if ( iDispatcher == NULL )
       
  1421         {
       
  1422         iIsBusy = EFalse;
       
  1423         return KErrGeneral;
       
  1424         }
       
  1425 
       
  1426     iDispatcher->RemoveMemoryObserver( this );
       
  1427 
       
  1428     delete iMessage;
       
  1429     iMessage = NULL;
       
  1430     iMessage = HBufC8::New( aErrorDescription.Length() + 1 );
       
  1431 
       
  1432     if ( iMessage == NULL )
       
  1433         {
       
  1434         iIsBusy = EFalse;
       
  1435         return KErrNoMemory;
       
  1436         }
       
  1437 
       
  1438     TPtr8 ptr8 = iMessage->Des();
       
  1439     if ( aCommandId != 0 )
       
  1440         {
       
  1441         ptr8.Append( aCommandId );
       
  1442         }
       
  1443     else
       
  1444         {
       
  1445         ptr8.Append( iCommandId );
       
  1446         }
       
  1447 
       
  1448     ptr8.Append( aErrorDescription );
       
  1449 
       
  1450     TInt err = KErrNone;
       
  1451 
       
  1452     err = iDispatcher->DispatchOutgoingErrorMessage(
       
  1453         aErrorCode, *iMessage, KAudioServiceUid );
       
  1454 
       
  1455     if ( err == KErrNoMemory )
       
  1456         {
       
  1457         HTI_LOG_TEXT( "Message queue memory full - waiting" );
       
  1458         iIsBusy = ETrue; // Should already be true, but just in case
       
  1459         iDispatcher->AddMemoryObserver( this );
       
  1460         // For the caller of this method all is OK, sending is just delayed
       
  1461         err = KErrNone;
       
  1462         }
       
  1463 
       
  1464     else if ( err == KErrNone )
       
  1465         {
       
  1466         HTI_LOG_TEXT( "Error message sent to dispatcher" );
       
  1467         delete iMessage;
       
  1468         iMessage = NULL;
       
  1469         iIsBusy = EFalse;
       
  1470         }
       
  1471 
       
  1472     else // give up on sending
       
  1473         {
       
  1474         HTI_LOG_FORMAT( "Other dispatcher error %d", err );
       
  1475         delete iMessage;
       
  1476         iMessage = NULL;
       
  1477         iIsBusy = EFalse;
       
  1478         }
       
  1479 
       
  1480     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SendErrorResponseMsg" );
       
  1481     return err;
       
  1482     }
       
  1483 
       
  1484 
       
  1485 // -----------------------------------------------------------------------------
       
  1486 // CHtiAudioServicePlugin::ParseString()
       
  1487 // -----------------------------------------------------------------------------
       
  1488 //
       
  1489 TInt CHtiAudioServicePlugin::ParseString( const TDesC8& aRequest,
       
  1490                                           TInt aOffset,
       
  1491                                           TDes& aResult )
       
  1492     {
       
  1493     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::ParseString" );
       
  1494 
       
  1495     // If offset outside the string return empty string
       
  1496     if ( aOffset >= aRequest.Size() )
       
  1497         {
       
  1498         return aOffset;
       
  1499         }
       
  1500 
       
  1501     TInt length = aRequest[aOffset];
       
  1502     HTI_LOG_FORMAT( "String length = %d", length );
       
  1503 
       
  1504     // If length is zero return empty string
       
  1505     if ( length < 1 )
       
  1506         {
       
  1507         return aOffset + 1;
       
  1508         }
       
  1509 
       
  1510     if ( length > aResult.MaxLength() )
       
  1511         {
       
  1512         return KErrBadDescriptor;
       
  1513         }
       
  1514 
       
  1515     TInt nextOffset = length + aOffset + 1;
       
  1516     HTI_LOG_FORMAT( "Next offset = %d", nextOffset );
       
  1517     HTI_LOG_FORMAT( "Request size = %d", aRequest.Size() );
       
  1518 
       
  1519     if ( nextOffset > aRequest.Size() )
       
  1520         {
       
  1521         return KErrArgument;
       
  1522         }
       
  1523 
       
  1524     aResult.Copy( aRequest.Mid( aOffset + 1, length ) );
       
  1525 
       
  1526     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::ParseString" );
       
  1527     return nextOffset;
       
  1528     }
       
  1529 
       
  1530 
       
  1531 // -----------------------------------------------------------------------------
       
  1532 // CHtiAudioServicePlugin::AddSubdirsRecursivelyL
       
  1533 // Scan all subdirectories from the given path and add them to the aArray.
       
  1534 // -----------------------------------------------------------------------------
       
  1535 //
       
  1536 void CHtiAudioServicePlugin::AddSubdirsRecursivelyL( const TDesC& aPath,
       
  1537                                                      CDesCArraySeg& aArray,
       
  1538                                                      RFs& aFs )
       
  1539     {
       
  1540     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::AddSubdirsRecursivelyL" );
       
  1541 
       
  1542     CDirScan* dirScan = CDirScan::NewL( aFs );
       
  1543     CleanupStack::PushL( dirScan );
       
  1544 
       
  1545     TFileName* path = new (ELeave) TFileName;
       
  1546     CleanupStack::PushL( path );
       
  1547 
       
  1548     CDir* directory = NULL;
       
  1549     TPtrC currentPath;
       
  1550 
       
  1551     dirScan->SetScanDataL( aPath, KEntryAttMatchExclusive | KEntryAttDir, ESortNone );
       
  1552     dirScan->NextL( directory );
       
  1553 
       
  1554     while ( directory )
       
  1555         {
       
  1556         CleanupStack::PushL( directory );
       
  1557         currentPath.Set( dirScan->FullPath() );
       
  1558 
       
  1559         TInt dirCount( directory->Count() );
       
  1560         for ( TInt i = 0; i < dirCount ; ++i )
       
  1561             {
       
  1562             path->Copy( currentPath );
       
  1563             path->Append( ( *directory )[ i ].iName );
       
  1564             path->Append( KBackslash );
       
  1565             aArray.AppendL( *path );
       
  1566             }
       
  1567 
       
  1568         CleanupStack::PopAndDestroy( directory );
       
  1569         directory = NULL;
       
  1570 
       
  1571         dirScan->NextL( directory );
       
  1572         }
       
  1573 
       
  1574     CleanupStack::PopAndDestroy( 2 ); // path, dirScan
       
  1575 
       
  1576     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::AddSubdirsRecursivelyL" );
       
  1577     }
       
  1578 
       
  1579 
       
  1580 // -----------------------------------------------------------------------------
       
  1581 // CHtiAudioServicePlugin::MatchMimeTypeL
       
  1582 // Check if the MIME type of the given file matches to the given pattern.
       
  1583 // -----------------------------------------------------------------------------
       
  1584 //
       
  1585 TBool CHtiAudioServicePlugin::MatchMimeTypeL( const TDesC& aFilePath,
       
  1586                       const TDesC& aMimeTypeMatchPattern )
       
  1587     {
       
  1588     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::MatchMimeTypeL" );
       
  1589 
       
  1590     RApaLsSession apaSession;
       
  1591     User::LeaveIfError( apaSession.Connect() );
       
  1592     CleanupClosePushL( apaSession );
       
  1593 
       
  1594     TUid dummyUid( KNullUid );
       
  1595     TDataType dataType;
       
  1596     User::LeaveIfError( apaSession.AppForDocument( aFilePath,
       
  1597                                                    dummyUid,
       
  1598                                                    dataType ) );
       
  1599     CleanupStack::PopAndDestroy(); // apaSession
       
  1600 
       
  1601     if ( dataType.Des().MatchF( aMimeTypeMatchPattern ) >= 0 )
       
  1602         {
       
  1603         HTI_LOG_TEXT( "Match" );
       
  1604         return ETrue;
       
  1605         }
       
  1606 
       
  1607     HTI_LOG_TEXT( "Not match" );
       
  1608     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::MatchMimeTypeL" );
       
  1609     return EFalse;
       
  1610     }
       
  1611 
       
  1612 
       
  1613 // -----------------------------------------------------------------------------
       
  1614 // CHtiAudioServicePlugin::SetAudioSettings
       
  1615 // Set the audio priority and priority preference values.
       
  1616 // -----------------------------------------------------------------------------
       
  1617 //
       
  1618 void CHtiAudioServicePlugin::SetAudioSettings( TAudioSetting aSetting )
       
  1619     {
       
  1620     HTI_LOG_FUNC_IN( "CHtiAudioServicePlugin::SetAudioSettings" );
       
  1621     HTI_LOG_FORMAT( "Setting values for audio setting %d", aSetting );
       
  1622 
       
  1623     switch ( aSetting )
       
  1624         {
       
  1625         case EGeneralMusic:
       
  1626             {
       
  1627             iAudioPriority = KAudioPriorityRealOnePlayer;
       
  1628             iAudioPriorityPreference =
       
  1629                 ( TMdaPriorityPreference ) KAudioPrefRealOneLocalPlayback;
       
  1630             break;
       
  1631             }
       
  1632 
       
  1633         case ERingTonePreview:
       
  1634             {
       
  1635             iAudioPriority = KAudioPriorityRingingTonePreview;
       
  1636             iAudioPriorityPreference =
       
  1637                 ( TMdaPriorityPreference ) KAudioPrefRingFilePreview;
       
  1638             break;
       
  1639             }
       
  1640 /*
       
  1641         case EIncomingCall:
       
  1642             {
       
  1643             iAudioPriority = KAudioPriorityPhoneCall;
       
  1644             iAudioPriorityPreference =
       
  1645                 ( TMdaPriorityPreference ) KAudioPrefIncomingCall;
       
  1646             break;
       
  1647             }
       
  1648 */
       
  1649         case EDtmfString:
       
  1650             {
       
  1651 
       
  1652             iAudioPriority = KAudioPriorityDTMFString;
       
  1653             iAudioPriorityPreference =
       
  1654                 ( TMdaPriorityPreference ) KAudioDTMFString;
       
  1655             break;
       
  1656             }
       
  1657 
       
  1658         default:
       
  1659             {
       
  1660             iAudioPriority = EMdaPriorityNormal;
       
  1661             iAudioPriorityPreference = EMdaPriorityPreferenceTimeAndQuality;
       
  1662             break;
       
  1663             }
       
  1664         }
       
  1665 
       
  1666     HTI_LOG_FUNC_OUT( "CHtiAudioServicePlugin::SetAudioSettings" );
       
  1667     }
       
  1668 
       
  1669 
       
  1670 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1671 
       
  1672 //  End of File