os/mm/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundserver.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <e32math.h>
sl@0
    17
#include "mmfdevsoundserver.h"
sl@0
    18
#include "mmfdevsoundserverstart.h"
sl@0
    19
#include "mmfdevsoundsession.h"
sl@0
    20
#include "mmfdevsoundserverconsts.h"
sl@0
    21
sl@0
    22
const TInt KDevSoundShutDownDelay = 0; //no delay
sl@0
    23
_LIT(KMMFDevSoundServerName, "MMFDevSoundServer-");
sl@0
    24
sl@0
    25
// ======== LOCAL FUNCTIONS ========
sl@0
    26
void Panic(TInt aPanicCode)
sl@0
    27
	{
sl@0
    28
	_LIT(KDevSoundServerPanicCategory, "mmfdevsoundserver");
sl@0
    29
	User::Panic(KDevSoundServerPanicCategory, aPanicCode);
sl@0
    30
	}
sl@0
    31
sl@0
    32
/**
sl@0
    33
	CMMFDevSoundServer* CMMFDevSoundServer::NewL
sl@0
    34
	Two-phased constructor.
sl@0
    35
 */
sl@0
    36
EXPORT_C CMMFDevSoundServer* CMMFDevSoundServer::NewL(
sl@0
    37
	MGlobalProperties* aGlobalProperties,
sl@0
    38
	TProcessId& aClientPID)
sl@0
    39
	{
sl@0
    40
	CMMFDevSoundServer* self = new(ELeave) CMMFDevSoundServer(aGlobalProperties,
sl@0
    41
															aClientPID);
sl@0
    42
	CleanupStack::PushL(self);
sl@0
    43
	self->ConstructL();
sl@0
    44
	CleanupStack::Pop(self);
sl@0
    45
	return self;
sl@0
    46
	}
sl@0
    47
sl@0
    48
/**
sl@0
    49
 	CMMFDevSoundServer::CMMFDevSoundServer
sl@0
    50
	C++ default constructor can NOT contain any code, that might leave.
sl@0
    51
 */
sl@0
    52
CMMFDevSoundServer::CMMFDevSoundServer(
sl@0
    53
	MGlobalProperties* aGlobalProperties,
sl@0
    54
	TProcessId& aClientPID) :
sl@0
    55
	CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions),
sl@0
    56
	iClientPID(aClientPID),
sl@0
    57
	iActualClientPID(aClientPID)
sl@0
    58
	{
sl@0
    59
	iGlobalProperties = aGlobalProperties;
sl@0
    60
	}
sl@0
    61
sl@0
    62
/**
sl@0
    63
 	CMMFDevSoundServer::ConstructL
sl@0
    64
 	Symbian 2nd phase constructor can leave.
sl@0
    65
 */
sl@0
    66
void CMMFDevSoundServer::ConstructL()
sl@0
    67
	{
sl@0
    68
	RProcess client;
sl@0
    69
	User::LeaveIfError(client.Open(iClientPID));
sl@0
    70
sl@0
    71
sl@0
    72
	client.Close();
sl@0
    73
sl@0
    74
	iDelayDevSoundShutDown = CDelayDevSoundShutDown::NewL();
sl@0
    75
sl@0
    76
	// Call base class to Start server
sl@0
    77
	StartL(KNullDesC);
sl@0
    78
	}
sl@0
    79
sl@0
    80
/**
sl@0
    81
	CMMFDevSoundServer::~CMMFDevSoundServer
sl@0
    82
	Destructor
sl@0
    83
*/
sl@0
    84
CMMFDevSoundServer::~CMMFDevSoundServer()
sl@0
    85
	{
sl@0
    86
	if (iDelayDevSoundShutDown)
sl@0
    87
		{
sl@0
    88
		iDelayDevSoundShutDown->Cancel();
sl@0
    89
		delete iDelayDevSoundShutDown;
sl@0
    90
		}
sl@0
    91
	}
sl@0
    92
sl@0
    93
/**
sl@0
    94
 	CMMFDevSoundServer::NewSessionL
sl@0
    95
 	Creates new session
sl@0
    96
 	(other items were commented in a header).
sl@0
    97
 */
