os/mm/mmlibs/mmfw/SecureDRM/src/Server/MmfDrmPluginServer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <e32math.h>
    17 #include <mmf/common/mmfcontrollerframework.h>
    18 #include "MmfDrmPluginServer.h"
    19 #include "MmfDrmPluginServerStart.h"
    20 #include "MmfDrmPluginServerSession.h"
    21 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    22 #include <mmf/common/mmfcontrollerframeworkclasses.h>
    23 #endif
    24 
    25 CMMFDRMPluginServer* CMMFDRMPluginServer::NewL()
    26 	{
    27 	CMMFDRMPluginServer* s = new(ELeave) CMMFDRMPluginServer();
    28 	CleanupStack::PushL(s);
    29 	s->ConstructL();
    30 	CleanupStack::Pop();
    31 	return s;
    32 	}
    33 
    34 CMMFDRMPluginServer::CMMFDRMPluginServer() :
    35 	CMmfIpcServer(EPriorityStandard)
    36 	{
    37 	}
    38 
    39 void CMMFDRMPluginServer::ConstructL()
    40 	{
    41 	iDelayServerShutDown = CDelayServerShutDown::NewL();
    42 	// Call base class to Start server
    43 	StartL(KDrmPluginServerName);
    44 	}
    45 
    46 CMMFDRMPluginServer::~CMMFDRMPluginServer()
    47 	{
    48 	iControllerServList.ResetAndDestroy();
    49 	iControllerServList.Close();
    50 	delete iDelayServerShutDown;
    51 	}
    52 
    53 CMmfIpcSession* CMMFDRMPluginServer::NewSessionL(const TVersion& aVersion) const
    54 	{
    55 	TVersion v(KMMFDRMPluginServerVersion,
    56 				KMMFDRMPluginServerMinorVersionNumber,
    57 				KMMFDRMPluginServerBuildVersionNumber);
    58 	if(!User::QueryVersionSupported(v, aVersion))
    59 		{
    60 		User::Leave(KErrNotSupported);
    61 		}
    62 		
    63 	for(TInt i = 0; i < iControllerServList.Count(); i++)
    64 		{
    65 		CStartAndMonitorControllerThread* controllerMonThread 
    66 			= iControllerServList[i];
    67 		if(!controllerMonThread->IsActive())
    68 			{
    69 			iControllerServList.Remove(i);
    70 			delete controllerMonThread;
    71 			}
    72 		}
    73 	iControllerServList.Compress();
    74 	
    75 	CMMFDRMPluginServerSession* session = CMMFDRMPluginServerSession::NewL();
    76 	return session;
    77 	}
    78 
    79 void CMMFDRMPluginServer::IncrementSessionId()
    80 	{
    81 	iSessionCount++;
    82 	}
    83 
    84 void CMMFDRMPluginServer::DecrementSessionId()
    85 	{
    86 	iSessionCount--;
    87 	if(iSessionCount == 0 && iControllerCount == 0)
    88 		{
    89 		// Guarantee that server will be closed, after a period of time, even
    90 		// a session has been created without a controller thread initialized 
    91 		if(!iDelayServerShutDown->IsActive())
    92 			{
    93 			// If shut down timer has been started previously, that setup has the piority
    94 			iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout));
    95 			}
    96 		}
    97 	}
    98 
    99 void CMMFDRMPluginServer::IncrementControllerCount()
   100 	{
   101 	iControllerCount++;
   102 	if(iControllerCount)
   103 		{
   104 		//In the case we started the shutdown due to no more controllers
   105 		iDelayServerShutDown->Cancel(); 
   106 		}
   107 	}
   108 
   109 void CMMFDRMPluginServer::DecrementControllerCount()
   110 	{
   111 	iControllerCount--;
   112     if (iControllerCount == 0)
   113 		{
   114 		iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout));
   115  		}
   116 	}
   117 	
   118 TInt CMMFDRMPluginServer::StartControllerServer(const RThread& aClientThread, TUint aMaxHeapSize, TBool aUseSharedHeap,
   119 											RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID, TUint aStackSize) const
   120 	{
   121 	CStartAndMonitorControllerThread* monitor = NULL;
   122 
   123 	TRAPD(err, monitor = 
   124 		CStartAndMonitorControllerThread::NewL(const_cast<CMMFDRMPluginServer*>(this)));
   125 	if(err != KErrNone)
   126 		{
   127 		delete monitor;
   128 		return err;
   129 		}
   130 
   131 	err = iControllerServList.Append(monitor);
   132 	if(err != KErrNone)
   133 		{
   134 		delete monitor;
   135 		return err;
   136 		}
   137 	
   138 	return monitor->StartControllerServer(aClientThread, aMaxHeapSize, aUseSharedHeap, 
   139 										aControllerSessionHandle, aControllerTID, aStackSize);
   140 	}
   141 
   142 void CMMFDRMPluginServer::PanicControllerThread(TThreadId aTid, const TDesC& aCategory,TInt aReason)
   143 	{
   144 	for(TInt i = 0; i < iControllerServList.Count(); i++)
   145 		{
   146 		if(iControllerServList[i]->Thread().Id() == aTid)
   147 			{
   148 			iControllerServList[i]->Thread().Panic(aCategory, aReason);
   149 			return;
   150 			}
   151 		}
   152 	}
   153 
   154 void CMMFDRMPluginServer::KillControllerThread(TThreadId aTid, TInt aReason)
   155 	{
   156 	for(TInt i = 0; i < iControllerServList.Count(); i++)
   157 		{
   158 		if(iControllerServList[i]->Thread().Id() == aTid)
   159 			{
   160 			iControllerServList[i]->Thread().Kill(aReason);
   161 			return;
   162 			}
   163 		}
   164 	}
   165 
   166 TInt CMMFDRMPluginServer::SetThreadPriority(TThreadId aTid, TThreadPriority aPriority)
   167 	{
   168 	TBool threadFound = EFalse;
   169 	for(TInt i = 0; i < iControllerServList.Count(); i++)
   170 		{
   171 		const RThread& controllerThread = iControllerServList[i]->Thread();
   172 		if (controllerThread.Id() == aTid)
   173 			{
   174 			if (controllerThread.Priority() != aPriority)
   175 				{
   176 				controllerThread.Suspend();
   177 				controllerThread.SetPriority(aPriority);
   178 				controllerThread.Resume();
   179 				}
   180 			threadFound = ETrue;
   181 			break;
   182 			}
   183 		}
   184 	return threadFound? KErrNone: KErrNotFound;
   185 	}
   186 
   187 CMMFDRMPluginServer::CDelayServerShutDown* CMMFDRMPluginServer::CDelayServerShutDown::NewL()
   188 	{
   189 	CDelayServerShutDown* self = new(ELeave) CDelayServerShutDown;
   190 	CleanupStack::PushL(self);
   191 	self->ConstructL();
   192 	CleanupStack::Pop();
   193 	return self;
   194 	}
   195 
   196 CMMFDRMPluginServer::CDelayServerShutDown::CDelayServerShutDown() : CActive(0)
   197 	{
   198 	}
   199         
   200 void CMMFDRMPluginServer::CDelayServerShutDown::ConstructL()
   201 	{
   202 	User::LeaveIfError(iShutDownTimer.CreateLocal());
   203 	CActiveScheduler::Add(this);
   204 	}
   205 
   206 CMMFDRMPluginServer::CDelayServerShutDown::~CDelayServerShutDown()
   207 	{
   208 	Cancel();
   209 	iShutDownTimer.Close();
   210 	}
   211 
   212 void CMMFDRMPluginServer::CDelayServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay)
   213 	{
   214 	__ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CMMFDRMPluginServer"), 1));
   215 	iShutDownTimer.After(iStatus, aDelay);
   216 	SetActive();
   217 	}
   218 
   219 void CMMFDRMPluginServer::CDelayServerShutDown::RunL()
   220 	{
   221 	CActiveScheduler::Stop();
   222 	}
   223 
   224 
   225 void CMMFDRMPluginServer::CDelayServerShutDown::DoCancel()
   226 	{
   227 	iShutDownTimer.Cancel();
   228 	}
   229 
   230 CStartAndMonitorControllerThread* CStartAndMonitorControllerThread::NewL(CMMFDRMPluginServer* aPluginServer)
   231 	{
   232 	CStartAndMonitorControllerThread* self = new(ELeave) CStartAndMonitorControllerThread(aPluginServer);
   233 	CleanupStack::PushL(self);
   234 	self->ConstructL();
   235 	CleanupStack::Pop();
   236 	return self;
   237 	}
   238 
   239 void CStartAndMonitorControllerThread::ConstructL()
   240 	{
   241 	CActiveScheduler::Add(this);
   242 	}
   243 	
   244 TInt CStartAndMonitorControllerThread::StartControllerServer(const RThread& /*aClientThread*/, TUint aMaxHeapSize, TBool aUseSharedHeap,
   245 													RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID,TUint aStackSize)
   246 	{
   247 	Cancel();
   248 	TInt err = KErrNone;
   249 
   250 	RServer2 controllerServer;	
   251 	TControllerProxyServerParams params;
   252 	params.iServer = &controllerServer;
   253 	params.iUsingSharedHeap = aUseSharedHeap;
   254 	
   255 	TName name;
   256 	name.Append(KMMFControllerProxyServerName);
   257 	
   258 	// Threads create own heap (default behaviour)
   259 	if(aMaxHeapSize < static_cast<TUint>(KMinHeapSize))
   260 		{
   261 		aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic
   262 		}
   263 	else if(aMaxHeapSize >  static_cast<TUint>(KMMFControllerProxyMaxHeapSize))
   264 		{
   265 		aMaxHeapSize = KMMFControllerProxyMaxHeapSize;
   266 		}
   267 	
   268 	err = iServerThread.Create(name, &CMMFControllerProxyServer::StartThread,
   269 		aStackSize, KMinHeapSize, aMaxHeapSize, 
   270 		&params, EOwnerThread);
   271 	if (err)
   272 		{
   273 		return err;
   274 		}
   275 		
   276 	// Synchronise with the server
   277 	TRequestStatus reqStatus;
   278 	iServerThread.Rendezvous(reqStatus);
   279 	
   280 	if (reqStatus!=KRequestPending)
   281 		{
   282 		iServerThread.Kill(0);
   283 		}
   284 	else
   285 		{
   286 		iServerThread.SetPriority(EPriorityNormal);
   287 		iServerThread.Resume();
   288 		// Server will call the reciprocal static synchronise call	
   289 		}
   290 
   291 	User::WaitForRequest(reqStatus); // wait for start or death
   292 	if(reqStatus.Int() != KErrNone)
   293 		{
   294 		iServerThread.Close();
   295 		controllerServer.Close();
   296 		return reqStatus.Int();
   297 		}
   298 	
   299 	err = aControllerSessionHandle.Open(controllerServer);
   300 	if(err != KErrNone)
   301 		{
   302 		iServerThread.Close();
   303 		controllerServer.Close();
   304 		return err;
   305 		}
   306 	
   307 	iStatus = KRequestPending;
   308 	iServerThread.Logon(iStatus);
   309 	if (iStatus != KRequestPending)
   310 		{
   311 		// Failed to logon
   312 		aControllerSessionHandle.Close();
   313 		iServerThread.Close();
   314 		controllerServer.Close();
   315 		return iStatus.Int();
   316 		}
   317 	else
   318 		{
   319 		SetActive();
   320 		}
   321 		
   322 	aControllerSessionHandle.ShareProtected();
   323 	aControllerTID = iServerThread.Id();
   324 	iDrmPluginServer->IncrementControllerCount();
   325 	return KErrNone;
   326 	}
   327 
   328 
   329 CStartAndMonitorControllerThread::CStartAndMonitorControllerThread(CMMFDRMPluginServer* aPluginServer)
   330 	: CActive(EPriorityStandard)
   331 	{
   332 	iDrmPluginServer = aPluginServer;
   333 	}
   334 
   335 CStartAndMonitorControllerThread::~CStartAndMonitorControllerThread()
   336 	{
   337 	Cancel();
   338 	}
   339     
   340 void CStartAndMonitorControllerThread::RunL()
   341 	{
   342 	iServerThread.Close();
   343 	iDrmPluginServer->DecrementControllerCount();
   344 	}
   345 
   346 void CStartAndMonitorControllerThread::DoCancel()
   347 	{
   348 	iServerThread.LogonCancel(iStatus);
   349 	iServerThread.Kill(0);
   350 	iServerThread.Close();
   351 	iDrmPluginServer->DecrementControllerCount();
   352 	}
   353 
   354 TInt RMMFControllerServerProxy::Open(RServer2& aControllerServerHandle)
   355 	{
   356 	TInt err = CreateSession(aControllerServerHandle, KMMFControllerProxyVersion, 
   357 							-1, EIpcSession_GlobalSharable);
   358 	return err;
   359 	}