os/mm/devsound/sounddevbt/PlatSec/src/Server/AudioServer/MmfBtAudioServer.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 "MmfBtAudioServer.h"
    18 #include "MmfBtAudioServerStart.h"
    19 #include "MmfBtDevSoundSession.h"
    20 #include "MmfBtAudioServerSession.h"
    21 #include "MmfBtDevSoundServer.h"
    22 #include "MmfBtDevSoundServerStart.h"
    23 #include "../../../../inc/common/mmfBtBase.hrh"
    24 
    25 
    26 static const TUid KUidDevSoundServer = {KUidMmfBtDevSoundServerDllUnicodeDefine};
    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 	iDelayAudioServerShutDown = CDelayAudioServerShutDown::NewL();
    48 	// Call base class to Start server
    49 	StartL(KAudioServerName);
    50 	}
    51 
    52 CMMFAudioServer::~CMMFAudioServer()
    53 	{
    54 	if (iDelayAudioServerShutDown)
    55 		{
    56 		iDelayAudioServerShutDown->Cancel();
    57 		delete iDelayAudioServerShutDown;
    58 		}
    59 	iDevSoundServList.Close();
    60 	iPolicyServerHandle.Close();
    61 	}
    62 
    63 CMmfIpcSession* CMMFAudioServer::NewSessionL(const TVersion& aVersion) const
    64 	{
    65 	TVersion v(KMMFAudioServerVersion,KMMFAudioServerMinorVersionNumber,KMMFAudioServerBuildVersionNumber);
    66 	if(!User::QueryVersionSupported(v, aVersion))
    67 		User::Leave(KErrNotSupported);
    68 
    69 	for(TInt i=0; i<iDevSoundServList.Count(); i++)
    70 		{
    71 		CStartAndMonitorDevSoundThread* devSoundMonitorThread = iDevSoundServList[i];
    72 		if(!devSoundMonitorThread->IsActive())
    73 			{
    74 			iDevSoundServList.Remove(i);
    75 			delete devSoundMonitorThread;
    76 			}
    77 		iDevSoundServList.Compress();
    78 		}
    79 
    80 	TName devSoundServerName;
    81 	User::LeaveIfError(StartDevSoundServerL(devSoundServerName));
    82 	CMMFAudioServerSession* audioServerSession = CMMFAudioServerSession::NewL(devSoundServerName);
    83 	return audioServerSession;
    84 	}
    85 
    86 void CMMFAudioServer::IncrementSessionId()
    87 	{
    88 	iAudioServerSessionId++;
    89 	}
    90 
    91 void CMMFAudioServer::DecrementSessionId()
    92 	{
    93 	iAudioServerSessionId--;
    94 	}
    95 
    96 void CMMFAudioServer::IncrementDevSoundCount()
    97 	{
    98 	iDevSoundCount++;
    99 	if(iDevSoundCount)
   100 		iDelayAudioServerShutDown->Cancel(); //in the case we started the shutdown due to no more DevSound
   101 	}
   102 
   103 void CMMFAudioServer::DecrementDevSoundCount()
   104 	{
   105 	iDevSoundCount--;
   106     if ( iDevSoundCount == 0 )
   107 		{
   108 		iDelayAudioServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KAudioServerShutDownDelay));
   109  		}
   110 	}
   111 
   112 void CMMFAudioServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/)
   113 	{
   114 	// For the session requested, send event to client
   115 	iSessionIter.SetToFirst();
   116 	CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   117 	while (session != NULL)
   118 		{
   119 		if (session->AudioServerSessionId() == aSessionToAlert)
   120 			{
   121 			break;  // Finished
   122 			}
   123 		session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   124 		}
   125 	}
   126 
   127 void CMMFAudioServer::LaunchRequest(TInt aSessionId)
   128 	{
   129 	iSessionIter.SetToFirst();
   130 	CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   131 	while (session != NULL)
   132 		{
   133 		if (session->AudioServerSessionId() == aSessionId)
   134 			{
   135 			break;  // Finished
   136 			}
   137 		session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
   138 		}
   139 	}
   140 
   141 TInt CMMFAudioServer::StartDevSoundServerL(TName& aDevSoundName) const
   142 	{
   143 	RMessage2 message(Message());
   144 	CStartAndMonitorDevSoundThread* monitorDevSound = NULL;
   145 
   146 	TRAPD(err, monitorDevSound = CStartAndMonitorDevSoundThread::NewL(const_cast<CMMFAudioServer*>(this)));
   147 	if(err != KErrNone)
   148 		{
   149 		delete monitorDevSound;
   150 		return err;
   151 		}
   152 
   153 	iDevSoundServList.Append(monitorDevSound);
   154 	
   155 	CMMFAudioServer* mutableThis = const_cast<CMMFAudioServer*>(this);
   156 	mutableThis->iGlobalNum+=1;
   157 
   158 	return monitorDevSound->StartDevSoundServerL(message, aDevSoundName, iGlobalNum);
   159 
   160 	}
   161 
   162 
   163 CMMFAudioServer::CDelayAudioServerShutDown* CMMFAudioServer::CDelayAudioServerShutDown::NewL()
   164 	{
   165 	CDelayAudioServerShutDown* self = new(ELeave) CDelayAudioServerShutDown;
   166 	CleanupStack::PushL(self);
   167 	self->ConstructL();
   168 	CleanupStack::Pop();
   169 	return self;
   170 	}
   171 
   172 CMMFAudioServer::CDelayAudioServerShutDown::CDelayAudioServerShutDown() : CActive(0)
   173 	{
   174 	}
   175         
   176 void CMMFAudioServer::CDelayAudioServerShutDown::ConstructL()
   177 	{
   178 	User::LeaveIfError(iShutDownTimer.CreateLocal());
   179 	CActiveScheduler::Add(this);
   180 	}
   181 
   182 CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown()
   183 	{
   184 	Cancel();
   185 	iShutDownTimer.Close();
   186 	}
   187 
   188 
   189 void CMMFAudioServer::CDelayAudioServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay)
   190 	{
   191 	__ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CDelayedShutDown"), 1));
   192 	iShutDownTimer.After(iStatus, aDelay);
   193 	SetActive();
   194 	}
   195 
   196 void CMMFAudioServer::CDelayAudioServerShutDown::RunL()
   197 	{
   198 	CActiveScheduler::Stop();
   199 	}
   200 
   201 
   202 void CMMFAudioServer::CDelayAudioServerShutDown::DoCancel()
   203 	{
   204 	iShutDownTimer.Cancel();
   205 	}
   206 
   207 
   208 CStartAndMonitorDevSoundThread* CStartAndMonitorDevSoundThread::NewL(CMMFAudioServer* aAudioServer)
   209 	{
   210 	CStartAndMonitorDevSoundThread* self = new(ELeave) CStartAndMonitorDevSoundThread(aAudioServer);
   211 	CleanupStack::PushL(self);
   212 	self->ConstructL();
   213 	CleanupStack::Pop();
   214 	return self;
   215 	}
   216 
   217 void CStartAndMonitorDevSoundThread::ConstructL()
   218 	{
   219 	CActiveScheduler::Add(this);
   220 	}
   221 	
   222 TInt CStartAndMonitorDevSoundThread::StartDevSoundServerL(RMessage2& aMessage, TName& aDevSoundName, TInt aUniqueNum)
   223 	{
   224 	RThread clientThread;
   225 	aMessage.ClientL(clientThread);
   226 	RProcess clientProcess;
   227 	User::LeaveIfError(clientThread.Process(clientProcess));
   228 	TProcessId clientProcessId(clientProcess.Id());
   229 
   230 	clientThread.Close();
   231 	clientProcess.Close();
   232 
   233 	TDevSoundServerStart start(iAudioServer, clientProcessId);//Pass to DevSoundServer the clien't process ID 
   234 
   235 	const TUidType serverUid(KNullUid,KNullUid,KUidDevSoundServer);
   236 	
   237 	TThreadFunction serverFunc=CMMFDevSoundServer::StartThread;
   238 	//
   239 	// To deal with the unique thread (+semaphore!) naming in EPOC, and that we may
   240 	// be trying to restart a server that has just exited we attempt to create a
   241 	// unique thread name for the server.
   242 	//
   243 
   244 	TInt err = KErrNone;
   245 	TName name(KDevSoundServerName);
   246 	name.AppendNum(TInt(this),EHex);
   247 	name.Append(TChar('.'));
   248 	name.AppendNum(aUniqueNum,EHex);
   249 	err = iServer.Create(name, serverFunc, KDevSoundServerStackSize,
   250 	                	KDevSoundServerInitHeapSize, KDevSoundServerMaxHeapSize,
   251 	                	&start, EOwnerProcess);
   252 				
   253 
   254 	if(err != KErrNone)
   255 		return err;
   256 	// Synchronise with the server
   257 	TRequestStatus reqStatus;
   258 	iServer.Rendezvous(reqStatus);
   259 	
   260 	if (reqStatus!=KRequestPending)
   261 		{
   262 		iServer.Kill(0);
   263 		}
   264 	else
   265 		{
   266 		// Start the test harness
   267 		iServer.Resume();
   268 		// Server will call the reciprocal static synchronise call	
   269 		}
   270 
   271 	User::WaitForRequest(reqStatus); // wait for start or death
   272 	if(reqStatus.Int() != KErrNone)
   273 		{
   274 		iServer.Close();
   275 		return reqStatus.Int();
   276 		}
   277 		
   278 	aDevSoundName = iServer.Name();
   279 
   280 	iServer.Logon(iStatus);
   281 	SetActive();
   282 
   283 	iAudioServer->IncrementDevSoundCount();
   284 	return KErrNone;
   285 	}
   286 
   287 
   288 CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread(CMMFAudioServer* aAudioServer): CActive(0)
   289 	{
   290 	iAudioServer = aAudioServer;
   291 	}
   292 
   293 CStartAndMonitorDevSoundThread::~CStartAndMonitorDevSoundThread()
   294 	{
   295 	Cancel();
   296 	}
   297     
   298 void CStartAndMonitorDevSoundThread::RunL()
   299 	{
   300 	iServer.Close();
   301 	iAudioServer->DecrementDevSoundCount();
   302 	}
   303 
   304 void CStartAndMonitorDevSoundThread::DoCancel()
   305 	{
   306 	iServer.LogonCancel(iStatus);
   307 	}
   308 
   309 
   310