sl@0
    98
CMmfIpcSession* CMMFDevSoundServer::NewSessionL(const TVersion& aVersion) const
sl@0
    99
	{
sl@0
   100
	CMmfIpcSession* devSoundSession = NULL;
sl@0
   101
	
sl@0
   102
	TRAPD(error, devSoundSession = CreateNewSessionL(aVersion));
sl@0
   103
	
sl@0
   104
	if (error!=KErrNone)
sl@0
   105
		{
sl@0
   106
		// session create failed, so flag for subsequent destruction of server
sl@0
   107
		CMMFDevSoundServer* mutableThis = const_cast<CMMFDevSoundServer*>(this);
sl@0
   108
		mutableThis->CheckForNoSessionsLeft();
sl@0
   109
		User::Leave(error);
sl@0
   110
		}
sl@0
   111
	return devSoundSession;
sl@0
   112
	}
sl@0
   113
sl@0
   114
/**
sl@0
   115
 	CMMFDevSoundServer::CreateNewSessionL
sl@0
   116
 	Guts of what would otherwise be in NewSessionL() itself
sl@0
   117
 */
sl@0
   118
CMmfIpcSession* CMMFDevSoundServer::CreateNewSessionL(const TVersion& aVersion) const
sl@0
   119
	{
sl@0
   120
	TVersion version(KMMFDevSoundServerVersion,
sl@0
   121
			KMMFDevSoundServerMinorVersionNumber,
sl@0
   122
			KMMFDevSoundServerBuildVersionNumber);
sl@0
   123
sl@0
   124
	if(!User::QueryVersionSupported(version, aVersion))
sl@0
   125
		{
sl@0
   126
		User::Leave(KErrNotSupported);
sl@0
   127
		}
sl@0
   128
sl@0
   129
	CMMFDevSoundSession* devSoundSession =
sl@0
   130
					CMMFDevSoundSession::NewL(*iGlobalProperties);
sl@0
   131
	return devSoundSession;
sl@0
   132
	}
sl@0
   133
sl@0
   134
/**
sl@0
   135
 	CMMFDevSoundServer::IncrementSessionId
sl@0
   136
 	Increments session count
sl@0
   137
 	(other items were commented in a header).
sl@0
   138
 */
sl@0
   139
void CMMFDevSoundServer::IncrementSessionId()
sl@0
   140
	{
sl@0
   141
	iDevSoundSessionId++;
sl@0
   142
	if (iDevSoundSessionId)
sl@0
   143
		{
sl@0
   144
		iDelayDevSoundShutDown->Cancel();
sl@0
   145
		}
sl@0
   146
	}
sl@0
   147
sl@0
   148
/**
sl@0
   149
 	CMMFDevSoundServer::DecrementSessionId
sl@0
   150
 	Decrements session count
sl@0
   151
 	(other items were commented in a header).
sl@0
   152
 */
sl@0
   153
void CMMFDevSoundServer::DecrementSessionId()
sl@0
   154
	{
sl@0
   155
	iDevSoundSessionId--;
sl@0
   156
	CheckForNoSessionsLeft();
sl@0
   157
	}
sl@0
   158
sl@0
   159
/**
sl@0
   160
 	CMMFDevSoundServer::CheckForNoSessionsLeft
sl@0
   161
 	If no sessions are left, we kick off timer, which closes down server after timeout
sl@0
   162
 	really meaning the server closes asynchronously
sl@0
   163
 */
sl@0
   164
void CMMFDevSoundServer::CheckForNoSessionsLeft()
sl@0
   165
	{
sl@0
   166
	if (iDevSoundSessionId == 0)
sl@0
   167
		{
sl@0
   168
		iDelayDevSoundShutDown->SetDelay(
sl@0
   169
					TTimeIntervalMicroSeconds32(KDevSoundShutDownDelay));
sl@0
   170
		}
sl@0
   171
	}
sl@0
   172
sl@0
   173
/**
sl@0
   174
 	CMMFDevSoundServer::SendEventToClient
sl@0
   175
 	For the session requested, send event to client
sl@0
   176
 	(other items were commented in a header).
sl@0
   177
 */
sl@0
   178
