sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "MmfDevSoundServer.h" sl@0: #include "MmfDevSoundServerStart.h" sl@0: #include "MmfDevSoundSession.h" sl@0: sl@0: const TInt KDevSoundShutDownDelay = 0; //0 sec sl@0: _LIT(KMMFDevSoundServerName, "MMFDevSoundServer-"); sl@0: sl@0: sl@0: sl@0: EXPORT_C CMMFDevSoundServer* CMMFDevSoundServer::NewL(CMMFAudioServer* aAudioServer, TProcessId& aClientPID) sl@0: { sl@0: CMMFDevSoundServer* s = new(ELeave) CMMFDevSoundServer(aAudioServer, aClientPID); sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return s; sl@0: } sl@0: sl@0: CMMFDevSoundServer::CMMFDevSoundServer(CMMFAudioServer* aAudioServer, TProcessId& aClientPID) : sl@0: CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions), iClientPID(aClientPID) sl@0: { sl@0: iAudioServer = aAudioServer; sl@0: } sl@0: sl@0: void CMMFDevSoundServer::ConstructL() sl@0: { sl@0: RProcess client; sl@0: User::LeaveIfError(client.Open(iClientPID)); sl@0: iClientHasCaps = client.HasCapability(ECapabilityMultimediaDD, KSuppressPlatSecDiagnostic); sl@0: client.Close(); sl@0: sl@0: iDelayDevSoundShutDown = CDelayDevSoundShutDown::NewL(); sl@0: sl@0: // Call base class to Start server sl@0: StartL(KNullDesC); sl@0: } sl@0: sl@0: CMMFDevSoundServer::~CMMFDevSoundServer() sl@0: { sl@0: if (iDelayDevSoundShutDown) sl@0: { sl@0: iDelayDevSoundShutDown->Cancel(); sl@0: delete iDelayDevSoundShutDown; sl@0: } sl@0: } sl@0: sl@0: CMmfIpcSession* CMMFDevSoundServer::NewSessionL(const TVersion& aVersion) const sl@0: { sl@0: TVersion v(KMMFDevSoundServerVersion,KMMFDevSoundServerMinorVersionNumber,KMMFDevSoundServerBuildVersionNumber); sl@0: if(!User::QueryVersionSupported(v, aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: CMMFDevSoundSession* devSoundSession = CMMFDevSoundSession::NewL(iAudioServer->PolicyServerHandle()); sl@0: return devSoundSession; sl@0: } sl@0: sl@0: void CMMFDevSoundServer::IncrementSessionId() sl@0: { sl@0: iDevSoundSessionId++; sl@0: if(iDevSoundSessionId) sl@0: iDelayDevSoundShutDown->Cancel(); sl@0: sl@0: } sl@0: sl@0: void CMMFDevSoundServer::DecrementSessionId() sl@0: { sl@0: iDevSoundSessionId--; sl@0: if ( iDevSoundSessionId == 0 ) sl@0: { sl@0: iDelayDevSoundShutDown->SetDelay(TTimeIntervalMicroSeconds32(KDevSoundShutDownDelay)); sl@0: } sl@0: } sl@0: sl@0: void CMMFDevSoundServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/) sl@0: { sl@0: // For the session requested, send event to client sl@0: iSessionIter.SetToFirst(); sl@0: CMMFDevSoundSession* session = static_cast(iSessionIter++); sl@0: while (session != NULL) sl@0: { sl@0: if (session->DevSoundSessionId() == aSessionToAlert) sl@0: { sl@0: break; // Finished sl@0: } sl@0: session = static_cast(iSessionIter++); sl@0: } sl@0: } sl@0: sl@0: void CMMFDevSoundServer::LaunchRequest(TInt aSessionId) sl@0: { sl@0: iSessionIter.SetToFirst(); sl@0: CMMFDevSoundSession* session = static_cast(iSessionIter++); sl@0: while (session != NULL) sl@0: { sl@0: if (session->DevSoundSessionId() == aSessionId) sl@0: { sl@0: break; // Finished sl@0: } sl@0: session = static_cast(iSessionIter++); sl@0: } sl@0: } sl@0: sl@0: TBool CMMFDevSoundServer::CheckClientCapabilities() sl@0: { sl@0: return iClientHasCaps; sl@0: } sl@0: sl@0: void CMMFDevSoundServer::SetClientCapabilitiesL(TThreadId aTid) sl@0: { sl@0: RThread clientThread; sl@0: User::LeaveIfError(clientThread.Open(aTid)); sl@0: CleanupClosePushL(clientThread); sl@0: sl@0: RProcess clientProcess; sl@0: User::LeaveIfError(clientThread.Process(clientProcess)); sl@0: CleanupClosePushL(clientProcess); sl@0: sl@0: iClientHasCaps = clientProcess.HasCapability(ECapabilityMultimediaDD, KSuppressPlatSecDiagnostic); sl@0: sl@0: CleanupStack::PopAndDestroy(2, &clientThread); // clientProcess, clientThread sl@0: } sl@0: sl@0: void CMMFDevSoundServer::RenamePrioritizeServer() sl@0: { sl@0: //Rename devsound server name sl@0: RThread devsoundServerThread; sl@0: TThreadId threadId; sl@0: TName name; sl@0: name.Append(KMMFDevSoundServerName); sl@0: threadId = devsoundServerThread.Id(); sl@0: name.AppendNum(threadId.Id(),EHex); sl@0: //We are ignoring the error code returned from User::RenameThread sl@0: //as it is not important here, may be for profiling sl@0: User::RenameThread(name); sl@0: sl@0: //Set the devsound priority sl@0: TThreadPriority devsoundServerPriority = static_cast(KDevsoundServerPriority); sl@0: devsoundServerThread.SetPriority(devsoundServerPriority); sl@0: } sl@0: sl@0: CMMFDevSoundServer::CDelayDevSoundShutDown* CMMFDevSoundServer::CDelayDevSoundShutDown::NewL() sl@0: { sl@0: CDelayDevSoundShutDown* self = new(ELeave) CDelayDevSoundShutDown; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CMMFDevSoundServer::CDelayDevSoundShutDown::CDelayDevSoundShutDown() : CActive(0) sl@0: { sl@0: } sl@0: sl@0: void CMMFDevSoundServer::CDelayDevSoundShutDown::ConstructL() sl@0: { sl@0: User::LeaveIfError(iTimer.CreateLocal()); sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CMMFDevSoundServer::CDelayDevSoundShutDown::~CDelayDevSoundShutDown() sl@0: { sl@0: Cancel(); sl@0: iTimer.Close(); sl@0: } sl@0: sl@0: sl@0: void CMMFDevSoundServer::CDelayDevSoundShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay) sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), sl@0: User::Panic(_L("CDelayedShutDown"), 1)); sl@0: iTimer.After(iStatus, aDelay); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CMMFDevSoundServer::CDelayDevSoundShutDown::RunL() sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: void CMMFDevSoundServer::CDelayDevSoundShutDown::DoCancel() sl@0: { sl@0: iTimer.Cancel(); sl@0: } sl@0: sl@0: /** sl@0: @internalTechnology sl@0: sl@0: This function raises a panic on the client of the devsoundserver sl@0: sl@0: @param aError sl@0: one of the several panic codes that may be raised by this dll on the client sl@0: sl@0: @panic EMMFDevSoundPlayDataWithoutInitialize is raised when playdata is called without initialization sl@0: @panic EMMFDevSoundRecordDataWithoutInitialize is raised when recorddata is called without initialization sl@0: */ sl@0: GLDEF_C void PanicClient(const RMmfIpcMessage& aMessage, TMMFDevSoundClientPanicCodes aPanicCode) sl@0: { sl@0: aMessage.Panic(KMMFDevSoundClientPanicCategory, aPanicCode); sl@0: }