1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,349 @@
1.4 +// Copyright (c) 2006-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 "mmfdevsoundserver.h"
1.21 +#include "mmfdevsoundserverstart.h"
1.22 +#include "mmfdevsoundsession.h"
1.23 +#include "mmfdevsoundserverconsts.h"
1.24 +
1.25 +const TInt KDevSoundShutDownDelay = 0; //no delay
1.26 +_LIT(KMMFDevSoundServerName, "MMFDevSoundServer-");
1.27 +
1.28 +// ======== LOCAL FUNCTIONS ========
1.29 +void Panic(TInt aPanicCode)
1.30 + {
1.31 + _LIT(KDevSoundServerPanicCategory, "mmfdevsoundserver");
1.32 + User::Panic(KDevSoundServerPanicCategory, aPanicCode);
1.33 + }
1.34 +
1.35 +/**
1.36 + CMMFDevSoundServer* CMMFDevSoundServer::NewL
1.37 + Two-phased constructor.
1.38 + */
1.39 +EXPORT_C CMMFDevSoundServer* CMMFDevSoundServer::NewL(
1.40 + MGlobalProperties* aGlobalProperties,
1.41 + TProcessId& aClientPID)
1.42 + {
1.43 + CMMFDevSoundServer* self = new(ELeave) CMMFDevSoundServer(aGlobalProperties,
1.44 + aClientPID);
1.45 + CleanupStack::PushL(self);
1.46 + self->ConstructL();
1.47 + CleanupStack::Pop(self);
1.48 + return self;
1.49 + }
1.50 +
1.51 +/**
1.52 + CMMFDevSoundServer::CMMFDevSoundServer
1.53 + C++ default constructor can NOT contain any code, that might leave.
1.54 + */
1.55 +CMMFDevSoundServer::CMMFDevSoundServer(
1.56 + MGlobalProperties* aGlobalProperties,
1.57 + TProcessId& aClientPID) :
1.58 + CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions),
1.59 + iClientPID(aClientPID),
1.60 + iActualClientPID(aClientPID)
1.61 + {
1.62 + iGlobalProperties = aGlobalProperties;
1.63 + }
1.64 +
1.65 +/**
1.66 + CMMFDevSoundServer::ConstructL
1.67 + Symbian 2nd phase constructor can leave.
1.68 + */
1.69 +void CMMFDevSoundServer::ConstructL()
1.70 + {
1.71 + RProcess client;
1.72 + User::LeaveIfError(client.Open(iClientPID));
1.73 +
1.74 +
1.75 + client.Close();
1.76 +
1.77 + iDelayDevSoundShutDown = CDelayDevSoundShutDown::NewL();
1.78 +
1.79 + // Call base class to Start server
1.80 + StartL(KNullDesC);
1.81 + }
1.82 +
1.83 +/**
1.84 + CMMFDevSoundServer::~CMMFDevSoundServer
1.85 + Destructor
1.86 +*/
1.87 +CMMFDevSoundServer::~CMMFDevSoundServer()
1.88 + {
1.89 + if (iDelayDevSoundShutDown)
1.90 + {
1.91 + iDelayDevSoundShutDown->Cancel();
1.92 + delete iDelayDevSoundShutDown;
1.93 + }
1.94 + }
1.95 +
1.96 +/**
1.97 + CMMFDevSoundServer::NewSessionL
1.98 + Creates new session
1.99 + (other items were commented in a header).
1.100 + */
1.101 +CMmfIpcSession* CMMFDevSoundServer::NewSessionL(const TVersion& aVersion) const
1.102 + {
1.103 + CMmfIpcSession* devSoundSession = NULL;
1.104 +
1.105 + TRAPD(error, devSoundSession = CreateNewSessionL(aVersion));
1.106 +
1.107 + if (error!=KErrNone)
1.108 + {
1.109 + // session create failed, so flag for subsequent destruction of server
1.110 + CMMFDevSoundServer* mutableThis = const_cast<CMMFDevSoundServer*>(this);
1.111 + mutableThis->CheckForNoSessionsLeft();
1.112 + User::Leave(error);
1.113 + }
1.114 + return devSoundSession;
1.115 + }
1.116 +
1.117 +/**
1.118 + CMMFDevSoundServer::CreateNewSessionL
1.119 + Guts of what would otherwise be in NewSessionL() itself
1.120 + */
1.121 +CMmfIpcSession* CMMFDevSoundServer::CreateNewSessionL(const TVersion& aVersion) const
1.122 + {
1.123 + TVersion version(KMMFDevSoundServerVersion,
1.124 + KMMFDevSoundServerMinorVersionNumber,
1.125 + KMMFDevSoundServerBuildVersionNumber);
1.126 +
1.127 + if(!User::QueryVersionSupported(version, aVersion))
1.128 + {
1.129 + User::Leave(KErrNotSupported);
1.130 + }
1.131 +
1.132 + CMMFDevSoundSession* devSoundSession =
1.133 + CMMFDevSoundSession::NewL(*iGlobalProperties);
1.134 + return devSoundSession;
1.135 + }
1.136 +
1.137 +/**
1.138 + CMMFDevSoundServer::IncrementSessionId
1.139 + Increments session count
1.140 + (other items were commented in a header).
1.141 + */
1.142 +void CMMFDevSoundServer::IncrementSessionId()
1.143 + {
1.144 + iDevSoundSessionId++;
1.145 + if (iDevSoundSessionId)
1.146 + {
1.147 + iDelayDevSoundShutDown->Cancel();
1.148 + }
1.149 + }
1.150 +
1.151 +/**
1.152 + CMMFDevSoundServer::DecrementSessionId
1.153 + Decrements session count
1.154 + (other items were commented in a header).
1.155 + */
1.156 +void CMMFDevSoundServer::DecrementSessionId()
1.157 + {
1.158 + iDevSoundSessionId--;
1.159 + CheckForNoSessionsLeft();
1.160 + }
1.161 +
1.162 +/**
1.163 + CMMFDevSoundServer::CheckForNoSessionsLeft
1.164 + If no sessions are left, we kick off timer, which closes down server after timeout
1.165 + really meaning the server closes asynchronously
1.166 + */
1.167 +void CMMFDevSoundServer::CheckForNoSessionsLeft()
1.168 + {
1.169 + if (iDevSoundSessionId == 0)
1.170 + {
1.171 + iDelayDevSoundShutDown->SetDelay(
1.172 + TTimeIntervalMicroSeconds32(KDevSoundShutDownDelay));
1.173 + }
1.174 + }
1.175 +
1.176 +/**
1.177 + CMMFDevSoundServer::SendEventToClient
1.178 + For the session requested, send event to client
1.179 + (other items were commented in a header).
1.180 + */
1.181 +void CMMFDevSoundServer::SendEventToClient(TInt aSessionToAlert,
1.182 + TInt /*aSessionToBeLaunched*/)
1.183 + {
1.184 + iSessionIter.SetToFirst();
1.185 + CMMFDevSoundSession* session =
1.186 + static_cast<CMMFDevSoundSession*>(iSessionIter++);
1.187 +
1.188 + while (session != NULL)
1.189 + {
1.190 + if (session->DevSoundSessionId() == aSessionToAlert)
1.191 + {
1.192 + break; // Finished
1.193 + }
1.194 + session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
1.195 + }
1.196 + }
1.197 +
1.198 +/**
1.199 + CMMFDevSoundServer::LaunchRequest
1.200 + Launches the DevSound servers waiting for Audio Policy.
1.201 + (other items were commented in a header).
1.202 + */
1.203 +void CMMFDevSoundServer::LaunchRequest(TInt aSessionId)
1.204 + {
1.205 + iSessionIter.SetToFirst();
1.206 + CMMFDevSoundSession* session =
1.207 + static_cast<CMMFDevSoundSession*>(iSessionIter++);
1.208 +
1.209 + while (session != NULL)
1.210 + {
1.211 + if (session->DevSoundSessionId() == aSessionId)
1.212 + {
1.213 + break; // Finished
1.214 + }
1.215 + session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
1.216 + }
1.217 + }
1.218 +
1.219 +
1.220 +void CMMFDevSoundServer::RenamePrioritizeServer()
1.221 + {
1.222 + //Rename devsound server name
1.223 + RThread devsoundServerThread;
1.224 + TThreadId threadId;
1.225 + TName name;
1.226 + name.Append(KMMFDevSoundServerName);
1.227 + threadId = devsoundServerThread.Id();
1.228 + name.AppendNum(threadId.Id(),EHex);
1.229 + //We are ignoring the error code returned from User::RenameThread
1.230 + //as it is not important here, may be for profiling
1.231 + User::RenameThread(name);
1.232 +
1.233 + //Set the devsound priority
1.234 + TThreadPriority devsoundServerPriority = static_cast<TThreadPriority>(KDevsoundServerPriority);
1.235 + devsoundServerThread.SetPriority(devsoundServerPriority);
1.236 + }
1.237 +
1.238 +/**
1.239 + CMMFDevSoundServer* CMMFDevSoundServer::NewL
1.240 + Two-phased constructor.
1.241 + */
1.242 +CMMFDevSoundServer::CDelayDevSoundShutDown*
1.243 +CMMFDevSoundServer::CDelayDevSoundShutDown::NewL()
1.244 + {
1.245 + CDelayDevSoundShutDown* self = new(ELeave) CDelayDevSoundShutDown;
1.246 + CleanupStack::PushL(self);
1.247 + self->ConstructL();
1.248 + CleanupStack::Pop(self);
1.249 + return self;
1.250 + }
1.251 +
1.252 +/**
1.253 + CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown
1.254 + C++ constructor
1.255 + (other items were commented in a header).
1.256 + */
1.257 +CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown()
1.258 + : CActive(0)
1.259 + {
1.260 + }
1.261 +
1.262 +/**
1.263 + CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL
1.264 + Symbian 2nd phase constructor can leave.
1.265 + */
1.266 +void CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL()
1.267 + {
1.268 + User::LeaveIfError(iTimer.CreateLocal());
1.269 + CActiveScheduler::Add(this);
1.270 + }
1.271 +
1.272 +/**
1.273 + CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown
1.274 + Destructor
1.275 + */
1.276 +CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown()
1.277 + {
1.278 + Cancel();
1.279 + iTimer.Close();
1.280 + }
1.281 +
1.282 +/**
1.283 + CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay
1.284 + Request a timeout after aDelay
1.285 + (other items were commented in a header).
1.286 + */
1.287 +void CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay(
1.288 + TTimeIntervalMicroSeconds32 aDelay)
1.289 + {
1.290 + __ASSERT_ALWAYS(!IsActive(), Panic(EMMFDevSoundServerIsActive));
1.291 + iTimer.After(iStatus, aDelay);
1.292 + SetActive();
1.293 + }
1.294 +
1.295 +/**
1.296 + CMMFDevSoundServer::CDelayDevSoundShutDown::RunL
1.297 + Called by Active object framework after timer expires
1.298 + (other items were commented in a header).
1.299 + */
1.300 +void CMMFDevSoundServer::CDelayDevSoundShutDown::RunL()
1.301 + {
1.302 + CActiveScheduler::Stop();
1.303 + }
1.304 +
1.305 +/**
1.306 + CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel
1.307 + Called by Active object framework when user cancels active object.
1.308 + (other items were commented in a header).
1.309 + */
1.310 +void CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel()
1.311 + {
1.312 + iTimer.Cancel();
1.313 + }
1.314 +
1.315 +/**
1.316 + CMMFDevSoundServer::SetClientProcessIdL
1.317 + */
1.318 +void CMMFDevSoundServer::SetClientProcessIdL(TThreadId aTid)
1.319 + {
1.320 +
1.321 + RThread clientThread;
1.322 + User::LeaveIfError(clientThread.Open(aTid));
1.323 + CleanupClosePushL(clientThread);
1.324 +
1.325 + RProcess clientProcess;
1.326 + User::LeaveIfError(clientThread.Process(clientProcess));
1.327 + CleanupClosePushL(clientProcess);
1.328 +
1.329 + iActualClientPID = clientProcess.Id();
1.330 + CleanupStack::PopAndDestroy(2, &clientThread); // clientProcess, clientThread
1.331 + }
1.332 +//GLOBAL FUNCTIONS
1.333 +
1.334 +/**
1.335 + This function raises a panic on the client of the DevSound Server
1.336 +
1.337 + @param aError
1.338 + one of the several panic codes that may be raised by this dll on
1.339 + the client
1.340 +
1.341 + @panic EMMFDevSoundPlayDataWithoutInitialize is raised when playdata is
1.342 + called without initialization
1.343 + @panic EMMFDevSoundRecordDataWithoutInitialize is raised when recorddata
1.344 + is called without initialization
1.345 + */
1.346 +GLDEF_C void PanicClient(const RMmfIpcMessage& aMessage,
1.347 + TMMFDevSoundClientPanicCodes aPanicCode)
1.348 + {
1.349 + aMessage.Panic(KMMFDevSoundClientPanicCategory, aPanicCode);
1.350 + }
1.351 +
1.352 +// End of File