void CMMFDevSoundServer::SendEventToClient(TInt aSessionToAlert,
sl@0
   179
									TInt /*aSessionToBeLaunched*/)
sl@0
   180
	{
sl@0
   181
	iSessionIter.SetToFirst();
sl@0
   182
	CMMFDevSoundSession* session =
sl@0
   183
						static_cast<CMMFDevSoundSession*>(iSessionIter++);
sl@0
   184
sl@0
   185
	while (session != NULL)
sl@0
   186
		{
sl@0
   187
		if (session->DevSoundSessionId() == aSessionToAlert)
sl@0
   188
			{
sl@0
   189
			break;  // Finished
sl@0
   190
			}
sl@0
   191
		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
sl@0
   192
		}
sl@0
   193
	}
sl@0
   194
sl@0
   195
/**
sl@0
   196
 	CMMFDevSoundServer::LaunchRequest
sl@0
   197
 	Launches the DevSound servers waiting for Audio Policy.
sl@0
   198
 	(other items were commented in a header).
sl@0
   199
 */
sl@0
   200
void CMMFDevSoundServer::LaunchRequest(TInt aSessionId)
sl@0
   201
	{
sl@0
   202
	iSessionIter.SetToFirst();
sl@0
   203
	CMMFDevSoundSession* session =
sl@0
   204
					static_cast<CMMFDevSoundSession*>(iSessionIter++);
sl@0
   205
sl@0
   206
	while (session != NULL)
sl@0
   207
		{
sl@0
   208
		if (session->DevSoundSessionId() == aSessionId)
sl@0
   209
			{
sl@0
   210
			break;  // Finished
sl@0
   211
			}
sl@0
   212
		session = static_cast<CMMFDevSoundSession*>(iSessionIter++);
sl@0
   213
		}
sl@0
   214
	}
sl@0
   215
sl@0
   216
sl@0
   217
void CMMFDevSoundServer::RenamePrioritizeServer()
sl@0
   218
	{
sl@0
   219
	//Rename devsound server name
sl@0
   220
	RThread devsoundServerThread;
sl@0
   221
	TThreadId threadId;
sl@0
   222
	TName name;
sl@0
   223
	name.Append(KMMFDevSoundServerName); 
sl@0
   224
	threadId = devsoundServerThread.Id();
sl@0
   225
	name.AppendNum(threadId.Id(),EHex);
sl@0
   226
	//We are ignoring the error code returned from User::RenameThread
sl@0
   227
	//as it is not important here, may be for profiling
sl@0
   228
	User::RenameThread(name);
sl@0
   229
	
sl@0
   230
	//Set the devsound priority
sl@0
   231
	TThreadPriority devsoundServerPriority = static_cast<TThreadPriority>(KDevsoundServerPriority);
sl@0
   232
	devsoundServerThread.SetPriority(devsoundServerPriority);
sl@0
   233
	}
sl@0
   234
sl@0
   235
/**
sl@0
   236
 	CMMFDevSoundServer* CMMFDevSoundServer::NewL
sl@0
   237
 	Two-phased constructor.
sl@0
   238
 */
sl@0
   239
CMMFDevSoundServer::CDelayDevSoundShutDown*
sl@0
   240
CMMFDevSoundServer::CDelayDevSoundShutDown::NewL()
sl@0
   241
	{
sl@0
   242
	CDelayDevSoundShutDown* self = new(ELeave) CDelayDevSoundShutDown;
sl@0
   243
	CleanupStack::PushL(self);
sl@0
   244
	self->ConstructL();
sl@0
   245
	CleanupStack::Pop(self);
sl@0
   246
	return self;
sl@0
   247
	}
sl@0
   248
sl@0
   249
/**
sl@0
   250
	CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown
sl@0
   251
	C++ constructor
sl@0
   252
	(other items were commented in a header).
sl@0
   253
 */
sl@0
   254
CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown()
sl@0
   255
	: CActive(0)
sl@0
   256
	{
sl@0
   257
	}
sl@0
   258
sl@0
   259
/**
sl@0
   260
 	CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL
sl@0
   261
 	Symbian 2nd phase constructor can leave.
sl@0
   262
 */
sl@0
   263
void CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL()
sl@0
   264
	{
sl@0
   265
	User::LeaveIfError(iTimer.CreateLocal());
sl@0
   266
	CActiveScheduler::Add(this);
sl@0
   267
	}
sl@0
   268
sl@0
   269
/**
sl@0
   270
 	CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown
sl@0
   271
 	Destructor
sl@0
   272
 */
sl@0
   273
CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown()
sl@0
   274
	{
sl@0
   275
	Cancel();
sl@0
   276
	iTimer.Close();
sl@0
   277
	}
sl@0
   278
sl@0
   279
/**
sl@0
   280
 	CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay
sl@0
   281
 	Request a timeout after aDelay
sl@0
   282
 	(other items were commented in a header).
sl@0
   283
 */
sl@0
   284
void CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay(
sl@0
   285
		TTimeIntervalMicroSeconds32 aDelay)
sl@0
   286
	{
sl@0
   287
	__ASSERT_ALWAYS(!IsActive(), Panic(EMMFDevSoundServerIsActive));
sl@0
   288
	iTimer.After(iStatus, aDelay);
sl@0
   289
	SetActive();
sl@0
   290
	}
sl@0
   291
sl@0
   292
/**
sl@0
   293
 	CMMFDevSoundServer::CDelayDevSoundShutDown::RunL
sl@0
   294
 	Called by Active object framework after timer expires
sl@0
   295
 	(other items were commented in a header).
sl@0
   296
 */
sl@0
   297
void CMMFDevSoundServer::CDelayDevSoundShutDown::RunL()
sl@0
   298
	{
sl@0
   299
	CActiveScheduler::Stop();
sl@0
   300
	}
sl@0
   301
sl@0
   302
/**
sl@0
   303
 	CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel
sl@0
   304
 	Called by Active object framework when user cancels active object.
sl@0
   305
 	(other items were commented in a header).
sl@0
   306
 */
sl@0
   307
void CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel()
sl@0
   308
	{
sl@0
   309
	iTimer.Cancel();
sl@0
   310
	}
sl@0
   311
sl@0
   312
/**
sl@0
   313
 	CMMFDevSoundServer::SetClientProcessIdL
sl@0
   314
 */
sl@0
   315
void CMMFDevSoundServer::SetClientProcessIdL(TThreadId aTid)
sl@0
   316
	{
sl@0
   317
	
sl@0
   318
	RThread clientThread;
sl@0
   319
	User::LeaveIfError(clientThread.Open(aTid));
sl@0
   320
	CleanupClosePushL(clientThread);
sl@0
   321
	
sl@0
   322
	RProcess clientProcess;
sl@0
   323
	User::LeaveIfError(clientThread.Process(clientProcess));
sl@0
   324
	CleanupClosePushL(clientProcess);
sl@0
   325
	
sl@0
   326
	iActualClientPID = clientProcess.Id();
sl@0
   327
	CleanupStack::PopAndDestroy(2, &clientThread);	// clientProcess, clientThread		
sl@0
   328
	}
sl@0
   329
//GLOBAL FUNCTIONS
sl@0
   330
sl@0
   331
/**
sl@0
   332
 	This function raises a panic on the client of the DevSound Server
sl@0
   333
 	
sl@0
   334
 	@param  aError
sl@0
   335
			one of the several panic codes that may be raised by this dll on
sl@0
   336
			the client
sl@0
   337
 	
sl@0
   338
 	@panic  EMMFDevSoundPlayDataWithoutInitialize is raised when playdata is
sl@0
   339
			called without initialization
sl@0
   340
 	@panic  EMMFDevSoundRecordDataWithoutInitialize is raised when recorddata
sl@0
   341
			is called without initialization
sl@0
   342
 */
sl@0
   343
GLDEF_C void PanicClient(const RMmfIpcMessage& aMessage,
sl@0
   344
					TMMFDevSoundClientPanicCodes aPanicCode)
sl@0
   345
	{
sl@0
   346
	aMessage.Panic(KMMFDevSoundClientPanicCategory, aPanicCode);
sl@0
   347
	}
sl@0
   348
sl@0
   349
//  End of File