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 "MmfAudioServer.h" sl@0: #include "MmfAudioServerStart.h" sl@0: #include "MmfDevSoundSession.h" sl@0: #include "MmfAudioServerSession.h" sl@0: #include "MmfDevSoundServer.h" sl@0: #include "MmfDevSoundServerStart.h" sl@0: #include "mmfbase.hrh" sl@0: sl@0: sl@0: static const TUid KUidDevSoundServer = {KUidMmfDevSoundServerDllUnicodeDefine}; sl@0: sl@0: const TInt KAudioServerShutDownDelay = 50000000; //50 sec sl@0: sl@0: sl@0: CMMFAudioServer* CMMFAudioServer::NewL() sl@0: { sl@0: CMMFAudioServer* s = new(ELeave) CMMFAudioServer(); sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return s; sl@0: } sl@0: sl@0: CMMFAudioServer::CMMFAudioServer() : sl@0: CMmfIpcServer(EPriorityStandard) sl@0: { sl@0: } sl@0: sl@0: void CMMFAudioServer::ConstructL() sl@0: { sl@0: // Call base class to Start server sl@0: StartL(KAudioServerName); sl@0: iDelayAudioServerShutDown = CDelayAudioServerShutDown::NewL(); sl@0: // Create an audio policy server sl@0: iAudioPolicyProxy = new (ELeave) RMMFAudioPolicyProxy(); sl@0: User::LeaveIfError(iAudioPolicyProxy->CreateServer(iPolicyServerHandle)); sl@0: } sl@0: sl@0: CMMFAudioServer::~CMMFAudioServer() sl@0: { sl@0: if (iDelayAudioServerShutDown) sl@0: { sl@0: iDelayAudioServerShutDown->Cancel(); sl@0: delete iDelayAudioServerShutDown; sl@0: } sl@0: iDevSoundServList.ResetAndDestroy(); sl@0: iDevSoundServList.Close(); sl@0: if( iAudioPolicyProxy != NULL) sl@0: { sl@0: iAudioPolicyProxy->Close(); sl@0: delete iAudioPolicyProxy; sl@0: } sl@0: iPolicyServerHandle.Close(); sl@0: } sl@0: sl@0: CMmfIpcSession* CMMFAudioServer::NewSessionL(const TVersion& aVersion) const sl@0: { sl@0: TVersion v(KMMFAudioServerVersion,KMMFAudioServerMinorVersionNumber,KMMFAudioServerBuildVersionNumber); sl@0: if(!User::QueryVersionSupported(v, aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: TInt i=0; sl@0: while(iIsActive()) sl@0: { sl@0: iDevSoundServList.Remove(i); sl@0: delete devSoundMonitorThread; sl@0: } sl@0: else sl@0: { sl@0: i++; sl@0: } sl@0: } sl@0: iDevSoundServList.Compress(); sl@0: sl@0: RMMFDevSoundServerProxy devSoundSessionHandle; sl@0: User::LeaveIfError(StartDevSoundServer(devSoundSessionHandle)); sl@0: CMMFAudioServerSession* audioServerSession = CMMFAudioServerSession::NewL(devSoundSessionHandle); sl@0: return audioServerSession; sl@0: } sl@0: sl@0: void CMMFAudioServer::IncrementSessionId() sl@0: { sl@0: iAudioServerSessionId++; sl@0: } sl@0: sl@0: void CMMFAudioServer::DecrementSessionId() sl@0: { sl@0: iAudioServerSessionId--; sl@0: } sl@0: sl@0: void CMMFAudioServer::IncrementDevSoundCount() sl@0: { sl@0: iDevSoundCount++; sl@0: if(iDevSoundCount) sl@0: iDelayAudioServerShutDown->Cancel(); //in the case we started the shutdown due to no more DevSound sl@0: } sl@0: sl@0: void CMMFAudioServer::DecrementDevSoundCount() sl@0: { sl@0: iDevSoundCount--; sl@0: if ( iDevSoundCount == 0 ) sl@0: { sl@0: iDelayAudioServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KAudioServerShutDownDelay)); sl@0: } sl@0: } sl@0: sl@0: void CMMFAudioServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/) sl@0: { sl@0: // For the session requested, send event to client sl@0: iSessionIter.SetToFirst(); sl@0: CMMFAudioServerSession* session = static_cast(iSessionIter++); sl@0: while (session != NULL) sl@0: { sl@0: if (session->AudioServerSessionId() == aSessionToAlert) sl@0: { sl@0: break; // Finished sl@0: } sl@0: session = static_cast(iSessionIter++); sl@0: } sl@0: } sl@0: sl@0: void CMMFAudioServer::LaunchRequest(TInt aSessionId) sl@0: { sl@0: iSessionIter.SetToFirst(); sl@0: CMMFAudioServerSession* session = static_cast(iSessionIter++); sl@0: while (session != NULL) sl@0: { sl@0: if (session->AudioServerSessionId() == aSessionId) sl@0: { sl@0: break; // Finished sl@0: } sl@0: session = static_cast(iSessionIter++); sl@0: } sl@0: } sl@0: sl@0: TInt CMMFAudioServer::StartDevSoundServer(RMMFDevSoundServerProxy& aDevSoundSessionHandle) const sl@0: { sl@0: RMessage2 message(Message()); sl@0: CStartAndMonitorDevSoundThread* monitorDevSound = NULL; sl@0: sl@0: TRAPD(err, monitorDevSound = CStartAndMonitorDevSoundThread::NewL(const_cast(this))); sl@0: if(err != KErrNone) sl@0: { sl@0: delete monitorDevSound; sl@0: return err; sl@0: } sl@0: sl@0: err = iDevSoundServList.Append(monitorDevSound); sl@0: if(err != KErrNone) sl@0: { sl@0: delete monitorDevSound; sl@0: return err; sl@0: } sl@0: sl@0: return monitorDevSound->StartDevSoundServer(message, aDevSoundSessionHandle); sl@0: sl@0: } sl@0: sl@0: sl@0: CMMFAudioServer::CDelayAudioServerShutDown* CMMFAudioServer::CDelayAudioServerShutDown::NewL() sl@0: { sl@0: CDelayAudioServerShutDown* self = new(ELeave) CDelayAudioServerShutDown; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CMMFAudioServer::CDelayAudioServerShutDown::CDelayAudioServerShutDown() : CActive(0) sl@0: { sl@0: } sl@0: sl@0: void CMMFAudioServer::CDelayAudioServerShutDown::ConstructL() sl@0: { sl@0: User::LeaveIfError(iShutDownTimer.CreateLocal()); sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown() sl@0: { sl@0: Cancel(); sl@0: iShutDownTimer.Close(); sl@0: } sl@0: sl@0: sl@0: void CMMFAudioServer::CDelayAudioServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay) sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CDelayedShutDown"), 1)); sl@0: iShutDownTimer.After(iStatus, aDelay); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CMMFAudioServer::CDelayAudioServerShutDown::RunL() sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: sl@0: void CMMFAudioServer::CDelayAudioServerShutDown::DoCancel() sl@0: { sl@0: iShutDownTimer.Cancel(); sl@0: } sl@0: sl@0: sl@0: CStartAndMonitorDevSoundThread* CStartAndMonitorDevSoundThread::NewL(CMMFAudioServer* aAudioServer) sl@0: { sl@0: CStartAndMonitorDevSoundThread* self = new(ELeave) CStartAndMonitorDevSoundThread(aAudioServer); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: void CStartAndMonitorDevSoundThread::ConstructL() sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: TInt CStartAndMonitorDevSoundThread::StartDevSoundServer(RMessage2& aMessage, RMMFDevSoundServerProxy& aDevSoundSessionHandle) sl@0: { sl@0: RThread clientThread; sl@0: TInt err = aMessage.Client(clientThread); sl@0: if (err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: RProcess clientProcess; sl@0: err = clientThread.Process(clientProcess); sl@0: if (err != KErrNone) sl@0: { sl@0: clientThread.Close(); sl@0: return err; sl@0: } sl@0: TProcessId clientProcessId(clientProcess.Id()); sl@0: sl@0: clientThread.Close(); sl@0: clientProcess.Close(); sl@0: sl@0: RServer2 devSoundServerHandle; sl@0: TDevSoundServerStart start(iAudioServer, clientProcessId, devSoundServerHandle);//Pass to DevSoundServer the clien't process ID sl@0: sl@0: const TUidType serverUid(KNullUid,KNullUid,KUidDevSoundServer); sl@0: sl@0: TThreadFunction serverFunc=CMMFDevSoundServer::StartThread; sl@0: sl@0: err = iServer.Create(_L(""), serverFunc, KDevSoundServerStackSize, sl@0: #ifdef SYMBIAN_USE_SEPARATE_HEAPS sl@0: KDevSoundServerInitHeapSize, KDevSoundServerMaxHeapSize, sl@0: #else sl@0: &User::Heap(), //shared heap is now default sl@0: #endif sl@0: &start, EOwnerProcess); sl@0: sl@0: sl@0: if(err != KErrNone) sl@0: return err; sl@0: // Synchronise with the server sl@0: TRequestStatus reqStatus; sl@0: iServer.Rendezvous(reqStatus); sl@0: sl@0: if (reqStatus!=KRequestPending) sl@0: { sl@0: iServer.Kill(0); sl@0: } sl@0: else sl@0: { sl@0: // Start the test harness sl@0: iServer.Resume(); sl@0: // Server will call the reciprocal static synchronise call sl@0: } sl@0: sl@0: User::WaitForRequest(reqStatus); // wait for start or death sl@0: if(reqStatus.Int() != KErrNone) sl@0: { sl@0: iServer.Close(); sl@0: devSoundServerHandle.Close(); sl@0: return reqStatus.Int(); sl@0: } sl@0: err = aDevSoundSessionHandle.Open(devSoundServerHandle); sl@0: sl@0: if(err != KErrNone) sl@0: { sl@0: iServer.Close(); sl@0: devSoundServerHandle.Close(); sl@0: return err; sl@0: } sl@0: aDevSoundSessionHandle.ShareProtected(); sl@0: iServer.Logon(iStatus); sl@0: SetActive(); sl@0: sl@0: iAudioServer->IncrementDevSoundCount(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread(CMMFAudioServer* aAudioServer): CActive(0) sl@0: { sl@0: iAudioServer = aAudioServer; sl@0: } sl@0: sl@0: CStartAndMonitorDevSoundThread::~CStartAndMonitorDevSoundThread() sl@0: { sl@0: Cancel(); sl@0: } sl@0: sl@0: void CStartAndMonitorDevSoundThread::RunL() sl@0: { sl@0: iServer.Close(); sl@0: iAudioServer->DecrementDevSoundCount(); sl@0: } sl@0: sl@0: void CStartAndMonitorDevSoundThread::DoCancel() sl@0: { sl@0: iServer.LogonCancel(iStatus); sl@0: } sl@0: sl@0: TInt RMMFDevSoundServerProxy::Open(RServer2& aDevSoundServerHandle) sl@0: { sl@0: TInt err = CreateSession(aDevSoundServerHandle, TVersion(KMMFDevSoundServerVersion, sl@0: KMMFDevSoundServerMinorVersionNumber, sl@0: KMMFDevSoundServerBuildVersionNumber), -1, EIpcSession_GlobalSharable); sl@0: return err; sl@0: } sl@0: