os/mm/mmlibs/mmfw/tsrc/mmfunittest/Actrl/TestPlugins/AudioController/CustomMmfAudioController.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <mmf/server/mmffile.h>
    17 #include "CustomMmfAudioController.h"
    18 
    19 #include <mmf/plugin/mmfcontrollerimplementationuids.hrh>
    20 #include "ActrlTestUids.h"
    21 
    22 _LIT(KTestWavFile19, "c:\\mm\\mmf\\testfiles\\actrl\\newmail.wav");
    23 
    24 /**
    25 *
    26 * NewL
    27 *
    28 */
    29 CMMFController* CCustomMmfAudioController::NewL()
    30 	{
    31     CCustomMmfAudioController* self = new(ELeave) CCustomMmfAudioController;
    32 	CleanupStack::PushL(self);
    33 	self->ConstructL();
    34 	CleanupStack::Pop( self );
    35 	
    36 	return STATIC_CAST( CMMFController*, self );
    37 	}
    38 /**
    39 *
    40 * ~CCustomMmfAudioController
    41 *
    42 */
    43 CCustomMmfAudioController::~CCustomMmfAudioController()
    44 	{
    45     delete iStoppingMessage;
    46 	}
    47 
    48 /**
    49 *
    50 * CCustomMmfAudioController
    51 *
    52 */
    53 CCustomMmfAudioController::CCustomMmfAudioController()
    54 :CMMFAudioController(), iIsTest(EFalse)
    55 	{
    56 	}
    57 
    58 /**
    59  *  PrimeL
    60  *
    61  *  If Prime fails the client should reset the controller
    62  *  becaused as noted below this code is not transactional.
    63  *
    64  */
    65 void CCustomMmfAudioController::PrimeL(TMMFMessage& aMessage)
    66 	{
    67 	PrimeL();
    68 	aMessage.Complete(KErrNone);
    69 	}
    70 void CCustomMmfAudioController::PlayL(TMMFMessage& aMessage)
    71 	{
    72 	PlayL();
    73 	aMessage.Complete(KErrNone);
    74 	}
    75 void CCustomMmfAudioController::PauseL(TMMFMessage& aMessage)
    76 	{
    77 	PauseL();
    78 	aMessage.Complete(KErrNone);
    79 	} 
    80  
    81 void CCustomMmfAudioController::PrimeL()
    82 	{
    83 	// apply heap check's here
    84 	// Note if they fail this is the end of the controller
    85     
    86 	// call the base class functionality
    87 	TRAPD( errorCode, CMMFAudioController::PrimeL());
    88 	// send an event back to the test framework with 
    89 	// the error code
    90 	TMMFEvent aEvent( KPrimeTestId, errorCode );
    91 	DoSendEventToClient(aEvent);
    92 	//[ we need to preserve the leave semantics for the caller]
    93 	User::LeaveIfError( errorCode );
    94 	}
    95 
    96 /**
    97  *
    98  *  PlayL
    99  *
   100  */
   101 void CCustomMmfAudioController::PlayL()
   102 	{
   103 // call the base class functionality
   104 	TRAPD( errorCode, CMMFAudioController::PlayL());
   105 	// send an event back to the test framework with 
   106 	// the error code
   107 	TMMFEvent aEvent( KPlayTestId, errorCode );
   108 	DoSendEventToClient(aEvent);
   109 	//[ we need to preserve the leave semantics for the caller]
   110 	User::LeaveIfError( errorCode );
   111 	}
   112 
   113 /**
   114 *
   115 * MapdSetVolumeL
   116 *
   117 */
   118 void CCustomMmfAudioController::MapdSetVolumeL(TInt aVolume)
   119 	{
   120 	//Special return code to test fix for PDEF120609, test case id MM-MMF-ACLNT-U-0277-CP
   121 	if (aVolume == -999)
   122 		{
   123 		User::Leave(-12345);
   124 		}
   125 	CMMFAudioController::MapdSetVolumeL( aVolume );
   126 	}
   127 
   128 /**
   129 *
   130 * MapdGetMaxVolumeL
   131 *
   132 */
   133 void CCustomMmfAudioController::MapdGetMaxVolumeL(TInt& aMaxVolume)
   134 	{
   135 	CMMFAudioController::MapdGetMaxVolumeL( aMaxVolume );
   136 	}
   137 
   138 /**
   139 * MapdGetVolumeL
   140 *
   141 */
   142 void CCustomMmfAudioController::MapdGetVolumeL(TInt& aVolume)
   143 	{
   144 	CMMFAudioController::MapdGetVolumeL( aVolume );
   145 	}
   146 
   147 /**
   148 * 
   149 *PauseL
   150 *
   151 */
   152 void CCustomMmfAudioController::PauseL()
   153 	{
   154 	TRAPD( errorCode,CMMFAudioController::PauseL());
   155 	//[ send pause event ]
   156 	TMMFEvent aEvent( KPauseTestId, errorCode );
   157 	DoSendEventToClient(aEvent);
   158 	//[ we need to preserve the leave semantics for the caller]
   159 	User::LeaveIfError( errorCode );
   160 	}
   161 
   162 /**
   163 * 
   164 * StopL
   165 *
   166 */
   167 void CCustomMmfAudioController::StopL()
   168 	{
   169 	TRAPD( errorCode,CMMFAudioController::StopL());
   170 	//[ send stop event ]
   171 	TMMFEvent aEvent( KStopTestId, errorCode );
   172 	DoSendEventToClient(aEvent);
   173 	//[ we need to preserve the leave semantics for the caller]
   174 	User::LeaveIfError( errorCode );
   175 	}
   176 
   177 /**
   178 *
   179 * ResetL
   180 *
   181 */
   182 void CCustomMmfAudioController::ResetL()
   183 	{
   184 	TRAPD( errorCode,CMMFAudioController::ResetL());
   185 	//[ send stop event ]
   186 	TMMFEvent aEvent( KResetTestId, errorCode );
   187 	DoSendEventToClient(aEvent);
   188 	//[ we need to preserve the leave semantics for the caller]
   189 	User::LeaveIfError( errorCode );
   190 	}
   191 
   192 /**
   193 *
   194 * RemoveDataSourceL
   195 *
   196 */
   197 void CCustomMmfAudioController::RemoveDataSourceL(MDataSource& aDataSource)
   198 	{
   199 	TRAPD( errorCode,CMMFAudioController::RemoveDataSourceL( aDataSource));
   200 	//[ send stop event ]
   201 	TMMFEvent aEvent( KRemoveDataSourceTestId, errorCode );
   202 	DoSendEventToClient(aEvent);
   203 	//[ we need to preserve the leave semantics for the caller]
   204 	User::LeaveIfError( errorCode );
   205 	}
   206 
   207 /**
   208 *
   209 * RemoveDataSinkL
   210 *
   211 */
   212 void CCustomMmfAudioController::RemoveDataSinkL(MDataSink& aDataSink)
   213 	{
   214 	TRAPD( errorCode,CMMFAudioController::RemoveDataSinkL( aDataSink));
   215 	//[ send stop event ]
   216 	TMMFEvent aEvent( KRemoveDataSinkTestId, errorCode );
   217 	DoSendEventToClient(aEvent);
   218 	//[ we need to preserve the leave semantics for the caller]
   219 	User::LeaveIfError( errorCode );
   220 	}
   221 
   222 /**
   223 *
   224 * MarcSetMaxFileSizeL
   225 *
   226 */
   227 
   228 void CCustomMmfAudioController::MarcSetMaxFileSizeL(TInt aFileSize)
   229 	{
   230 	TRAPD( errorCode,CMMFAudioController::MarcSetMaxFileSizeL( aFileSize));
   231 	//[ send stop event ]
   232 	TMMFEvent aEvent( KMarcSetMaxFileSizeId, errorCode );
   233 	DoSendEventToClient(aEvent);
   234 	//[ we need to preserve the leave semantics for the caller]
   235 	User::LeaveIfError( errorCode );
   236 	}
   237 
   238 /**
   239 *
   240 * MarcGetRecordTimeAvailableL
   241 * @param aTime
   242 *
   243 */
   244 void CCustomMmfAudioController::MarcGetRecordTimeAvailableL(TTimeIntervalMicroSeconds& aTime)
   245 	{
   246 	TRAPD( errorCode,CMMFAudioController::MarcGetRecordTimeAvailableL( aTime));
   247 	//[ send stop event ]
   248 	TMMFEvent aEvent( KMarcGetRecordTimeAvailId, errorCode );
   249 	DoSendEventToClient(aEvent);
   250 	//[ we need to preserve the leave semantics for the caller]
   251 	User::LeaveIfError( errorCode );
   252 	}
   253 
   254 
   255 /**
   256 *
   257 * CustomCommand
   258 *
   259 */
   260 void CCustomMmfAudioController::CustomCommand(TMMFMessage& aMessage)
   261 	{
   262 	//[ check if the command is for the custom plugin
   263 	// otherwise pass it on to the real audio controller ]
   264 	TRAPD(err, iStoppingMessage = CCustomMMFMessageHolder::NewL(aMessage));
   265 	if (err != KErrNone)
   266 		{
   267 		aMessage.Complete(err);
   268 		return;
   269 		}
   270 	
   271 	iIsTest = ETrue;
   272 	if( IsMemoryAllocCmd( aMessage ) )
   273 		{
   274 		//[ it is a alloc memory test command ]
   275 		// [ new algorithm adopted from M&G database ]
   276 		//
   277 		TInt errorCode = KErrNone;
   278 		TInt failCount  = 1;
   279 		TBool completed  = EFalse;
   280 		TBool badResult  = EFalse;
   281 		TBool reachedEnd = EFalse; 
   282 		
   283 		for( ; ; )
   284 			{
   285 			__UHEAP_SETFAIL(RHeap::EFailNext ,failCount);	// Leavescan will think __UHEAP_SETFAIL is a leaving function due to the macro ending in 'L'. Does not leave
   286 
   287 			//NB: Do not use __MM_HEAP_MARK macro's in this test, the cleaning up the CustomMMFAudioController
   288 			//is insufficient to remove all possible allocated memory from the framework.
   289 			//CMMFControllerProxyServer::DoStartThreadL has been updated to do heap checking for 
   290 			//the whole server thread.
   291 
   292 			//[ run a scenario of the major api 
   293 			//functions which alloc memory in the controller]
   294 			TRAP( errorCode, AllocMemoryTestL());
   295 
   296 			if( errorCode == KErrNone )
   297 				{
   298 				// [ check we have passed through all allocs in the test]
   299 				TAny* testAlloc = User::Alloc(1);
   300 				if( testAlloc == NULL )
   301 					{
   302 					reachedEnd = ETrue;
   303 					failCount -= 1; // Failcount of 1 equates to 0 successful allocs, etc.
   304 					}
   305 				else 
   306 					{
   307 					User::Free( testAlloc );
   308 					}
   309 
   310 				completed = reachedEnd || badResult;
   311 				
   312 				}
   313 			else if( errorCode != KErrNoMemory ) 
   314 				{
   315 				// [ we failed for some reason other than memory
   316 				//     allocation, so fail the test ]
   317 				completed = ETrue;
   318 				badResult = ETrue;
   319 				}
   320 			
   321 			__UHEAP_SETFAIL(RHeap::ENone ,0);
   322 			
   323 			// [ exit the loop ]
   324 			if( completed )
   325 				{
   326 				break;
   327 				}
   328 
   329 			failCount +=1;
   330 			}
   331 
   332 		//This flag is used by the audio controller to alter its behaviour
   333 		//slightly to allow these tests to work
   334 		iIsTest=EFalse;
   335 		
   336 		if(!badResult)
   337 			{
   338 			aMessage.Complete(KErrNone);
   339 			}
   340 		else
   341 			{
   342 			aMessage.Complete(errorCode);
   343 			}
   344 		}
   345 	else
   346 		{
   347 		//[ let the plugin process the message ]
   348 		CMMFAudioController::CustomCommand(aMessage);
   349 		}
   350 	}
   351 
   352 /**
   353 *
   354 * IsMemoryAllocCmd
   355 *
   356 */
   357 TBool CCustomMmfAudioController::IsMemoryAllocCmd( TMMFMessage& )
   358 	{
   359 	return ETrue;
   360 	}
   361 
   362 
   363 static void CleanupController(TAny* ptr)
   364 	{
   365 	CMMFAudioController* controller = STATIC_CAST(CMMFAudioController*, ptr);
   366 	TRAP_IGNORE(controller->CMMFAudioController::ResetL());
   367 	}
   368 
   369 
   370 /**
   371 *
   372 * AllocMemoryTest
   373 *
   374 */
   375 TInt CCustomMmfAudioController::AllocMemoryTestL()
   376 	{
   377 	TMMFFileConfig fileConfig; // audio file 
   378 
   379 	fileConfig().iPath = KTestWavFile19;
   380 
   381 	//[ lets manufacture a source and sink ]
   382 
   383 	//[Create the source]
   384 	MDataSource* source = MDataSource::NewSourceL(KUidMmfFileSource, fileConfig);
   385 	CleanupDeletePushL(source);
   386 
   387 	//[ Create the sink ]
   388 	MDataSink* sink = MDataSink::NewSinkL(KUidMmfAudioOutput, KNullDesC8);
   389 	CleanupDeletePushL(sink);
   390 
   391 	// Use a cleanup item to stop & reset the controller and so remove the data 
   392 	// sources/sinks automatically when this funtion leaves. This can be done
   393 	// before the sinks/sources are added.
   394 	TCleanupItem cleanupItem(CleanupController, this);
   395 	CleanupStack::PushL(cleanupItem);
   396 
   397 
   398 	//[ add the source ]
   399 	CMMFAudioController::AddDataSourceL(*source);
   400 	 
   401 	//[ add the sink ]
   402 	CMMFAudioController::AddDataSinkL(*sink);
   403 
   404 	//[ prime ]
   405 	CMMFAudioController::PrimeL();	 
   406 	 
   407 	//[ play ]
   408 	CMMFAudioController::PlayL();
   409 	 
   410 	//[ pause ]
   411 	CMMFAudioController::PauseL();
   412 	 
   413 	//[ play ]
   414 	CMMFAudioController::PlayL();
   415 	 
   416 	//[ stop ]
   417 	CMMFAudioController::StopL(iStoppingMessage->iMessage);
   418 	 
   419 	// [ prime ]
   420 	CMMFAudioController::PrimeL();
   421 	 
   422 	//[ reset ]	
   423 	CMMFAudioController::ResetL();
   424 
   425 	CleanupStack::PopAndDestroy(3);// source, sink, cleanupItem
   426 
   427 	return KErrNone;
   428 	}
   429 
   430 //Leaves with KErrNoMemory.
   431 CMMFController* CMemoryFailAudioController::NewL()
   432 	{
   433 	if(ETrue) //condition used to avoid any warning
   434 		{
   435 		User::Leave(KErrNoMemory);	
   436 		}
   437 	return NULL;
   438 	}
   439 CMemoryFailAudioController::CMemoryFailAudioController():CMMFAudioController()
   440 	{
   441 	}
   442 CMemoryFailAudioController::~CMemoryFailAudioController()
   443 	{
   444     if(iSink)
   445     	{
   446     	iSink->SinkThreadLogoff();
   447     	}
   448     if(iClip)
   449     	{
   450     	iClip->SourceThreadLogoff();
   451     	}
   452 	}
   453 
   454 void CMemoryFailAudioController::AddDataSourceL(MDataSource& aSource)
   455 	{
   456     if (iClip)
   457     	{
   458     	User::Leave(KErrAlreadyExists);
   459     	}
   460 	if ((aSource.DataSourceType()==KUidMmfDescriptorSource)||
   461 			(aSource.DataSourceType()==KUidMmfFileSource))
   462 	    {
   463 	    User::LeaveIfError(aSource.SourceThreadLogon(*this));
   464 	    iClip = static_cast<CMMFClip*>(&aSource);
   465 	    if(iClip->Size())
   466 	    	{
   467 	    	iClip->SourcePrimeL();
   468 	    	}
   469 	    else
   470 	    	{
   471 	    	iClip->SourceStopL();
   472 	    	}
   473 	    }
   474 	else 
   475 		{
   476 		User::Leave(KErrNotSupported);
   477 		}
   478 	}
   479 
   480 void CMemoryFailAudioController::AddDataSinkL(MDataSink& aSink)
   481 	{
   482     if(iMMFDevSound)
   483     	{
   484     	User::Leave(KErrAlreadyExists);
   485     	}
   486     if (aSink.DataSinkType()!=KUidMmfAudioOutput) 
   487     	{
   488     	User::Leave(KErrNotSupported);	
   489     	}
   490     User::LeaveIfError(aSink.SinkThreadLogon(*this));
   491     iSink = &aSink;
   492     MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(&aSink);
   493     iMMFDevSound = &(audioOutput->SoundDevice());
   494 	iMMFDevSound->SetPrioritySettings(iPrioritySettings);
   495 	return;
   496 	}
   497 
   498 void CMemoryFailAudioController::SetPrioritySettings(const TMMFPrioritySettings& aSettings)
   499 	{
   500     iPrioritySettings = aSettings;
   501     if (iMMFDevSound)
   502     	{
   503     	iMMFDevSound->SetPrioritySettings(aSettings);
   504     	}
   505 	}
   506 
   507 //Does not acces files; returns hard-coded value.
   508 TTimeIntervalMicroSeconds CMemoryFailAudioController::DurationL()const
   509 	{
   510 	return TTimeIntervalMicroSeconds(1000000); //return 1sec
   511 	}
   512 
   513 CMMFController* CMemoryPassAudioController::NewL()
   514 	{
   515 	CMemoryPassAudioController* self = new (ELeave) CMemoryPassAudioController();
   516 	return STATIC_CAST( CMMFController*, self );
   517 	}
   518 CMemoryPassAudioController::CMemoryPassAudioController():CMemoryFailAudioController()
   519 	{
   520 	}
   521 
   522 //Derived from Audio Controller. Panics the controller thread after the play is started
   523 CMMFController* CPanicAudioController::NewL()
   524 	{
   525 	CPanicAudioController* self = new(ELeave) CPanicAudioController;
   526 	CleanupStack::PushL(self);
   527 	self->ConstructL();
   528 	CleanupStack::Pop( self );
   529 	return static_cast<CMMFController*>(self);
   530 	}
   531 
   532 CPanicAudioController::CPanicAudioController():CMMFAudioController()
   533 	{
   534 	}
   535 
   536 CPanicAudioController::~CPanicAudioController()
   537 	{
   538 	delete iPanicTimer;
   539 	}
   540 
   541 void CPanicAudioController::AddDataSourceL(MDataSource& aSource)
   542 	{
   543     TRAP_IGNORE(CMMFAudioController::AddDataSourceL(aSource));
   544 	}
   545 
   546 void CPanicAudioController::AddDataSinkL(MDataSink& aSink)
   547 	{
   548     TRAP_IGNORE(CMMFAudioController::AddDataSinkL(aSink));
   549 	}
   550 	
   551 void CPanicAudioController::PrimeL()
   552 	{
   553 	TRAP_IGNORE(CMMFAudioController::PrimeL());
   554 	}
   555 		
   556 void CPanicAudioController::PlayL()
   557 	{
   558 	TRAP_IGNORE(CMMFAudioController::PlayL());
   559 	//trigger the panic
   560 	iPanicTimer->Start(1000000, 1000000, TCallBack(PanicTimerComplete, this));
   561 	}
   562 		
   563 void CPanicAudioController::ConstructL()
   564 	{
   565 	CMMFAudioController::ConstructL();
   566 	iPanicTimer = CPeriodic::NewL(CActive::EPriorityStandard);
   567 	}
   568 
   569 TTimeIntervalMicroSeconds CPanicAudioController::DurationL()const
   570 	{
   571 	return TTimeIntervalMicroSeconds(0);
   572 	}
   573 	
   574 void CPanicAudioController::SetPositionL(const TTimeIntervalMicroSeconds& aPosition)
   575 	{
   576 	TRAP_IGNORE(CMMFAudioController::SetPositionL(aPosition));
   577 	}
   578 	
   579 TInt CPanicAudioController::PanicTimerComplete(TAny* /*aParent*/)
   580 	{
   581 	User::Panic(_L("CustomMmfAudioController"), 0);
   582 	return KErrNone;
   583 	}
   584