os/mm/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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