devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,349 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32math.h>
+#include "mmfdevsoundserver.h"
+#include "mmfdevsoundserverstart.h"
+#include "mmfdevsoundsession.h"
+#include "mmfdevsoundserverconsts.h"
+
+const TInt KDevSoundShutDownDelay = 0; //no delay
+_LIT(KMMFDevSoundServerName, "MMFDevSoundServer-");
+
+// ======== LOCAL FUNCTIONS ========
+void Panic(TInt aPanicCode)
+	{
+	_LIT(KDevSoundServerPanicCategory, "mmfdevsoundserver");
+	User::Panic(KDevSoundServerPanicCategory, aPanicCode);
+	}
+
+/**
+	CMMFDevSoundServer* CMMFDevSoundServer::NewL
+	Two-phased constructor.
+ */
+EXPORT_C CMMFDevSoundServer* CMMFDevSoundServer::NewL(
+	MGlobalProperties* aGlobalProperties,
+	TProcessId& aClientPID)
+	{
+	CMMFDevSoundServer* self = new(ELeave) CMMFDevSoundServer(aGlobalProperties,
+															aClientPID);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+ 	CMMFDevSoundServer::CMMFDevSoundServer
+	C++ default constructor can NOT contain any code, that might leave.
+ */
+CMMFDevSoundServer::CMMFDevSoundServer(
+	MGlobalProperties* aGlobalProperties,
+	TProcessId& aClientPID) :
+	CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions),
+	iClientPID(aClientPID),
+	iActualClientPID(aClientPID)
+	{
+	iGlobalProperties = aGlobalProperties;
+	}
+
+/**
+ 	CMMFDevSoundServer::ConstructL
+ 	Symbian 2nd phase constructor can leave.
+ */
+void CMMFDevSoundServer::ConstructL()
+	{
+	RProcess client;
+	User::LeaveIfError(client.Open(iClientPID));
+
+
+	client.Close();
+
+	iDelayDevSoundShutDown = CDelayDevSoundShutDown::NewL();
+
+	// Call base class to Start server
+	StartL(KNullDesC);
+	}
+
+/**
+	CMMFDevSoundServer::~CMMFDevSoundServer
+	Destructor
+*/
+CMMFDevSoundServer::~CMMFDevSoundServer()
+	{
+	if (iDelayDevSoundShutDown)
+		{
+		iDelayDevSoundShutDown->Cancel();
+		delete iDelayDevSoundShutDown;
+		}
+	}
+
+/**
+ 	CMMFDevSoundServer::NewSessionL
+ 	Creates new session
+ 	(other items were commented in a header).
+ */
+CMmfIpcSession* CMMFDevSoundServer::NewSessionL(const TVersion& aVersion) const
+	{
+	CMmfIpcSession* devSoundSession = NULL;
+	
+	TRAPD(error, devSoundSession = CreateNewSessionL(aVersion));
+	
+	if (error!=KErrNone)
+		{
+		// session create failed, so flag for subsequent destruction of server
+		CMMFDevSoundServer* mutableThis = const_cast<CMMFDevSoundServer*>(this);
+		mutableThis->CheckForNoSessionsLeft();
+		User::Leave(error);
+		}
+	return devSoundSession;
+	}
+
+/**
+ 	CMMFDevSoundServer::CreateNewSessionL
+ 	Guts of what would otherwise be in NewSessionL() itself
+ */
+CMmfIpcSession* CMMFDevSoundServer::CreateNewSessionL(const TVersion& aVersion) const
+	{
+	TVersion version(KMMFDevSoundServerVersion,
+			KMMFDevSoundServerMinorVersionNumber,
+			KMMFDevSoundServerBuildVersionNumber);
+
+	if(!User::QueryVersionSupported(version, aVersion))
+		{
+		User::Leave(KErrNotSupported);
+		}
+
+	CMMFDevSoundSession* devSoundSession =
+					CMMFDevSoundSession::NewL(*iGlobalProperties);
+	return devSoundSession;
+	}
+
+/**
+ 	CMMFDevSoundServer::IncrementSessionId
+ 	Increments session count
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::IncrementSessionId()
+	{
+	iDevSoundSessionId++;
+	if (iDevSoundSessionId)
+		{
+		iDelayDevSoundShutDown->Cancel();
+		}
+	}
+
+/**
+ 	CMMFDevSoundServer::DecrementSessionId
+ 	Decrements session count
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::DecrementSessionId()
+	{
+	iDevSoundSessionId--;
+	CheckForNoSessionsLeft();
+	}
+
+/**
+ 	CMMFDevSoundServer::CheckForNoSessionsLeft
+ 	If no sessions are left, we kick off timer, which closes down server after timeout
+ 	really meaning the server closes asynchronously
+ */
+void CMMFDevSoundServer::CheckForNoSessionsLeft()
+	{
+	if (iDevSoundSessionId == 0)
+		{
+		iDelayDevSoundShutDown->SetDelay(
+					TTimeIntervalMicroSeconds32(KDevSoundShutDownDelay));
+		}
+	}
+
+/**
+ 	CMMFDevSoundServer::SendEventToClient
+ 	For the session requested, send event to client
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::SendEventToClient(TInt aSessionToAlert,
+									TInt /*aSessionToBeLaunched*/)
+	{
+	iSessionIter.SetToFirst();
+	CMMFDevSoundSession* session =
+						static_cast<CMMFDevSoundSession*>(iSessionIter++);
+
+	while (session != NULL)
+		{
+		if (session->DevSoundSessionId() == aSessionToAlert)
+			{
+			break;  // Finished
+			}
+		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
+		}
+	}
+
+/**
+ 	CMMFDevSoundServer::LaunchRequest
+ 	Launches the DevSound servers waiting for Audio Policy.
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::LaunchRequest(TInt aSessionId)
+	{
+	iSessionIter.SetToFirst();
+	CMMFDevSoundSession* session =
+					static_cast<CMMFDevSoundSession*>(iSessionIter++);
+
+	while (session != NULL)
+		{
+		if (session->DevSoundSessionId() == aSessionId)
+			{
+			break;  // Finished
+			}
+		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
+		}
+	}
+
+
+void CMMFDevSoundServer::RenamePrioritizeServer()
+	{
+	//Rename devsound server name
+	RThread devsoundServerThread;
+	TThreadId threadId;
+	TName name;
+	name.Append(KMMFDevSoundServerName); 
+	threadId = devsoundServerThread.Id();
+	name.AppendNum(threadId.Id(),EHex);
+	//We are ignoring the error code returned from User::RenameThread
+	//as it is not important here, may be for profiling
+	User::RenameThread(name);
+	
+	//Set the devsound priority
+	TThreadPriority devsoundServerPriority = static_cast<TThreadPriority>(KDevsoundServerPriority);
+	devsoundServerThread.SetPriority(devsoundServerPriority);
+	}
+
+/**
+ 	CMMFDevSoundServer* CMMFDevSoundServer::NewL
+ 	Two-phased constructor.
+ */
+CMMFDevSoundServer::CDelayDevSoundShutDown*
+CMMFDevSoundServer::CDelayDevSoundShutDown::NewL()
+	{
+	CDelayDevSoundShutDown* self = new(ELeave) CDelayDevSoundShutDown;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+	CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown
+	C++ constructor
+	(other items were commented in a header).
+ */
+CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown()
+	: CActive(0)
+	{
+	}
+
+/**
+ 	CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL
+ 	Symbian 2nd phase constructor can leave.
+ */
+void CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL()
+	{
+	User::LeaveIfError(iTimer.CreateLocal());
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ 	CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown
+ 	Destructor
+ */
+CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown()
+	{
+	Cancel();
+	iTimer.Close();
+	}
+
+/**
+ 	CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay
+ 	Request a timeout after aDelay
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay(
+		TTimeIntervalMicroSeconds32 aDelay)
+	{
+	__ASSERT_ALWAYS(!IsActive(), Panic(EMMFDevSoundServerIsActive));
+	iTimer.After(iStatus, aDelay);
+	SetActive();
+	}
+
+/**
+ 	CMMFDevSoundServer::CDelayDevSoundShutDown::RunL
+ 	Called by Active object framework after timer expires
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::CDelayDevSoundShutDown::RunL()
+	{
+	CActiveScheduler::Stop();
+	}
+
+/**
+ 	CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel
+ 	Called by Active object framework when user cancels active object.
+ 	(other items were commented in a header).
+ */
+void CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+/**
+ 	CMMFDevSoundServer::SetClientProcessIdL
+ */
+void CMMFDevSoundServer::SetClientProcessIdL(TThreadId aTid)
+	{
+	
+	RThread clientThread;
+	User::LeaveIfError(clientThread.Open(aTid));
+	CleanupClosePushL(clientThread);
+	
+	RProcess clientProcess;
+	User::LeaveIfError(clientThread.Process(clientProcess));
+	CleanupClosePushL(clientProcess);
+	
+	iActualClientPID = clientProcess.Id();
+	CleanupStack::PopAndDestroy(2, &clientThread);	// clientProcess, clientThread		
+	}
+//GLOBAL FUNCTIONS
+
+/**
+ 	This function raises a panic on the client of the DevSound Server
+ 	
+ 	@param  aError
+			one of the several panic codes that may be raised by this dll on
+			the client
+ 	
+ 	@panic  EMMFDevSoundPlayDataWithoutInitialize is raised when playdata is
+			called without initialization
+ 	@panic  EMMFDevSoundRecordDataWithoutInitialize is raised when recorddata
+			is called without initialization
+ */
+GLDEF_C void PanicClient(const RMmfIpcMessage& aMessage,
+					TMMFDevSoundClientPanicCodes aPanicCode)
+	{
+	aMessage.Panic(KMMFDevSoundClientPanicCategory, aPanicCode);
+	}
+
+//  End of File