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