os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfAudioServer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-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 "MmfAudioServer.h"
    18 #include "MmfAudioServerStart.h"
    19 #include "MmfDevSoundSession.h"
    20 #include "MmfAudioServerSession.h"
    21 #include "MmfDevSoundServer.h"
    22 #include "MmfDevSoundServerStart.h"
    23 #include "mmfbase.hrh"
    24 
    25 
    26 static const TUid KUidDevSoundServer = {KUidMmfDevSoundServerDllUnicodeDefine};
    27 
    28 const TInt KAudioServerShutDownDelay = 50000000; //50 sec
    29 
    30 
    31 CMMFAudioServer* CMMFAudioServer::NewL()
    32 	{
    33 	CMMFAudioServer* s = new(ELeave) CMMFAudioServer();
    34 	CleanupStack::PushL(s);
    35 	s->ConstructL();
    36 	CleanupStack::Pop();
    37 	return s;
    38 	}
    39 
    40 CMMFAudioServer::CMMFAudioServer() :
    41 	CMmfIpcServer(EPriorityStandard)
    42 	{
    43 	}
    44 
    45 void CMMFAudioServer::ConstructL()
    46 	{
    47 	// Call base class to Start server
    48 	StartL(KAudioServerName);
    49 	iDelayAudioServerShutDown = CDelayAudioServerShutDown::NewL();
    50 	// Create an audio policy server
    51 	iAudioPolicyProxy = new (ELeave) RMMFAudioPolicyProxy();	
    52 	User::LeaveIfError(iAudioPolicyProxy->CreateServer(iPolicyServerHandle));
    53 	}
    54 
    55 CMMFAudioServer::~CMMFAudioServer()
    56 	{
    57 	if (iDelayAudioServerShutDown)
    58 		{
    59 		iDelayAudioServerShutDown->Cancel();
    60 		delete iDelayAudioServerShutDown;
    61 		}
    62 	iDevSoundServList.ResetAndDestroy();
    63 	iDevSoundServList.Close();
    64 	if( iAudioPolicyProxy != NULL)
    65 		{
    66 		iAudioPolicyProxy->Close(); 
    67 		delete iAudioPolicyProxy;
    68 		}	
    69 	iPolicyServerHandle.Close();
    70 	}
    71 
    72 CMmfIpcSession* CMMFAudioServer::NewSessionL(const TVersion& aVersion) const
    73 	{
    74 	TVersion v(KMMFAudioServerVersion,KMMFAudioServerMinorVersionNumber,KMMFAudioServerBuildVersionNumber);
    75 	if(!User::QueryVersionSupported(v, aVersion))
    76 		User::Leave(KErrNotSupported);
    77 
    78 	TInt i=0;
    79 	while(i<iDevSoundServList.Count())
    80 		{
    81 		CStartAndMonitorDevSoundThread* devSoundMonitorThread = iDevSoundServList[i];
    82 		if(!devSoundMonitorThread->IsActive())
    83 			{
    84 			iDevSoundServList.Remove(i);
    85 			delete devSoundMonitorThread;
    86 			}
    87 		else
    88 			{
    89 			i++;
    90 			}
    91 		}
    92 	iDevSoundServList.Compress();
    93 
    94 	RMMFDevSoundServerProxy devSoundSessionHandle;
    95 	User::LeaveIfError(StartDevSoundServer(devSoundSessionHandle));
    96 	CMMFAudioServerSession* audioServerSession = CMMFAudioServerSession::NewL(devSoundSessionHandle);
    97 	return audioServerSession;
    98 	}
    99 
   100 void CMMFAudioServer::IncrementSessionId()
   101 	{
   102 	iAudioServerSessionId++;
   103 	}
   104 
   105 void CMMFAudioServer::DecrementSessionId()
   106 	{
   107 	iAudioServerSessionId--;
   108 	}
   109 
   110 void CMMFAudioServer::IncrementDevSoundCount()
   111 	{
   112 	iDevSoundCount++;
   113 	if(iDevSoundCount)
   114 		iDelayAudioServerShutDown->Cancel(); //in the case we started the shutdown due to no more DevSound
   115 	}
   116 
   117 void CMMFAudioServer::DecrementDevSoundCount()
   118 	{
   119 	iDevSoundCount--;
   120     if ( iDevSoundCount == 0 )
   121 		{
   122 		iDelayAudioServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KAudioServerShutDownDelay));
   123  		}
   124 	}
   125 
   126 void CMMFAudioServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/)
   127 	{
   128 	// For the session requested, send event to client
   129 	iSessionIter.SetToFirst();
   130 	CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   131 	while (session != NULL)
   132 		{
   133 		if (session->AudioServerSessionId() == aSessionToAlert)
   134 			{
   135 			break;  // Finished
   136 			}
   137 		session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   138 		}
   139 	}
   140 
   141 void CMMFAudioServer::LaunchRequest(TInt aSessionId)
   142 	{
   143 	iSessionIter.SetToFirst();
   144 	CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   145 	while (session != NULL)
   146 		{
   147 		if (session->AudioServerSessionId() == aSessionId)
   148 			{
   149 			break;  // Finished
   150 			}
   151 		session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   152 		}
   153 	}
   154 
   155 TInt CMMFAudioServer::StartDevSoundServer(RMMFDevSoundServerProxy& aDevSoundSessionHandle) const
   156 	{
   157 	RMessage2 message(Message());
   158 	CStartAndMonitorDevSoundThread* monitorDevSound = NULL;
   159 
   160 	TRAPD(err, monitorDevSound = CStartAndMonitorDevSoundThread::NewL(const_cast<CMMFAudioServer*>(this)));
   161 	if(err != KErrNone)
   162 		{
   163 		delete monitorDevSound;
   164 		return err;
   165 		}
   166 
   167 	err = iDevSoundServList.Append(monitorDevSound);
   168 	if(err != KErrNone)
   169 		{
   170 		delete monitorDevSound;
   171 		return err;
   172 		}
   173 	
   174 	return monitorDevSound->StartDevSoundServer(message, aDevSoundSessionHandle);
   175 
   176 	}
   177 
   178 
   179 CMMFAudioServer::CDelayAudioServerShutDown* CMMFAudioServer::CDelayAudioServerShutDown::NewL()
   180 	{
   181 	CDelayAudioServerShutDown* self = new(ELeave) CDelayAudioServerShutDown;
   182 	CleanupStack::PushL(self);
   183 	self->ConstructL();
   184 	CleanupStack::Pop();
   185 	return self;
   186 	}
   187 
   188 CMMFAudioServer::CDelayAudioServerShutDown::CDelayAudioServerShutDown() : CActive(0)
   189 	{
   190 	}
   191         
   192 void CMMFAudioServer::CDelayAudioServerShutDown::ConstructL()
   193 	{
   194 	User::LeaveIfError(iShutDownTimer.CreateLocal());
   195 	CActiveScheduler::Add(this);
   196 	}
   197 
   198 CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown()
   199 	{
   200 	Cancel();
   201 	iShutDownTimer.Close();
   202 	}
   203 
   204 
   205 void CMMFAudioServer::CDelayAudioServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay)
   206 	{
   207 	__ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CDelayedShutDown"), 1));
   208 	iShutDownTimer.After(iStatus, aDelay);
   209 	SetActive();
   210 	}
   211 
   212 void CMMFAudioServer::CDelayAudioServerShutDown::RunL()
   213 	{
   214 	CActiveScheduler::Stop();
   215 	}
   216 
   217 
   218 void CMMFAudioServer::CDelayAudioServerShutDown::DoCancel()
   219 	{
   220 	iShutDownTimer.Cancel();
   221 	}
   222 
   223 
   224 CStartAndMonitorDevSoundThread* CStartAndMonitorDevSoundThread::NewL(CMMFAudioServer* aAudioServer)
   225 	{
   226 	CStartAndMonitorDevSoundThread* self = new(ELeave) CStartAndMonitorDevSoundThread(aAudioServer);
   227 	CleanupStack::PushL(self);
   228 	self->ConstructL();
   229 	CleanupStack::Pop();
   230 	return self;
   231 	}
   232 
   233 void CStartAndMonitorDevSoundThread::ConstructL()
   234 	{
   235 	CActiveScheduler::Add(this);
   236 	}
   237 	
   238 TInt CStartAndMonitorDevSoundThread::StartDevSoundServer(RMessage2& aMessage, RMMFDevSoundServerProxy& aDevSoundSessionHandle)
   239 	{
   240 	RThread clientThread;
   241 	TInt err = aMessage.Client(clientThread);
   242 	if (err != KErrNone)
   243 		{
   244 		return err;
   245 		}
   246 	RProcess clientProcess;
   247     err = clientThread.Process(clientProcess);
   248 	if (err != KErrNone)
   249 		{
   250 		clientThread.Close();	
   251 		return err;
   252 		}
   253 	TProcessId clientProcessId(clientProcess.Id());
   254 
   255 	clientThread.Close();
   256 	clientProcess.Close();
   257 
   258 	RServer2 devSoundServerHandle;
   259 	TDevSoundServerStart start(iAudioServer, clientProcessId, devSoundServerHandle);//Pass to DevSoundServer the clien't process ID 
   260 
   261 	const TUidType serverUid(KNullUid,KNullUid,KUidDevSoundServer);
   262 	
   263 	TThreadFunction serverFunc=CMMFDevSoundServer::StartThread;
   264 	
   265 	err = iServer.Create(_L(""), serverFunc, KDevSoundServerStackSize,
   266 #ifdef SYMBIAN_USE_SEPARATE_HEAPS
   267 	                	KDevSoundServerInitHeapSize, KDevSoundServerMaxHeapSize,
   268 #else
   269 						&User::Heap(), //shared heap is now default
   270 #endif
   271 	                	&start, EOwnerProcess);
   272 				
   273 
   274 	if(err != KErrNone)
   275 		return err;
   276 	// Synchronise with the server
   277 	TRequestStatus reqStatus;
   278 	iServer.Rendezvous(reqStatus);
   279 	
   280 	if (reqStatus!=KRequestPending)
   281 		{
   282 		iServer.Kill(0);
   283 		}
   284 	else
   285 		{
   286 		// Start the test harness
   287 		iServer.Resume();
   288 		// Server will call the reciprocal static synchronise call	
   289 		}
   290 
   291 	User::WaitForRequest(reqStatus); // wait for start or death
   292 	if(reqStatus.Int() != KErrNone)
   293 		{
   294 		iServer.Close();
   295 		devSoundServerHandle.Close();
   296 		return reqStatus.Int();
   297 		}
   298 	err = aDevSoundSessionHandle.Open(devSoundServerHandle);
   299 	
   300 	if(err != KErrNone)
   301 		{
   302 		iServer.Close();
   303 		devSoundServerHandle.Close();
   304 		return err;
   305 		}
   306 	aDevSoundSessionHandle.ShareProtected();
   307 	iServer.Logon(iStatus);
   308 	SetActive();
   309 
   310 	iAudioServer->IncrementDevSoundCount();
   311 	return KErrNone;
   312 	}
   313 
   314 
   315 CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread(CMMFAudioServer* aAudioServer): CActive(0)
   316 	{
   317 	iAudioServer = aAudioServer;
   318 	}
   319 
   320 CStartAndMonitorDevSoundThread::~CStartAndMonitorDevSoundThread()
   321 	{
   322 	Cancel();
   323 	}
   324     
   325 void CStartAndMonitorDevSoundThread::RunL()
   326 	{
   327 	iServer.Close();
   328 	iAudioServer->DecrementDevSoundCount();
   329 	}
   330 
   331 void CStartAndMonitorDevSoundThread::DoCancel()
   332 	{
   333 	iServer.LogonCancel(iStatus);
   334 	}
   335 
   336 TInt RMMFDevSoundServerProxy::Open(RServer2& aDevSoundServerHandle)
   337 	{
   338 	TInt err = CreateSession(aDevSoundServerHandle, TVersion(KMMFDevSoundServerVersion,
   339 														KMMFDevSoundServerMinorVersionNumber,
   340 														KMMFDevSoundServerBuildVersionNumber), -1, EIpcSession_GlobalSharable);
   341 	return err;
   342 	}
   343