diff -r 000000000000 -r 40261b775718 mmlibs/mmfw/SecureDRM/src/Server/MmfDrmPluginServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmlibs/mmfw/SecureDRM/src/Server/MmfDrmPluginServer.cpp Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,359 @@ +// Copyright (c) 2007-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 +#include +#include "MmfDrmPluginServer.h" +#include "MmfDrmPluginServerStart.h" +#include "MmfDrmPluginServerSession.h" +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif + +CMMFDRMPluginServer* CMMFDRMPluginServer::NewL() + { + CMMFDRMPluginServer* s = new(ELeave) CMMFDRMPluginServer(); + CleanupStack::PushL(s); + s->ConstructL(); + CleanupStack::Pop(); + return s; + } + +CMMFDRMPluginServer::CMMFDRMPluginServer() : + CMmfIpcServer(EPriorityStandard) + { + } + +void CMMFDRMPluginServer::ConstructL() + { + iDelayServerShutDown = CDelayServerShutDown::NewL(); + // Call base class to Start server + StartL(KDrmPluginServerName); + } + +CMMFDRMPluginServer::~CMMFDRMPluginServer() + { + iControllerServList.ResetAndDestroy(); + iControllerServList.Close(); + delete iDelayServerShutDown; + } + +CMmfIpcSession* CMMFDRMPluginServer::NewSessionL(const TVersion& aVersion) const + { + TVersion v(KMMFDRMPluginServerVersion, + KMMFDRMPluginServerMinorVersionNumber, + KMMFDRMPluginServerBuildVersionNumber); + if(!User::QueryVersionSupported(v, aVersion)) + { + User::Leave(KErrNotSupported); + } + + for(TInt i = 0; i < iControllerServList.Count(); i++) + { + CStartAndMonitorControllerThread* controllerMonThread + = iControllerServList[i]; + if(!controllerMonThread->IsActive()) + { + iControllerServList.Remove(i); + delete controllerMonThread; + } + } + iControllerServList.Compress(); + + CMMFDRMPluginServerSession* session = CMMFDRMPluginServerSession::NewL(); + return session; + } + +void CMMFDRMPluginServer::IncrementSessionId() + { + iSessionCount++; + } + +void CMMFDRMPluginServer::DecrementSessionId() + { + iSessionCount--; + if(iSessionCount == 0 && iControllerCount == 0) + { + // Guarantee that server will be closed, after a period of time, even + // a session has been created without a controller thread initialized + if(!iDelayServerShutDown->IsActive()) + { + // If shut down timer has been started previously, that setup has the piority + iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout)); + } + } + } + +void CMMFDRMPluginServer::IncrementControllerCount() + { + iControllerCount++; + if(iControllerCount) + { + //In the case we started the shutdown due to no more controllers + iDelayServerShutDown->Cancel(); + } + } + +void CMMFDRMPluginServer::DecrementControllerCount() + { + iControllerCount--; + if (iControllerCount == 0) + { + iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout)); + } + } + +TInt CMMFDRMPluginServer::StartControllerServer(const RThread& aClientThread, TUint aMaxHeapSize, TBool aUseSharedHeap, + RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID, TUint aStackSize) const + { + CStartAndMonitorControllerThread* monitor = NULL; + + TRAPD(err, monitor = + CStartAndMonitorControllerThread::NewL(const_cast(this))); + if(err != KErrNone) + { + delete monitor; + return err; + } + + err = iControllerServList.Append(monitor); + if(err != KErrNone) + { + delete monitor; + return err; + } + + return monitor->StartControllerServer(aClientThread, aMaxHeapSize, aUseSharedHeap, + aControllerSessionHandle, aControllerTID, aStackSize); + } + +void CMMFDRMPluginServer::PanicControllerThread(TThreadId aTid, const TDesC& aCategory,TInt aReason) + { + for(TInt i = 0; i < iControllerServList.Count(); i++) + { + if(iControllerServList[i]->Thread().Id() == aTid) + { + iControllerServList[i]->Thread().Panic(aCategory, aReason); + return; + } + } + } + +void CMMFDRMPluginServer::KillControllerThread(TThreadId aTid, TInt aReason) + { + for(TInt i = 0; i < iControllerServList.Count(); i++) + { + if(iControllerServList[i]->Thread().Id() == aTid) + { + iControllerServList[i]->Thread().Kill(aReason); + return; + } + } + } + +TInt CMMFDRMPluginServer::SetThreadPriority(TThreadId aTid, TThreadPriority aPriority) + { + TBool threadFound = EFalse; + for(TInt i = 0; i < iControllerServList.Count(); i++) + { + const RThread& controllerThread = iControllerServList[i]->Thread(); + if (controllerThread.Id() == aTid) + { + if (controllerThread.Priority() != aPriority) + { + controllerThread.Suspend(); + controllerThread.SetPriority(aPriority); + controllerThread.Resume(); + } + threadFound = ETrue; + break; + } + } + return threadFound? KErrNone: KErrNotFound; + } + +CMMFDRMPluginServer::CDelayServerShutDown* CMMFDRMPluginServer::CDelayServerShutDown::NewL() + { + CDelayServerShutDown* self = new(ELeave) CDelayServerShutDown; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +CMMFDRMPluginServer::CDelayServerShutDown::CDelayServerShutDown() : CActive(0) + { + } + +void CMMFDRMPluginServer::CDelayServerShutDown::ConstructL() + { + User::LeaveIfError(iShutDownTimer.CreateLocal()); + CActiveScheduler::Add(this); + } + +CMMFDRMPluginServer::CDelayServerShutDown::~CDelayServerShutDown() + { + Cancel(); + iShutDownTimer.Close(); + } + +void CMMFDRMPluginServer::CDelayServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay) + { + __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CMMFDRMPluginServer"), 1)); + iShutDownTimer.After(iStatus, aDelay); + SetActive(); + } + +void CMMFDRMPluginServer::CDelayServerShutDown::RunL() + { + CActiveScheduler::Stop(); + } + + +void CMMFDRMPluginServer::CDelayServerShutDown::DoCancel() + { + iShutDownTimer.Cancel(); + } + +CStartAndMonitorControllerThread* CStartAndMonitorControllerThread::NewL(CMMFDRMPluginServer* aPluginServer) + { + CStartAndMonitorControllerThread* self = new(ELeave) CStartAndMonitorControllerThread(aPluginServer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +void CStartAndMonitorControllerThread::ConstructL() + { + CActiveScheduler::Add(this); + } + +TInt CStartAndMonitorControllerThread::StartControllerServer(const RThread& /*aClientThread*/, TUint aMaxHeapSize, TBool aUseSharedHeap, + RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID,TUint aStackSize) + { + Cancel(); + TInt err = KErrNone; + + RServer2 controllerServer; + TControllerProxyServerParams params; + params.iServer = &controllerServer; + params.iUsingSharedHeap = aUseSharedHeap; + + TName name; + name.Append(KMMFControllerProxyServerName); + + // Threads create own heap (default behaviour) + if(aMaxHeapSize < static_cast(KMinHeapSize)) + { + aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic + } + else if(aMaxHeapSize > static_cast(KMMFControllerProxyMaxHeapSize)) + { + aMaxHeapSize = KMMFControllerProxyMaxHeapSize; + } + + err = iServerThread.Create(name, &CMMFControllerProxyServer::StartThread, + aStackSize, KMinHeapSize, aMaxHeapSize, + ¶ms, EOwnerThread); + if (err) + { + return err; + } + + // Synchronise with the server + TRequestStatus reqStatus; + iServerThread.Rendezvous(reqStatus); + + if (reqStatus!=KRequestPending) + { + iServerThread.Kill(0); + } + else + { + iServerThread.SetPriority(EPriorityNormal); + iServerThread.Resume(); + // Server will call the reciprocal static synchronise call + } + + User::WaitForRequest(reqStatus); // wait for start or death + if(reqStatus.Int() != KErrNone) + { + iServerThread.Close(); + controllerServer.Close(); + return reqStatus.Int(); + } + + err = aControllerSessionHandle.Open(controllerServer); + if(err != KErrNone) + { + iServerThread.Close(); + controllerServer.Close(); + return err; + } + + iStatus = KRequestPending; + iServerThread.Logon(iStatus); + if (iStatus != KRequestPending) + { + // Failed to logon + aControllerSessionHandle.Close(); + iServerThread.Close(); + controllerServer.Close(); + return iStatus.Int(); + } + else + { + SetActive(); + } + + aControllerSessionHandle.ShareProtected(); + aControllerTID = iServerThread.Id(); + iDrmPluginServer->IncrementControllerCount(); + return KErrNone; + } + + +CStartAndMonitorControllerThread::CStartAndMonitorControllerThread(CMMFDRMPluginServer* aPluginServer) + : CActive(EPriorityStandard) + { + iDrmPluginServer = aPluginServer; + } + +CStartAndMonitorControllerThread::~CStartAndMonitorControllerThread() + { + Cancel(); + } + +void CStartAndMonitorControllerThread::RunL() + { + iServerThread.Close(); + iDrmPluginServer->DecrementControllerCount(); + } + +void CStartAndMonitorControllerThread::DoCancel() + { + iServerThread.LogonCancel(iStatus); + iServerThread.Kill(0); + iServerThread.Close(); + iDrmPluginServer->DecrementControllerCount(); + } + +TInt RMMFControllerServerProxy::Open(RServer2& aControllerServerHandle) + { + TInt err = CreateSession(aControllerServerHandle, KMMFControllerProxyVersion, + -1, EIpcSession_GlobalSharable); + return err; + }