1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/devsound/sounddevbt/PlatSec/src/Server/AudioServer/MmfBtAudioServer.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,310 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32math.h>
1.20 +#include "MmfBtAudioServer.h"
1.21 +#include "MmfBtAudioServerStart.h"
1.22 +#include "MmfBtDevSoundSession.h"
1.23 +#include "MmfBtAudioServerSession.h"
1.24 +#include "MmfBtDevSoundServer.h"
1.25 +#include "MmfBtDevSoundServerStart.h"
1.26 +#include "../../../../inc/common/mmfBtBase.hrh"
1.27 +
1.28 +
1.29 +static const TUid KUidDevSoundServer = {KUidMmfBtDevSoundServerDllUnicodeDefine};
1.30 +
1.31 +const TInt KAudioServerShutDownDelay = 50000000; //50 sec
1.32 +
1.33 +
1.34 +CMMFAudioServer* CMMFAudioServer::NewL()
1.35 + {
1.36 + CMMFAudioServer* s = new(ELeave) CMMFAudioServer();
1.37 + CleanupStack::PushL(s);
1.38 + s->ConstructL();
1.39 + CleanupStack::Pop();
1.40 + return s;
1.41 + }
1.42 +
1.43 +CMMFAudioServer::CMMFAudioServer() :
1.44 + CMmfIpcServer(EPriorityStandard)
1.45 + {
1.46 + }
1.47 +
1.48 +void CMMFAudioServer::ConstructL()
1.49 + {
1.50 + iDelayAudioServerShutDown = CDelayAudioServerShutDown::NewL();
1.51 + // Call base class to Start server
1.52 + StartL(KAudioServerName);
1.53 + }
1.54 +
1.55 +CMMFAudioServer::~CMMFAudioServer()
1.56 + {
1.57 + if (iDelayAudioServerShutDown)
1.58 + {
1.59 + iDelayAudioServerShutDown->Cancel();
1.60 + delete iDelayAudioServerShutDown;
1.61 + }
1.62 + iDevSoundServList.Close();
1.63 + iPolicyServerHandle.Close();
1.64 + }
1.65 +
1.66 +CMmfIpcSession* CMMFAudioServer::NewSessionL(const TVersion& aVersion) const
1.67 + {
1.68 + TVersion v(KMMFAudioServerVersion,KMMFAudioServerMinorVersionNumber,KMMFAudioServerBuildVersionNumber);
1.69 + if(!User::QueryVersionSupported(v, aVersion))
1.70 + User::Leave(KErrNotSupported);
1.71 +
1.72 + for(TInt i=0; i<iDevSoundServList.Count(); i++)
1.73 + {
1.74 + CStartAndMonitorDevSoundThread* devSoundMonitorThread = iDevSoundServList[i];
1.75 + if(!devSoundMonitorThread->IsActive())
1.76 + {
1.77 + iDevSoundServList.Remove(i);
1.78 + delete devSoundMonitorThread;
1.79 + }
1.80 + iDevSoundServList.Compress();
1.81 + }
1.82 +
1.83 + TName devSoundServerName;
1.84 + User::LeaveIfError(StartDevSoundServerL(devSoundServerName));
1.85 + CMMFAudioServerSession* audioServerSession = CMMFAudioServerSession::NewL(devSoundServerName);
1.86 + return audioServerSession;
1.87 + }
1.88 +
1.89 +void CMMFAudioServer::IncrementSessionId()
1.90 + {
1.91 + iAudioServerSessionId++;
1.92 + }
1.93 +
1.94 +void CMMFAudioServer::DecrementSessionId()
1.95 + {
1.96 + iAudioServerSessionId--;
1.97 + }
1.98 +
1.99 +void CMMFAudioServer::IncrementDevSoundCount()
1.100 + {
1.101 + iDevSoundCount++;
1.102 + if(iDevSoundCount)
1.103 + iDelayAudioServerShutDown->Cancel(); //in the case we started the shutdown due to no more DevSound
1.104 + }
1.105 +
1.106 +void CMMFAudioServer::DecrementDevSoundCount()
1.107 + {
1.108 + iDevSoundCount--;
1.109 + if ( iDevSoundCount == 0 )
1.110 + {
1.111 + iDelayAudioServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KAudioServerShutDownDelay));
1.112 + }
1.113 + }
1.114 +
1.115 +void CMMFAudioServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/)
1.116 + {
1.117 + // For the session requested, send event to client
1.118 + iSessionIter.SetToFirst();
1.119 + CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
1.120 + while (session != NULL)
1.121 + {
1.122 + if (session->AudioServerSessionId() == aSessionToAlert)
1.123 + {
1.124 + break; // Finished
1.125 + }
1.126 + session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
1.127 + }
1.128 + }
1.129 +
1.130 +void CMMFAudioServer::LaunchRequest(TInt aSessionId)
1.131 + {
1.132 + iSessionIter.SetToFirst();
1.133 + CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
1.134 + while (session != NULL)
1.135 + {
1.136 + if (session->AudioServerSessionId() == aSessionId)
1.137 + {
1.138 + break; // Finished
1.139 + }
1.140 + session = static_cast<CMMFAudioServerSession*>(iSessionIter++);
1.141 + }
1.142 + }
1.143 +
1.144 +TInt CMMFAudioServer::StartDevSoundServerL(TName& aDevSoundName) const
1.145 + {
1.146 + RMessage2 message(Message());
1.147 + CStartAndMonitorDevSoundThread* monitorDevSound = NULL;
1.148 +
1.149 + TRAPD(err, monitorDevSound = CStartAndMonitorDevSoundThread::NewL(const_cast<CMMFAudioServer*>(this)));
1.150 + if(err != KErrNone)
1.151 + {
1.152 + delete monitorDevSound;
1.153 + return err;
1.154 + }
1.155 +
1.156 + iDevSoundServList.Append(monitorDevSound);
1.157 +
1.158 + CMMFAudioServer* mutableThis = const_cast<CMMFAudioServer*>(this);
1.159 + mutableThis->iGlobalNum+=1;
1.160 +
1.161 + return monitorDevSound->StartDevSoundServerL(message, aDevSoundName, iGlobalNum);
1.162 +
1.163 + }
1.164 +
1.165 +
1.166 +CMMFAudioServer::CDelayAudioServerShutDown* CMMFAudioServer::CDelayAudioServerShutDown::NewL()
1.167 + {
1.168 + CDelayAudioServerShutDown* self = new(ELeave) CDelayAudioServerShutDown;
1.169 + CleanupStack::PushL(self);
1.170 + self->ConstructL();
1.171 + CleanupStack::Pop();
1.172 + return self;
1.173 + }
1.174 +
1.175 +CMMFAudioServer::CDelayAudioServerShutDown::CDelayAudioServerShutDown() : CActive(0)
1.176 + {
1.177 + }
1.178 +
1.179 +void CMMFAudioServer::CDelayAudioServerShutDown::ConstructL()
1.180 + {
1.181 + User::LeaveIfError(iShutDownTimer.CreateLocal());
1.182 + CActiveScheduler::Add(this);
1.183 + }
1.184 +
1.185 +CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown()
1.186 + {
1.187 + Cancel();
1.188 + iShutDownTimer.Close();
1.189 + }
1.190 +
1.191 +
1.192 +void CMMFAudioServer::CDelayAudioServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay)
1.193 + {
1.194 + __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CDelayedShutDown"), 1));
1.195 + iShutDownTimer.After(iStatus, aDelay);
1.196 + SetActive();
1.197 + }
1.198 +
1.199 +void CMMFAudioServer::CDelayAudioServerShutDown::RunL()
1.200 + {
1.201 + CActiveScheduler::Stop();
1.202 + }
1.203 +
1.204 +
1.205 +void CMMFAudioServer::CDelayAudioServerShutDown::DoCancel()
1.206 + {
1.207 + iShutDownTimer.Cancel();
1.208 + }
1.209 +
1.210 +
1.211 +CStartAndMonitorDevSoundThread* CStartAndMonitorDevSoundThread::NewL(CMMFAudioServer* aAudioServer)
1.212 + {
1.213 + CStartAndMonitorDevSoundThread* self = new(ELeave) CStartAndMonitorDevSoundThread(aAudioServer);
1.214 + CleanupStack::PushL(self);
1.215 + self->ConstructL();
1.216 + CleanupStack::Pop();
1.217 + return self;
1.218 + }
1.219 +
1.220 +void CStartAndMonitorDevSoundThread::ConstructL()
1.221 + {
1.222 + CActiveScheduler::Add(this);
1.223 + }
1.224 +
1.225 +TInt CStartAndMonitorDevSoundThread::StartDevSoundServerL(RMessage2& aMessage, TName& aDevSoundName, TInt aUniqueNum)
1.226 + {
1.227 + RThread clientThread;
1.228 + aMessage.ClientL(clientThread);
1.229 + RProcess clientProcess;
1.230 + User::LeaveIfError(clientThread.Process(clientProcess));
1.231 + TProcessId clientProcessId(clientProcess.Id());
1.232 +
1.233 + clientThread.Close();
1.234 + clientProcess.Close();
1.235 +
1.236 + TDevSoundServerStart start(iAudioServer, clientProcessId);//Pass to DevSoundServer the clien't process ID
1.237 +
1.238 + const TUidType serverUid(KNullUid,KNullUid,KUidDevSoundServer);
1.239 +
1.240 + TThreadFunction serverFunc=CMMFDevSoundServer::StartThread;
1.241 + //
1.242 + // To deal with the unique thread (+semaphore!) naming in EPOC, and that we may
1.243 + // be trying to restart a server that has just exited we attempt to create a
1.244 + // unique thread name for the server.
1.245 + //
1.246 +
1.247 + TInt err = KErrNone;
1.248 + TName name(KDevSoundServerName);
1.249 + name.AppendNum(TInt(this),EHex);
1.250 + name.Append(TChar('.'));
1.251 + name.AppendNum(aUniqueNum,EHex);
1.252 + err = iServer.Create(name, serverFunc, KDevSoundServerStackSize,
1.253 + KDevSoundServerInitHeapSize, KDevSoundServerMaxHeapSize,
1.254 + &start, EOwnerProcess);
1.255 +
1.256 +
1.257 + if(err != KErrNone)
1.258 + return err;
1.259 + // Synchronise with the server
1.260 + TRequestStatus reqStatus;
1.261 + iServer.Rendezvous(reqStatus);
1.262 +
1.263 + if (reqStatus!=KRequestPending)
1.264 + {
1.265 + iServer.Kill(0);
1.266 + }
1.267 + else
1.268 + {
1.269 + // Start the test harness
1.270 + iServer.Resume();
1.271 + // Server will call the reciprocal static synchronise call
1.272 + }
1.273 +
1.274 + User::WaitForRequest(reqStatus); // wait for start or death
1.275 + if(reqStatus.Int() != KErrNone)
1.276 + {
1.277 + iServer.Close();
1.278 + return reqStatus.Int();
1.279 + }
1.280 +
1.281 + aDevSoundName = iServer.Name();
1.282 +
1.283 + iServer.Logon(iStatus);
1.284 + SetActive();
1.285 +
1.286 + iAudioServer->IncrementDevSoundCount();
1.287 + return KErrNone;
1.288 + }
1.289 +
1.290 +
1.291 +CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread(CMMFAudioServer* aAudioServer): CActive(0)
1.292 + {
1.293 + iAudioServer = aAudioServer;
1.294 + }
1.295 +
1.296 +CStartAndMonitorDevSoundThread::~CStartAndMonitorDevSoundThread()
1.297 + {
1.298 + Cancel();
1.299 + }
1.300 +
1.301 +void CStartAndMonitorDevSoundThread::RunL()
1.302 + {
1.303 + iServer.Close();
1.304 + iAudioServer->DecrementDevSoundCount();
1.305 + }
1.306 +
1.307 +void CStartAndMonitorDevSoundThread::DoCancel()
1.308 + {
1.309 + iServer.LogonCancel(iStatus);
1.310 + }
1.311 +
1.312 +
1.313 +