devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2006-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 <e32math.h>
       
    17 #include "mmfdevsoundserver.h"
       
    18 #include "mmfdevsoundserverstart.h"
       
    19 #include "mmfdevsoundsession.h"
       
    20 #include "mmfdevsoundserverconsts.h"
       
    21 
       
    22 const TInt KDevSoundShutDownDelay = 0; //no delay
       
    23 _LIT(KMMFDevSoundServerName, "MMFDevSoundServer-");
       
    24 
       
    25 // ======== LOCAL FUNCTIONS ========
       
    26 void Panic(TInt aPanicCode)
       
    27 	{
       
    28 	_LIT(KDevSoundServerPanicCategory, "mmfdevsoundserver");
       
    29 	User::Panic(KDevSoundServerPanicCategory, aPanicCode);
       
    30 	}
       
    31 
       
    32 /**
       
    33 	CMMFDevSoundServer* CMMFDevSoundServer::NewL
       
    34 	Two-phased constructor.
       
    35  */
       
    36 EXPORT_C CMMFDevSoundServer* CMMFDevSoundServer::NewL(
       
    37 	MGlobalProperties* aGlobalProperties,
       
    38 	TProcessId& aClientPID)
       
    39 	{
       
    40 	CMMFDevSoundServer* self = new(ELeave) CMMFDevSoundServer(aGlobalProperties,
       
    41 															aClientPID);
       
    42 	CleanupStack::PushL(self);
       
    43 	self->ConstructL();
       
    44 	CleanupStack::Pop(self);
       
    45 	return self;
       
    46 	}
       
    47 
       
    48 /**
       
    49  	CMMFDevSoundServer::CMMFDevSoundServer
       
    50 	C++ default constructor can NOT contain any code, that might leave.
       
    51  */
       
    52 CMMFDevSoundServer::CMMFDevSoundServer(
       
    53 	MGlobalProperties* aGlobalProperties,
       
    54 	TProcessId& aClientPID) :
       
    55 	CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions),
       
    56 	iClientPID(aClientPID),
       
    57 	iActualClientPID(aClientPID)
       
    58 	{
       
    59 	iGlobalProperties = aGlobalProperties;
       
    60 	}
       
    61 
       
    62 /**
       
    63  	CMMFDevSoundServer::ConstructL
       
    64  	Symbian 2nd phase constructor can leave.
       
    65  */
       
    66 void CMMFDevSoundServer::ConstructL()
       
    67 	{
       
    68 	RProcess client;
       
    69 	User::LeaveIfError(client.Open(iClientPID));
       
    70 
       
    71 
       
    72 	client.Close();
       
    73 
       
    74 	iDelayDevSoundShutDown = CDelayDevSoundShutDown::NewL();
       
    75 
       
    76 	// Call base class to Start server
       
    77 	StartL(KNullDesC);
       
    78 	}
       
    79 
       
    80 /**
       
    81 	CMMFDevSoundServer::~CMMFDevSoundServer
       
    82 	Destructor
       
    83 */
       
    84 CMMFDevSoundServer::~CMMFDevSoundServer()
       
    85 	{
       
    86 	if (iDelayDevSoundShutDown)
       
    87 		{
       
    88 		iDelayDevSoundShutDown->Cancel();
       
    89 		delete iDelayDevSoundShutDown;
       
    90 		}
       
    91 	}
       
    92 
       
    93 /**
       
    94  	CMMFDevSoundServer::NewSessionL
       
    95  	Creates new session
       
    96  	(other items were commented in a header).
       
    97  */
       
    98 CMmfIpcSession* CMMFDevSoundServer::NewSessionL(const TVersion& aVersion) const
       
    99 	{
       
   100 	CMmfIpcSession* devSoundSession = NULL;
       
   101 	
       
   102 	TRAPD(error, devSoundSession = CreateNewSessionL(aVersion));
       
   103 	
       
   104 	if (error!=KErrNone)
       
   105 		{
       
   106 		// session create failed, so flag for subsequent destruction of server
       
   107 		CMMFDevSoundServer* mutableThis = const_cast<CMMFDevSoundServer*>(this);
       
   108 		mutableThis->CheckForNoSessionsLeft();
       
   109 		User::Leave(error);
       
   110 		}
       
   111 	return devSoundSession;
       
   112 	}
       
   113 
       
   114 /**
       
   115  	CMMFDevSoundServer::CreateNewSessionL
       
   116  	Guts of what would otherwise be in NewSessionL() itself
       
   117  */
       
   118 CMmfIpcSession* CMMFDevSoundServer::CreateNewSessionL(const TVersion& aVersion) const
       
   119 	{
       
   120 	TVersion version(KMMFDevSoundServerVersion,
       
   121 			KMMFDevSoundServerMinorVersionNumber,
       
   122 			KMMFDevSoundServerBuildVersionNumber);
       
   123 
       
   124 	if(!User::QueryVersionSupported(version, aVersion))
       
   125 		{
       
   126 		User::Leave(KErrNotSupported);
       
   127 		}
       
   128 
       
   129 	CMMFDevSoundSession* devSoundSession =
       
   130 					CMMFDevSoundSession::NewL(*iGlobalProperties);
       
   131 	return devSoundSession;
       
   132 	}
       
   133 
       
   134 /**
       
   135  	CMMFDevSoundServer::IncrementSessionId
       
   136  	Increments session count
       
   137  	(other items were commented in a header).
       
   138  */
       
   139 void CMMFDevSoundServer::IncrementSessionId()
       
   140 	{
       
   141 	iDevSoundSessionId++;
       
   142 	if (iDevSoundSessionId)
       
   143 		{
       
   144 		iDelayDevSoundShutDown->Cancel();
       
   145 		}
       
   146 	}
       
   147 
       
   148 /**
       
   149  	CMMFDevSoundServer::DecrementSessionId
       
   150  	Decrements session count
       
   151  	(other items were commented in a header).
       
   152  */
       
   153 void CMMFDevSoundServer::DecrementSessionId()
       
   154 	{
       
   155 	iDevSoundSessionId--;
       
   156 	CheckForNoSessionsLeft();
       
   157 	}
       
   158 
       
   159 /**
       
   160  	CMMFDevSoundServer::CheckForNoSessionsLeft
       
   161  	If no sessions are left, we kick off timer, which closes down server after timeout
       
   162  	really meaning the server closes asynchronously
       
   163  */
       
   164 void CMMFDevSoundServer::CheckForNoSessionsLeft()
       
   165 	{
       
   166 	if (iDevSoundSessionId == 0)
       
   167 		{
       
   168 		iDelayDevSoundShutDown->SetDelay(
       
   169 					TTimeIntervalMicroSeconds32(KDevSoundShutDownDelay));
       
   170 		}
       
   171 	}
       
   172 
       
   173 /**
       
   174  	CMMFDevSoundServer::SendEventToClient
       
   175  	For the session requested, send event to client
       
   176  	(other items were commented in a header).
       
   177  */
       
   178 void CMMFDevSoundServer::SendEventToClient(TInt aSessionToAlert,
       
   179 									TInt /*aSessionToBeLaunched*/)
       
   180 	{
       
   181 	iSessionIter.SetToFirst();
       
   182 	CMMFDevSoundSession* session =
       
   183 						static_cast<CMMFDevSoundSession*>(iSessionIter++);
       
   184 
       
   185 	while (session != NULL)
       
   186 		{
       
   187 		if (session->DevSoundSessionId() == aSessionToAlert)
       
   188 			{
       
   189 			break;  // Finished
       
   190 			}
       
   191 		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
       
   192 		}
       
   193 	}
       
   194 
       
   195 /**
       
   196  	CMMFDevSoundServer::LaunchRequest
       
   197  	Launches the DevSound servers waiting for Audio Policy.
       
   198  	(other items were commented in a header).
       
   199  */
       
   200 void CMMFDevSoundServer::LaunchRequest(TInt aSessionId)
       
   201 	{
       
   202 	iSessionIter.SetToFirst();
       
   203 	CMMFDevSoundSession* session =
       
   204 					static_cast<CMMFDevSoundSession*>(iSessionIter++);
       
   205 
       
   206 	while (session != NULL)
       
   207 		{
       
   208 		if (session->DevSoundSessionId() == aSessionId)
       
   209 			{
       
   210 			break;  // Finished
       
   211 			}
       
   212 		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
       
   213 		}
       
   214 	}
       
   215 
       
   216 
       
   217 void CMMFDevSoundServer::RenamePrioritizeServer()
       
   218 	{
       
   219 	//Rename devsound server name
       
   220 	RThread devsoundServerThread;
       
   221 	TThreadId threadId;
       
   222 	TName name;
       
   223 	name.Append(KMMFDevSoundServerName); 
       
   224 	threadId = devsoundServerThread.Id();
       
   225 	name.AppendNum(threadId.Id(),EHex);
       
   226 	//We are ignoring the error code returned from User::RenameThread
       
   227 	//as it is not important here, may be for profiling
       
   228 	User::RenameThread(name);
       
   229 	
       
   230 	//Set the devsound priority
       
   231 	TThreadPriority devsoundServerPriority = static_cast<TThreadPriority>(KDevsoundServerPriority);
       
   232 	devsoundServerThread.SetPriority(devsoundServerPriority);
       
   233 	}
       
   234 
       
   235 /**
       
   236  	CMMFDevSoundServer* CMMFDevSoundServer::NewL
       
   237  	Two-phased constructor.
       
   238  */
       
   239 CMMFDevSoundServer::CDelayDevSoundShutDown*
       
   240 CMMFDevSoundServer::CDelayDevSoundShutDown::NewL()
       
   241 	{
       
   242 	CDelayDevSoundShutDown* self = new(ELeave) CDelayDevSoundShutDown;
       
   243 	CleanupStack::PushL(self);
       
   244 	self->ConstructL();
       
   245 	CleanupStack::Pop(self);
       
   246 	return self;
       
   247 	}
       
   248 
       
   249 /**
       
   250 	CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown
       
   251 	C++ constructor
       
   252 	(other items were commented in a header).
       
   253  */
       
   254 CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown()
       
   255 	: CActive(0)
       
   256 	{
       
   257 	}
       
   258 
       
   259 /**
       
   260  	CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL
       
   261  	Symbian 2nd phase constructor can leave.
       
   262  */
       
   263 void CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL()
       
   264 	{
       
   265 	User::LeaveIfError(iTimer.CreateLocal());
       
   266 	CActiveScheduler::Add(this);
       
   267 	}
       
   268 
       
   269 /**
       
   270  	CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown
       
   271  	Destructor
       
   272  */
       
   273 CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown()
       
   274 	{
       
   275 	Cancel();
       
   276 	iTimer.Close();
       
   277 	}
       
   278 
       
   279 /**
       
   280  	CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay
       
   281  	Request a timeout after aDelay
       
   282  	(other items were commented in a header).
       
   283  */
       
   284 void CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay(
       
   285 		TTimeIntervalMicroSeconds32 aDelay)
       
   286 	{
       
   287 	__ASSERT_ALWAYS(!IsActive(), Panic(EMMFDevSoundServerIsActive));
       
   288 	iTimer.After(iStatus, aDelay);
       
   289 	SetActive();
       
   290 	}
       
   291 
       
   292 /**
       
   293  	CMMFDevSoundServer::CDelayDevSoundShutDown::RunL
       
   294  	Called by Active object framework after timer expires
       
   295  	(other items were commented in a header).
       
   296  */
       
   297 void CMMFDevSoundServer::CDelayDevSoundShutDown::RunL()
       
   298 	{
       
   299 	CActiveScheduler::Stop();
       
   300 	}
       
   301 
       
   302 /**
       
   303  	CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel
       
   304  	Called by Active object framework when user cancels active object.
       
   305  	(other items were commented in a header).
       
   306  */
       
   307 void CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel()
       
   308 	{
       
   309 	iTimer.Cancel();
       
   310 	}
       
   311 
       
   312 /**
       
   313  	CMMFDevSoundServer::SetClientProcessIdL
       
   314  */
       
   315 void CMMFDevSoundServer::SetClientProcessIdL(TThreadId aTid)
       
   316 	{
       
   317 	
       
   318 	RThread clientThread;
       
   319 	User::LeaveIfError(clientThread.Open(aTid));
       
   320 	CleanupClosePushL(clientThread);
       
   321 	
       
   322 	RProcess clientProcess;
       
   323 	User::LeaveIfError(clientThread.Process(clientProcess));
       
   324 	CleanupClosePushL(clientProcess);
       
   325 	
       
   326 	iActualClientPID = clientProcess.Id();
       
   327 	CleanupStack::PopAndDestroy(2, &clientThread);	// clientProcess, clientThread		
       
   328 	}
       
   329 //GLOBAL FUNCTIONS
       
   330 
       
   331 /**
       
   332  	This function raises a panic on the client of the DevSound Server
       
   333  	
       
   334  	@param  aError
       
   335 			one of the several panic codes that may be raised by this dll on
       
   336 			the client
       
   337  	
       
   338  	@panic  EMMFDevSoundPlayDataWithoutInitialize is raised when playdata is
       
   339 			called without initialization
       
   340  	@panic  EMMFDevSoundRecordDataWithoutInitialize is raised when recorddata
       
   341 			is called without initialization
       
   342  */
       
   343 GLDEF_C void PanicClient(const RMmfIpcMessage& aMessage,
       
   344 					TMMFDevSoundClientPanicCodes aPanicCode)
       
   345 	{
       
   346 	aMessage.Panic(KMMFDevSoundClientPanicCategory, aPanicCode);
       
   347 	}
       
   348 
       
   349 //  End of File