mmlibs/mmfw/src/ControllerFramework/MMFControllerFramework.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2002-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/server/mmfdrmpluginserverproxy.h>
       
    18 #include "mmfcontrollerframework.h"
       
    19 #include "mmfcontroller.h"
       
    20 #include "mmfcontrollerheap.h"
       
    21 #include "mmfcontrollerframeworkpriv.h"
       
    22 #include "mmfcontrollerpatchdata.h"
       
    23 
       
    24 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    25 #include <mmf/common/mmfcontrollerextendeddata.h>
       
    26 #include <mmf/common/mmfcustomcommandparsermanager.h>
       
    27 #include <mmf/common/mmfcontrollerframeworkclasses.h>
       
    28 #endif
       
    29 
       
    30 // Panic
       
    31    
       
    32 enum
       
    33 	{
       
    34 	EPanicHeapHalfOpen=1,
       
    35 	EPanicHeapOpenWithoutTls,
       
    36 	EPanicReleaseWithoutRegister,
       
    37 	EPanicBadInvariant
       
    38 	};
       
    39 	
       
    40 #ifdef _DEBUG
       
    41 static void Panic(TInt aReason)
       
    42 	{
       
    43 	_LIT(KControllerFramework, "ControllerFramework");
       
    44 	User::Panic(KControllerFramework, aReason);
       
    45 	}
       
    46 #endif
       
    47 
       
    48 EXPORT_C RMMFControllerProxy::RMMFControllerProxy() :
       
    49 	iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFControllerProxy, KMMFObjectHandleControllerProxy)),
       
    50 	iLogonAO(NULL), iThreadPriority(static_cast<TThreadPriority>(KDefaultMMFControllerThreadPriority)), iFlags(0)
       
    51 	{
       
    52 	iSubThread.Close();//iSubThread is automatically initialised to be a handle to this thread!
       
    53 	}
       
    54 
       
    55 TInt RMMFControllerProxy::LoadController(
       
    56 	TUid aControllerUid, 
       
    57  	const CMMFControllerImplementationInformation& aControllerInfo,
       
    58  	TBool aUseSharedHeap,
       
    59  	TBool aNoDRMCap)
       
    60 	{
       
    61 	// First check that we haven't already created the subthread
       
    62 	if (iSubThread.Handle() != 0)
       
    63 		return KErrAlreadyExists;
       
    64 	
       
    65 #ifdef SYMBIAN_FORCE_USE_SHARED_HEAP
       
    66 	aUseSharedHeap = ETrue;
       
    67 #endif
       
    68 
       
    69 	//determine what maximum heap size this thread should be created with
       
    70 	TUint maxHeapSize =0;
       
    71 	TInt error = KErrNone;
       
    72 	maxHeapSize = aControllerInfo.HeapSpaceRequired();
       
    73 	TUint stackSize = aControllerInfo.StackSize();
       
    74 	
       
    75 	ASSERT(!iLogonAO);
       
    76 	TRAP(error, iLogonAO = CLogonMonitor::NewL(this));
       
    77 	
       
    78 	if (!error)
       
    79 		{
       
    80 		if (aNoDRMCap && aControllerInfo.SupportsSecureDRMProcessMode())
       
    81 			{
       
    82 			error = DoCreateSessionForNoDRMCapClient(maxHeapSize, aUseSharedHeap, stackSize);
       
    83 			}
       
    84 		else
       
    85 			{
       
    86 			// server2 will be set in this function call
       
    87 			error = DoCreateSubThread(&iLogonAO->Server(), maxHeapSize, aUseSharedHeap, stackSize);
       
    88 		
       
    89 			// Now create a session with the controller proxy server running in the subthread
       
    90 			if (!error)
       
    91 				{
       
    92 				// create a session with iServer2 (local server)
       
    93 				error = CreateSession(iLogonAO->Server(), KMMFControllerProxyVersion);
       
    94 				}
       
    95 			}
       
    96 		}
       
    97 
       
    98 	// Finally, tell the controller proxy server to load the relevant plugin
       
    99 	if (!error)
       
   100 		{
       
   101 		TMMFUidPckg uidPckg(aControllerUid);
       
   102 		error = SendSync(iDestinationPckg, 
       
   103 						 EMMFControllerProxyLoadControllerPluginByUid, 
       
   104 						 uidPckg, 
       
   105 						 KNullDesC8);
       
   106 		}
       
   107 
       
   108 	// If an error occurred with any of the above, close all the handles
       
   109 	if (error)
       
   110 		Close();
       
   111 
       
   112 	return error;
       
   113 	}
       
   114 
       
   115 
       
   116 EXPORT_C TInt RMMFControllerProxy::LoadController(TUid aControllerUid, TBool aUseSharedHeap)
       
   117 	{
       
   118  	CMMFControllerImplementationInformation* controllerInfo = NULL;
       
   119  	
       
   120  	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
       
   121 	if (!err && controllerInfo)
       
   122 		{
       
   123 		err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, EFalse);
       
   124 		delete controllerInfo;
       
   125 		}
       
   126  	return err;
       
   127 	}
       
   128 
       
   129 EXPORT_C TInt RMMFControllerProxy::LoadController(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
       
   130 	{
       
   131 	return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, EFalse);
       
   132 	}
       
   133 
       
   134 EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(TUid aControllerUid, TBool aUseSharedHeap)
       
   135 	{
       
   136 	CMMFControllerImplementationInformation* controllerInfo = NULL;
       
   137 	
       
   138 	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
       
   139 	if (!err && controllerInfo)
       
   140 		{
       
   141 		err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, ETrue);
       
   142 		delete controllerInfo;
       
   143 		}
       
   144 	return err;
       
   145 	}
       
   146 	
       
   147 EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
       
   148 	{
       
   149 	return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, ETrue);
       
   150 	}
       
   151 
       
   152 TUint RMMFControllerProxy::ControllersMaxHeapSizeL(TUid aControllerUid)
       
   153 	{
       
   154 	CMMFControllerImplementationInformation* controllerInfo = NULL;
       
   155 
       
   156 	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
       
   157 
       
   158 
       
   159 	TUint maxHeapSize = KMMFDefaultControllerThreadHeapSize;
       
   160 	
       
   161 	if((err != KErrNone) && (err != KErrCorrupt))
       
   162 		{
       
   163 		delete controllerInfo;
       
   164 		User::Leave(err);
       
   165 		}
       
   166 
       
   167 
       
   168 	if(controllerInfo && (err == KErrNone))
       
   169 		maxHeapSize = controllerInfo->HeapSpaceRequired();
       
   170 
       
   171 	delete controllerInfo;
       
   172 
       
   173 	return maxHeapSize;
       
   174 	}
       
   175 
       
   176 
       
   177 TInt RMMFControllerProxy::DoCreateSubThread(RServer2* aServer2, TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
       
   178 	{
       
   179 	TInt error = KErrNone;
       
   180 
       
   181 	TControllerProxyServerParams params;
       
   182 	params.iServer = aServer2;
       
   183 	params.iUsingSharedHeap = aUseSharedHeap;
       
   184 
       
   185 #ifdef SYMBIAN_USE_CLIENT_HEAP
       
   186 	// controller threads share the *client* heap (intended for out of memory testing)
       
   187 	error = iSubThread.Create(_L(""), &CMMFControllerProxyServer::StartThread, 
       
   188 			aStackSize, NULL, &params, EOwnerThread);
       
   189 #else
       
   190 	if( aUseSharedHeap )
       
   191 		{
       
   192 		//controller threads all share a controller heap
       
   193 		CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
       
   194 		if(contHeap == NULL)
       
   195 			{
       
   196 			TRAP(error, contHeap = CMMFControllerHeap::NewL());
       
   197 			if(error)
       
   198 				{			
       
   199 				return error;	
       
   200 				}
       
   201 				
       
   202 			Dll::SetTls(contHeap);
       
   203 			}
       
   204 			
       
   205 		__ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap)==0, Panic(EPanicHeapHalfOpen));
       
   206 			
       
   207 		RHeap* sharedHeap = contHeap->RegisterHeap();
       
   208 		// We've registered, so record the fact so can "unregister" on close or error
       
   209 		iFlags |= EFlagOpenedSharedHeap; 
       
   210 		
       
   211 		error = iSubThread.Create(KNullDesC, &CMMFControllerProxyServer::StartThread,
       
   212 				aStackSize, sharedHeap, 						
       
   213 				&params, EOwnerThread);		
       
   214 		}
       
   215 	else
       
   216 		{	
       
   217 		// Threads create own heap (default behaviour)
       
   218 		if(aMaxHeapSize < static_cast<TUint>(KMinHeapSize))
       
   219 			aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic
       
   220 		else if(aMaxHeapSize >  static_cast<TUint>(KMMFControllerProxyMaxHeapSize))
       
   221 			aMaxHeapSize = KMMFControllerProxyMaxHeapSize;
       
   222 		
       
   223 		TThreadCreateInfo threadSettings (KNullDesC, &CMMFControllerProxyServer::StartThread,
       
   224 										  aStackSize, &params);
       
   225 		threadSettings.SetCreateHeap(KMinHeapSize, aMaxHeapSize);
       
   226 		threadSettings.SetOwner(EOwnerThread);
       
   227 		threadSettings.SetPaging(TThreadCreateInfo::EUnpaged);
       
   228 		
       
   229 		error = iSubThread.Create(threadSettings);
       
   230 		}
       
   231 #endif
       
   232 
       
   233 	if (error)
       
   234 		{
       
   235 		return error;
       
   236 		}
       
   237 
       
   238 	TRequestStatus rendezvous;
       
   239 	iSubThread.Rendezvous(rendezvous);
       
   240 	if (rendezvous != KRequestPending)
       
   241 		{
       
   242 		iSubThread.Kill(0);
       
   243 		}
       
   244 	else
       
   245 		{
       
   246 		iLogonAO->StartMonitoring(iSubThread);
       
   247 		if (iLogonAO->iStatus != KRequestPending)
       
   248 			{
       
   249 			// Failed to logon
       
   250 			iSubThread.RendezvousCancel(rendezvous);
       
   251 			User::WaitForRequest(rendezvous);
       
   252 			iSubThread.Kill(0);
       
   253 			iSubThread.Close();
       
   254 			return iLogonAO->iStatus.Int();
       
   255 			}
       
   256 		else
       
   257 			{
       
   258 			iSubThread.SetPriority(iThreadPriority);
       
   259 			iSubThread.Resume();
       
   260 			}
       
   261 		}
       
   262 		
       
   263 	User::WaitForRequest(rendezvous); // wait for startup or death
       
   264 	
       
   265 	if (rendezvous != KErrNone)
       
   266 		{
       
   267 		iLogonAO->Cancel();
       
   268 		iSubThread.Close();
       
   269 		// if open failed, but we registered the heap, need to release
       
   270 		if((iFlags&EFlagOpenedSharedHeap))
       
   271 			{
       
   272 			ReleaseHeap();
       
   273 			}		
       
   274 		}
       
   275 		
       
   276 	return rendezvous.Int();
       
   277 	}
       
   278 
       
   279 EXPORT_C void RMMFControllerProxy::Close()
       
   280 	{
       
   281 #ifdef _DEBUG
       
   282 	_LIT(KMMFClientThreadPanic, "MMFClientThread");
       
   283 #endif
       
   284 	// check if thread was created
       
   285 	TBool subThreadCreated = EFalse;
       
   286 	TRequestStatus logoffStatus;
       
   287 	TBool logoffFailed = EFalse;
       
   288 	if (iSubThread.Handle() != KNullHandle)
       
   289 		{
       
   290 		subThreadCreated = ETrue;
       
   291 		iLogonAO->Cancel();
       
   292 		iSubThread.Logon(logoffStatus);
       
   293 		
       
   294 		if (logoffStatus == KErrNoMemory && iSubThread.ExitType() == EExitPending)
       
   295 			{
       
   296 			// Logon() call has failed because of a lack of memory
       
   297 			logoffFailed = ETrue;
       
   298 			}
       
   299 		}
       
   300 
       
   301 	// Close the controller and wait for its exit.
       
   302 	// Close the session to signal the controller proxy server to shut down.
       
   303 	RHandleBase::Close();
       
   304 	
       
   305 	// Now wait for the death of the subthread if we have a valid handle...
       
   306 	if (subThreadCreated)
       
   307 		{
       
   308 		RProcess thisProcess;
       
   309 		RProcess controllerProcess;
       
   310 		iSubThread.Process(controllerProcess);	// ignore error, best try
       
   311 		TBool secureDrmMode = thisProcess.Id() != controllerProcess.Id();
       
   312 		thisProcess.Close();
       
   313 		controllerProcess.Close();
       
   314 				
       
   315 		RTimer timer;
       
   316 		TInt err = timer.CreateLocal();
       
   317 		// If we managed to create the timer and logon to the thread, 
       
   318 		// wait for both the death and the timeout to minimise the risk of deadlock
       
   319 		if (!err && !logoffFailed)
       
   320 			{
       
   321 			TRequestStatus timeout;
       
   322 			timer.After(timeout, KMmfControllerThreadShutdownTimeout);
       
   323 			User::WaitForRequest(logoffStatus, timeout);
       
   324 			if (logoffStatus == KRequestPending)
       
   325 				{
       
   326 				// we have timed out.  Kill the controller thread
       
   327 				iSubThread.LogonCancel(logoffStatus);
       
   328 				User::WaitForRequest(logoffStatus);
       
   329 				
       
   330 				if (!secureDrmMode)
       
   331 					{
       
   332 					// Controller server thread is created in current process
       
   333 				#ifdef _DEBUG
       
   334 					iSubThread.Panic(KMMFClientThreadPanic,KErrDied);
       
   335 				#else
       
   336 					iSubThread.Kill(KErrDied);
       
   337 				#endif
       
   338 					}
       
   339 				else
       
   340 					{
       
   341 					// Controller server thread is created through DRM plugin server
       
   342 					RMMFDRMPluginServerProxy server;
       
   343 					// ignore all RMMFDRMPluginServerProxy errors, best try
       
   344 					err = server.Open();
       
   345 					if (err == KErrNone)
       
   346 						{
       
   347 					#ifdef _DEBUG
       
   348 						server.PanicControllerThread(iSubThread.Id(), KMMFClientThreadPanic, KErrDied);
       
   349 					#else
       
   350 						server.KillControllerThread(iSubThread.Id(), KErrDied);
       
   351 					#endif
       
   352 						server.Close();
       
   353 						}
       
   354 					}
       
   355 				}
       
   356 			else
       
   357 				{
       
   358 				// subthread has exited. Cancel the timer.
       
   359 				timer.Cancel();
       
   360 				User::WaitForRequest(timeout);
       
   361 				}
       
   362 			}
       
   363 		else
       
   364 			{
       
   365 			// We have no timer or we can't logon to the thread so we'll just poll the thread status a maximum
       
   366 			// of 10 times and kill the thread if it hasn't exited after the polling
       
   367 			for (TInt i=0; i<10 && iSubThread.ExitType() == EExitPending; ++i)
       
   368 				{
       
   369 				User::After(KMmfControllerThreadShutdownTimeout/10);	// wait for a while
       
   370 				}
       
   371 				
       
   372 			if (iSubThread.ExitType() == EExitPending)
       
   373 				{
       
   374 				// The polling hasn't been succesful so we kill the thread
       
   375 				if (!secureDrmMode)
       
   376 					{
       
   377 					iSubThread.Kill(KErrDied);
       
   378 					}
       
   379 				else
       
   380 					{
       
   381 					// Controller server thread is created through DRM plugin server
       
   382 					RMMFDRMPluginServerProxy server;
       
   383 					// ignore all RMMFDRMPluginServerProxy errors, best try
       
   384 					err = server.Open();
       
   385 					if (err == KErrNone)
       
   386 						{
       
   387 						server.KillControllerThread(iSubThread.Id(), KErrDied);
       
   388 						}
       
   389 					}
       
   390 				}
       
   391 				
       
   392 			User::WaitForRequest(logoffStatus);
       
   393 			}
       
   394 		timer.Close();
       
   395 		}
       
   396 
       
   397 	// Close the handle to the controller thread
       
   398 	iSubThread.Close();
       
   399 	// Delete the Logon AO
       
   400 	if (iLogonAO)
       
   401 		{
       
   402 		delete iLogonAO;
       
   403 		iLogonAO = NULL;
       
   404 		}
       
   405 	// if this is last thread to be killed delete shared heap
       
   406 	if((iFlags&EFlagOpenedSharedHeap))
       
   407 		{
       
   408 		ReleaseHeap();
       
   409 		}	
       
   410 	}
       
   411 
       
   412 // Release the shared heap, should only be called if has previously been registered
       
   413 // by this thread
       
   414 void RMMFControllerProxy::ReleaseHeap()
       
   415 	{
       
   416 	__ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap), Panic(EPanicReleaseWithoutRegister));
       
   417 
       
   418 	CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
       
   419 	__ASSERT_DEBUG(contHeap!=NULL, Panic(EPanicHeapOpenWithoutTls));
       
   420 	
       
   421 	if(contHeap != NULL)
       
   422 		{
       
   423 		TInt refCount = contHeap->ReleaseHeap();
       
   424 		if(refCount == 0)
       
   425 			{  //no other controllers using the heap
       
   426 			delete contHeap;
       
   427 			Dll::SetTls(NULL);
       
   428 			}
       
   429 		}
       
   430 		
       
   431 	iFlags &= ~EFlagOpenedSharedHeap; // clear flag since we've released the heap
       
   432 	}
       
   433 
       
   434 EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) const
       
   435 	{
       
   436 	// Make sure we have been opened
       
   437 	if (iSubThread.Handle() == 0)
       
   438 		{
       
   439 		return KErrNotReady;
       
   440 		}
       
   441 	else
       
   442 		return SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom);
       
   443 	}
       
   444 
       
   445 
       
   446 EXPORT_C TInt RMMFControllerProxy::SendSync(TInt aFunction, const TIpcArgs& aIpcArgs) const
       
   447 	{
       
   448 	// Make sure we have been opened
       
   449 	if (iSubThread.Handle() == 0)
       
   450 		{
       
   451 		return KErrNotReady;
       
   452 		}
       
   453 	else
       
   454 		return RSessionBase::SendReceive(aFunction, aIpcArgs);
       
   455 	}
       
   456 	
       
   457 EXPORT_C void RMMFControllerProxy::SendAsync(TInt aFunction, const TIpcArgs& aIpcArgs, TRequestStatus& aStatus) const
       
   458 	{
       
   459 	// Make sure we have been opened
       
   460 	if (iSubThread.Handle() == 0)
       
   461 		{
       
   462 		TRequestStatus* status = &aStatus;
       
   463 		User::RequestComplete(status, KErrNotReady);
       
   464 		}
       
   465 	else
       
   466 		RSessionBase::SendReceive(aFunction, aIpcArgs, aStatus);
       
   467 	}
       
   468 
       
   469 
       
   470 
       
   471 EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) const
       
   472 	{
       
   473 	// Make sure we have been opened
       
   474 	if (iSubThread.Handle() == 0)
       
   475 		{
       
   476 		return KErrNotReady;
       
   477 		}
       
   478 	else
       
   479 		return SendReceive(aFunction, aDestination, aDataTo1, aDataTo2);
       
   480 	}
       
   481 
       
   482 EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) const
       
   483 	{
       
   484 	if (iSubThread.Handle() == 0)
       
   485 		{
       
   486 		TRequestStatus* stat = &aStatus;
       
   487 		User::RequestComplete(stat, KErrNotReady);
       
   488 		}
       
   489 	else
       
   490 		SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom, aStatus);
       
   491 	}
       
   492 
       
   493 EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) const
       
   494 	{
       
   495 	if (iSubThread.Handle() == 0)
       
   496 		{
       
   497 		TRequestStatus* stat = &aStatus;
       
   498 		User::RequestComplete(stat, KErrNotReady);
       
   499 		}
       
   500 	else
       
   501 		SendReceive(aFunction, aDestination, aDataTo1, aDataTo2, aStatus);
       
   502 	}
       
   503 
       
   504 EXPORT_C void RMMFControllerProxy::ReceiveEvents(TMMFEventPckg& aEvent, TRequestStatus& aStatus)
       
   505 	{
       
   506 	SendAsync(iDestinationPckg, EMMFControllerProxyReceiveEvents, KNullDesC8, KNullDesC8, aEvent, aStatus);
       
   507 	}
       
   508 
       
   509 EXPORT_C TInt RMMFControllerProxy::CancelReceiveEvents()
       
   510 	{
       
   511 	return SendSync(iDestinationPckg, EMMFControllerProxyCancelReceiveEvents, KNullDesC8, KNullDesC8);
       
   512 	}
       
   513 
       
   514 EXPORT_C TInt RMMFControllerProxy::SetThreadPriority(const TThreadPriority& aPriority) const
       
   515 	{
       
   516 	TInt err = KErrNone;
       
   517 
       
   518 	if (iSubThread.Handle() == 0)
       
   519 		{
       
   520 		err = KErrNotReady;
       
   521 		}
       
   522 	else
       
   523 		{
       
   524 		if (iThreadPriority != aPriority)
       
   525 			{
       
   526 			// This is a const method so cast it away to store the priority
       
   527 			RMMFControllerProxy* nonConstThis = const_cast<RMMFControllerProxy*>(this);
       
   528 			nonConstThis->iThreadPriority = aPriority;
       
   529 			}
       
   530 			
       
   531 		// check controller thread creation location
       
   532 		RProcess thisProcess;
       
   533 		RProcess controllerProcess;
       
   534 		err = iSubThread.Process(controllerProcess);
       
   535 		
       
   536 		if (err == KErrNone)
       
   537 			{
       
   538 			if (thisProcess.Id() == controllerProcess.Id())
       
   539 				{
       
   540 				// Controller server thread is created in current process
       
   541 				if (iSubThread.Priority() != iThreadPriority)
       
   542 					{
       
   543 					iSubThread.Suspend();
       
   544 					iSubThread.SetPriority(iThreadPriority);
       
   545 					iSubThread.Resume();
       
   546 					}
       
   547 				}
       
   548 			else
       
   549 				{
       
   550 				// Controller server thread is created through DRM plugin server
       
   551 				RMMFDRMPluginServerProxy server;
       
   552 				err = server.Open();
       
   553 				if (err == KErrNone)
       
   554 					{
       
   555 					err = server.SetThreadPriority(iSubThread.Id(), iThreadPriority);
       
   556 					server.Close();
       
   557 					}
       
   558 				}
       
   559 			}
       
   560 		thisProcess.Close();
       
   561 		controllerProcess.Close();
       
   562 		}
       
   563 	return err;
       
   564 	}
       
   565 	
       
   566 void RMMFControllerProxy::ThreadTerminated()
       
   567 	{
       
   568 	// The controller subthread has died and the controller should be closed
       
   569 	iSubThread.Close();
       
   570 	}
       
   571 
       
   572 TInt RMMFControllerProxy::DoCreateSessionForNoDRMCapClient(TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
       
   573 	{
       
   574 	TThreadId tid;
       
   575 	RMMFDRMPluginServerProxy server;
       
   576     TInt error = server.Open();
       
   577     
       
   578     if(!error)
       
   579     	{
       
   580     	error = server.LaunchControllerServer(aMaxHeapSize, aUseSharedHeap, tid, aStackSize);
       
   581     	}		    
       
   582     if(!error)
       
   583 		{
       
   584 		error = iSubThread.Open(tid, EOwnerThread);
       
   585 		if(!error)
       
   586 			{
       
   587 			iLogonAO->StartMonitoring(iSubThread);
       
   588 			if (iLogonAO->iStatus != KRequestPending)
       
   589 				{
       
   590 				// Failed to logon
       
   591 				server.KillControllerThread(tid, 0);
       
   592 				iSubThread.Close();
       
   593 				error = iLogonAO->iStatus.Int();
       
   594 				}
       
   595 			}
       
   596 		else
       
   597 			{
       
   598 			// Failed to open thread handle
       
   599 			server.KillControllerThread(tid, 0);
       
   600 			}
       
   601 		}
       
   602 	if(!error)
       
   603 		{
       
   604 		error = server.SetThreadPriority(tid, iThreadPriority);
       
   605 		if(!error)
       
   606 			{
       
   607 			error = SetReturnedHandle(server.GetControllerSessionHandle());	
       
   608 			}
       
   609 		if(error)
       
   610 			{
       
   611 			// Failed to create session with controller
       
   612 			iLogonAO->Cancel();
       
   613 			server.KillControllerThread(tid, 0);
       
   614 			iSubThread.Close();
       
   615 			}
       
   616 		}
       
   617     server.Close();
       
   618     return error;
       
   619 	}
       
   620 
       
   621 
       
   622 // RMMFCustomCommandsBase
       
   623 
       
   624 /**
       
   625 Constructor.
       
   626 
       
   627 @param  aController
       
   628         A reference to the controller client class that will be used to send
       
   629         custom commands to the controller plugin.
       
   630 @param  aInterfaceId
       
   631         The UID of the custom command interface that is provided by this client
       
   632         API class.
       
   633 
       
   634 @since 7.0s
       
   635 */
       
   636 EXPORT_C RMMFCustomCommandsBase::RMMFCustomCommandsBase(RMMFController& aController, TUid aInterfaceId)
       
   637 	: iController(aController), iDestinationPckg(aInterfaceId)
       
   638 	{
       
   639 	}
       
   640 
       
   641 
       
   642 // TMMFMessageDestination
       
   643 EXPORT_C TMMFMessageDestination::TMMFMessageDestination()
       
   644 	: iInterfaceId(KNullUid), iDestinationHandle(KMMFObjectHandleController)
       
   645 	{
       
   646 	}
       
   647 
       
   648 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId)
       
   649 	: iInterfaceId(aInterfaceId), iDestinationHandle(KMMFObjectHandleController)
       
   650 	{
       
   651 	}
       
   652 
       
   653 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId, TInt aDestinationHandle)
       
   654 	: iInterfaceId(aInterfaceId), iDestinationHandle(aDestinationHandle)
       
   655 	{
       
   656 	}
       
   657 
       
   658 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(const TMMFMessageDestination& aOther)
       
   659 	: iInterfaceId(aOther.iInterfaceId), iDestinationHandle(aOther.iDestinationHandle)
       
   660 	{
       
   661 	}
       
   662 
       
   663 EXPORT_C TUid TMMFMessageDestination::InterfaceId() const
       
   664 	{
       
   665 	return iInterfaceId;
       
   666 	}
       
   667 
       
   668 EXPORT_C TInt TMMFMessageDestination::DestinationHandle() const
       
   669 	{
       
   670 	return iDestinationHandle;
       
   671 	}
       
   672 
       
   673 EXPORT_C TBool TMMFMessageDestination::operator==(const TMMFMessageDestination& aOther) const
       
   674 	{
       
   675 	return ((iInterfaceId==aOther.iInterfaceId) && (iDestinationHandle==aOther.iDestinationHandle));
       
   676 	}
       
   677 
       
   678 
       
   679 
       
   680 // CMMFControllerProxySession
       
   681 CMMFControllerProxySession* CMMFControllerProxySession::NewL()
       
   682 	{
       
   683 	CMMFControllerProxySession* s = new(ELeave) CMMFControllerProxySession;
       
   684 	return s;
       
   685 	}
       
   686 
       
   687 void CMMFControllerProxySession::CreateL(const CMmfIpcServer& aServer)
       
   688 	{
       
   689 	CMmfIpcSession::CreateL(aServer);
       
   690 	iServer = STATIC_CAST(CMMFControllerProxyServer*, (CONST_CAST(CMmfIpcServer*, &aServer)));
       
   691 	iServer->SessionCreated();
       
   692 	}
       
   693 
       
   694 CMMFControllerProxySession::~CMMFControllerProxySession()
       
   695 	{
       
   696 	delete iController;
       
   697 	delete iEventReceiver;
       
   698 	iEvents.Close();
       
   699 	iServer->SessionDestroyed();
       
   700 	}
       
   701 
       
   702 
       
   703 
       
   704 void CMMFControllerProxySession::ServiceL(const RMmfIpcMessage& aMessage)
       
   705 	{
       
   706 	TMMFMessage message(aMessage);
       
   707 	// Get the destination info from the client.
       
   708 	message.FetchDestinationL();
       
   709 
       
   710 	if (message.Destination().InterfaceId() == KUidInterfaceMMFControllerProxy)
       
   711 		{
       
   712 		// Message for controller proxy so decode here
       
   713 		TBool complete = EFalse;
       
   714 		switch (message.Function())
       
   715 			{
       
   716 		case EMMFControllerProxyReceiveEvents:
       
   717 			complete = ReceiveEventsL(message);
       
   718 			break;
       
   719 		case EMMFControllerProxyCancelReceiveEvents:
       
   720 			complete = CancelReceiveEvents(message);
       
   721 			break;
       
   722 		case EMMFControllerProxyLoadControllerPluginByUid:
       
   723 			complete = LoadControllerL(message);
       
   724 			break;
       
   725 		default:
       
   726 			User::Leave(KErrNotSupported);
       
   727 			}
       
   728 		if (complete)
       
   729 			message.Complete(KErrNone);
       
   730 		}
       
   731 	else
       
   732 		{
       
   733 		// Message for controller so forward on to controller baseclass
       
   734 		if (iController)
       
   735 			iController->HandleRequestL(message);
       
   736 		else
       
   737 			User::Leave(KErrNotReady);
       
   738 		}
       
   739 	}
       
   740 
       
   741 CMMFControllerProxySession::CMMFControllerProxySession()
       
   742 	{
       
   743 	}
       
   744 
       
   745 TBool CMMFControllerProxySession::ReceiveEventsL(TMMFMessage& aMessage)
       
   746 	{
       
   747 	if (iEventReceiver)
       
   748 		User::Leave(KErrAlreadyExists);
       
   749 	iEventReceiver = CMMFEventReceiver::NewL(aMessage);
       
   750 	//send the next cached event (if any) to the client
       
   751 	if (iEvents.Count() > 0)
       
   752 		{
       
   753 		TMMFEvent& event = iEvents[0];
       
   754 		iEventReceiver->SendEvent(event);
       
   755 		delete iEventReceiver;
       
   756 		iEventReceiver=NULL;
       
   757 		iEvents.Remove(0);
       
   758 		}
       
   759 	return EFalse;
       
   760 	}
       
   761 
       
   762 TBool CMMFControllerProxySession::CancelReceiveEvents(TMMFMessage& /*aMessage*/)
       
   763 	{
       
   764 	delete iEventReceiver;
       
   765 	iEventReceiver = NULL;
       
   766 	return ETrue;
       
   767 	}
       
   768 
       
   769 TInt CMMFControllerProxySession::SendEventToClient(const TMMFEvent& aEvent)
       
   770 	{
       
   771 	TInt error = KErrNone;
       
   772 	if (iEventReceiver)
       
   773 		{
       
   774 		//send event to client now
       
   775 		iEventReceiver->SendEvent(aEvent);
       
   776 		delete iEventReceiver;
       
   777 		iEventReceiver=NULL;
       
   778 		error = KErrNone;
       
   779 		}
       
   780 	else
       
   781 		{
       
   782 		//queue the request for later
       
   783 		TMMFEvent event(aEvent);
       
   784 		//if we've exceeded the max number of cached messages, delete the first and append this one to the end
       
   785 		if (iEvents.Count() >= KMMFControllerProxyMaxCachedMessages)
       
   786 			iEvents.Remove(0);
       
   787 		error = iEvents.Append(event);
       
   788 		}
       
   789 	return error;
       
   790 	}
       
   791 
       
   792 TBool CMMFControllerProxySession::LoadControllerL(TMMFMessage& aMessage)
       
   793 	{
       
   794 	TMMFUidPckg pckg;
       
   795 	aMessage.ReadData1FromClientL(pckg);
       
   796 	
       
   797 	RThread clientThread;
       
   798 	aMessage.iMessage.ClientL(clientThread);
       
   799 	CleanupClosePushL(clientThread);
       
   800 	iController = CMMFController::NewL(pckg(), *this, clientThread.Id());
       
   801 	CleanupStack::PopAndDestroy(&clientThread);
       
   802 	return ETrue;
       
   803 	}
       
   804 
       
   805 
       
   806 
       
   807 CMMFControllerProxyServer* CMMFControllerProxyServer::NewL(RServer2* aServer2)
       
   808 	{
       
   809 	CMMFControllerProxyServer* s = new(ELeave) CMMFControllerProxyServer();
       
   810 	CleanupStack::PushL(s);
       
   811 	s->ConstructL(aServer2);
       
   812 	CleanupStack::Pop(s);
       
   813 	return s;
       
   814 	}
       
   815 
       
   816 CMMFControllerProxyServer::CMMFControllerProxyServer() :
       
   817 	CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions)
       
   818 	{
       
   819 	}
       
   820 
       
   821 void CMMFControllerProxyServer::ConstructL(RServer2* aServer2)
       
   822 	{
       
   823 	SetPinClientDescriptors(ETrue);
       
   824 	
       
   825 	StartL(KNullDesC);
       
   826 	*aServer2 = CServer2::Server();
       
   827 	
       
   828 	iShutdownTimer = CMMFControllerProxyShutdown::NewL();
       
   829 	iShutdownTimer->Start();
       
   830 	}
       
   831 
       
   832 CMMFControllerProxyServer::~CMMFControllerProxyServer()
       
   833 	{
       
   834 	delete iShutdownTimer;
       
   835 	}
       
   836 
       
   837 EXPORT_C TInt CMMFControllerProxyServer::StartThread(TAny* aParam)
       
   838 	{
       
   839 	TInt err = KErrNone;
       
   840 	//create cleanupstack
       
   841 	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
       
   842 	if (!cleanup)
       
   843 		err = KErrNoMemory;
       
   844 	if (!err)
       
   845 		{
       
   846 		TRAP(err, DoStartThreadL(aParam));
       
   847 		}
       
   848 	delete cleanup;
       
   849 	return err;
       
   850 	}
       
   851 	
       
   852 void CMMFControllerProxyServer::RenameControllerProxyThread()
       
   853 	{
       
   854 	RThread thread;
       
   855 	TThreadId threadId;
       
   856 	TName name;
       
   857 	name.Append(KMMFControllerProxyServerName);
       
   858 	threadId = thread.Id();
       
   859 	name.AppendNum(threadId.Id(),EHex);
       
   860 	User::RenameThread(name);
       
   861 	}
       
   862 
       
   863 void CMMFControllerProxyServer::DoStartThreadL(TAny* aParam)
       
   864 	{
       
   865 	TControllerProxyServerParams* params = static_cast<TControllerProxyServerParams*>(aParam);
       
   866 	
       
   867 	//Rename Current thread to unique name
       
   868 	RenameControllerProxyThread();
       
   869 	
       
   870 #ifndef SYMBIAN_USE_CLIENT_HEAP
       
   871 	TBool usingSharedHeap = params->iUsingSharedHeap; // take copy since params invalid after Rendezvous
       
   872 	
       
   873 	if( ! usingSharedHeap )
       
   874 		{
       
   875 		__UHEAP_MARK;
       
   876 		}
       
   877 
       
   878 #endif
       
   879 	// create and install the active scheduler we need
       
   880 	CActiveScheduler* s=new(ELeave) CActiveScheduler;
       
   881 	CleanupStack::PushL(s);
       
   882 	CActiveScheduler::Install(s);
       
   883 	// create the server (leave it on the cleanup stack)
       
   884 	CleanupStack::PushL(CMMFControllerProxyServer::NewL( params->iServer ) );
       
   885 	// Initialisation complete, now signal the client
       
   886 	RThread::Rendezvous(KErrNone);
       
   887 	// Ready to run
       
   888 	CActiveScheduler::Start();
       
   889 	
       
   890 	REComSession::FinalClose();
       
   891 	
       
   892 	// Cleanup the server and scheduler
       
   893 	CleanupStack::PopAndDestroy(2, s);
       
   894 #ifndef SYMBIAN_USE_CLIENT_HEAP
       
   895 	if( ! usingSharedHeap )
       
   896 		{
       
   897 		__UHEAP_MARKEND;
       
   898 		}
       
   899 #endif
       
   900 	}
       
   901 
       
   902 TInt CMMFControllerProxyServer::RunError(TInt aError)
       
   903 	{
       
   904 	// Send error to the client
       
   905 	Message().Complete(aError);
       
   906 	ReStart();
       
   907 	return KErrNone;
       
   908 	}
       
   909 
       
   910 CMmfIpcSession* CMMFControllerProxyServer::NewSessionL(const TVersion& aVersion) const
       
   911 	{
       
   912 	// Only one session is allowed to connect to us
       
   913 	if (iHaveSession)
       
   914 		User::Leave(KErrAlreadyExists);
       
   915 	// Check that the version number of the client is correct
       
   916 	if (!User::QueryVersionSupported(KMMFControllerProxyVersion, aVersion))
       
   917 		User::Leave(KErrNotSupported);
       
   918 
       
   919 	return CMMFControllerProxySession::NewL();
       
   920 	}
       
   921 
       
   922 void CMMFControllerProxyServer::SessionCreated()
       
   923 	{
       
   924 	iHaveSession = ETrue;
       
   925 	// Stop the shutdown timer
       
   926 	iShutdownTimer->Cancel();
       
   927 	}
       
   928 
       
   929 void CMMFControllerProxyServer::SessionDestroyed()
       
   930 	{
       
   931 	// Need to shut down
       
   932 	iShutdownTimer->ShutdownNow();
       
   933 	}
       
   934 
       
   935 CMMFControllerProxyShutdown* CMMFControllerProxyShutdown::NewL() 
       
   936 	{
       
   937 	CMMFControllerProxyShutdown* s = new(ELeave) CMMFControllerProxyShutdown();
       
   938 	CleanupStack::PushL(s);
       
   939 	s->ConstructL();
       
   940 	CleanupStack::Pop(s);
       
   941 	return s;
       
   942 	}
       
   943 
       
   944 CMMFControllerProxyShutdown::CMMFControllerProxyShutdown() : 
       
   945 	CTimer(EPriorityLow)
       
   946 	{
       
   947 	CActiveScheduler::Add(this);
       
   948 	}
       
   949 
       
   950 void CMMFControllerProxyShutdown::ConstructL()
       
   951 	{
       
   952 	CTimer::ConstructL();
       
   953 	}
       
   954 
       
   955 void CMMFControllerProxyShutdown::Start()
       
   956 	{
       
   957 	After(EMMFControllerProxyShutdownDelay);
       
   958 	}
       
   959 
       
   960 void CMMFControllerProxyShutdown::RunL()
       
   961 	{
       
   962 	ShutdownNow();
       
   963 	}
       
   964 
       
   965 void CMMFControllerProxyShutdown::ShutdownNow()
       
   966 	{
       
   967 	CActiveScheduler::Stop();
       
   968 	}
       
   969 
       
   970 
       
   971 
       
   972 
       
   973 
       
   974 
       
   975 
       
   976 CMMFEventReceiver* CMMFEventReceiver::NewL(const TMMFMessage& aMessage)
       
   977 	{
       
   978 	return new(ELeave) CMMFEventReceiver(aMessage);
       
   979 	}
       
   980 
       
   981 CMMFEventReceiver::~CMMFEventReceiver()
       
   982 	{
       
   983 	if (!(iMessage.IsCompleted()))
       
   984 		iMessage.Complete(KErrDied);
       
   985 	}
       
   986 
       
   987 void CMMFEventReceiver::SendEvent(const TMMFEvent& aEvent)
       
   988 	{
       
   989 	TMMFEventPckg eventpckg(aEvent);
       
   990 	TInt err = iMessage.WriteDataToClient(eventpckg);
       
   991 	iMessage.Complete(err);
       
   992 	}
       
   993 
       
   994 CMMFEventReceiver::CMMFEventReceiver(const TMMFMessage& aMessage) : iMessage(aMessage)
       
   995 	{
       
   996 	}
       
   997 
       
   998 
       
   999 
       
  1000 // TMMFMessage
       
  1001 EXPORT_C TMMFMessage::TMMFMessage(const TMMFMessage& aMessage) :
       
  1002 	iMessage(aMessage.iMessage), 
       
  1003 #ifdef __MMF_USE_IPC_V2__
       
  1004 	iFunction(aMessage.iFunction),
       
  1005 #endif  // __MMF_USE_IPC_V2__
       
  1006 	iDestination(aMessage.iDestination), 
       
  1007 	iAmCompleted(aMessage.iAmCompleted)
       
  1008 	{
       
  1009 	}
       
  1010 
       
  1011 EXPORT_C const TMMFMessageDestination& TMMFMessage::Destination()
       
  1012 	{
       
  1013 	return iDestination;
       
  1014 	}
       
  1015 
       
  1016 EXPORT_C TInt TMMFMessage::Function()
       
  1017 	{
       
  1018 #ifdef __MMF_USE_IPC_V2__
       
  1019 	return iFunction;
       
  1020 #else
       
  1021 	return iMessage.Function();
       
  1022 #endif // __MMF_USE_IPC_V2__
       
  1023 	}
       
  1024 
       
  1025 EXPORT_C TInt TMMFMessage::SizeOfData1FromClient()
       
  1026 	{
       
  1027 #ifdef __MMF_USE_IPC_V2__
       
  1028 	return iMessage.GetDesLength(1);
       
  1029 #else
       
  1030 	return iMessage.Client().GetDesLength(iMessage.Ptr1());
       
  1031 #endif // __MMF_USE_IPC_V2__
       
  1032 	}
       
  1033 
       
  1034 EXPORT_C void TMMFMessage::ReadData1FromClientL(TDes8& aDes)
       
  1035 	{
       
  1036 #ifdef __MMF_USE_IPC_V2__
       
  1037 	iMessage.ReadL(1, aDes);
       
  1038 #else
       
  1039 	iMessage.ReadL(iMessage.Ptr1(), aDes);
       
  1040 #endif // __MMF_USE_IPC_V2__
       
  1041 	}
       
  1042 
       
  1043 EXPORT_C TInt TMMFMessage::ReadData1FromClient(TDes8& aDes)
       
  1044 	{
       
  1045 	TRAPD(err, ReadData1FromClientL(aDes));
       
  1046 	return err;
       
  1047 	}
       
  1048 
       
  1049 EXPORT_C TInt TMMFMessage::SizeOfData2FromClient()
       
  1050 	{
       
  1051 #ifdef __MMF_USE_IPC_V2__
       
  1052 	return iMessage.GetDesLength(2);
       
  1053 #else
       
  1054 	return iMessage.Client().GetDesLength(iMessage.Ptr2());
       
  1055 #endif // __MMF_USE_IPC_V2__
       
  1056 	}
       
  1057 
       
  1058 EXPORT_C void TMMFMessage::ReadData2FromClientL(TDes8& aDes)
       
  1059 	{
       
  1060 #ifdef __MMF_USE_IPC_V2__
       
  1061 	iMessage.ReadL(2, aDes);
       
  1062 #else
       
  1063 	iMessage.ReadL(iMessage.Ptr2(), aDes);
       
  1064 #endif // __MMF_USE_IPC_V2__
       
  1065 	}
       
  1066 
       
  1067 EXPORT_C TInt TMMFMessage::ReadData2FromClient(TDes8& aDes)
       
  1068 	{
       
  1069 	TRAPD(err, ReadData2FromClientL(aDes));
       
  1070 	return err;
       
  1071 	}
       
  1072 
       
  1073 EXPORT_C void TMMFMessage::WriteDataToClientL(const TDesC8& aDes)
       
  1074 	{
       
  1075 #ifdef __MMF_USE_IPC_V2__
       
  1076 	iMessage.WriteL(3, aDes);
       
  1077 #else
       
  1078 	iMessage.WriteL(iMessage.Ptr3(), aDes);
       
  1079 #endif // __MMF_USE_IPC_V2__
       
  1080 	}
       
  1081 
       
  1082 EXPORT_C TInt TMMFMessage::WriteDataToClient(const TDesC8& aDes)
       
  1083 	{
       
  1084 	TRAPD(err, WriteDataToClientL(aDes));
       
  1085 	return err;
       
  1086 	}
       
  1087 
       
  1088 EXPORT_C void TMMFMessage::Complete(TInt aReason)
       
  1089 	{
       
  1090 	iMessage.Complete(aReason);
       
  1091 	iAmCompleted = ETrue;
       
  1092 	}
       
  1093 
       
  1094 EXPORT_C TBool TMMFMessage::IsCompleted()
       
  1095 	{
       
  1096 	return iAmCompleted;
       
  1097 	}
       
  1098 	
       
  1099 EXPORT_C void TMMFMessage::AdoptFileHandleFromClientL(TInt aFsHandleIndex, TInt aFileHandleIndex, RFile& aFile)
       
  1100 	{
       
  1101 	User::LeaveIfError(aFile.AdoptFromClient(RMessage2(iMessage) , aFsHandleIndex, aFileHandleIndex));
       
  1102 	}
       
  1103 
       
  1104 EXPORT_C TMMFMessage::TMMFMessage(const RMmfIpcMessage& aMessage) :
       
  1105 	iMessage(aMessage), 
       
  1106 #ifdef __MMF_USE_IPC_V2__
       
  1107 	iFunction(aMessage.Function()),
       
  1108 #endif // __MMF_USE_IPC_V2__
       
  1109 	iAmCompleted(EFalse)
       
  1110 	{
       
  1111 	}
       
  1112 
       
  1113 EXPORT_C void TMMFMessage::FetchDestinationL()
       
  1114 	{
       
  1115 	// Read the destination info from the client
       
  1116 	TMMFMessageDestinationPckg pckg;
       
  1117 #ifdef __MMF_USE_IPC_V2__
       
  1118 	iMessage.ReadL(0, pckg);
       
  1119 #else
       
  1120 	iMessage.ReadL(iMessage.Ptr0(), pckg);
       
  1121 #endif // __MMF_USE_IPC_V2__
       
  1122 	iDestination = pckg();
       
  1123 	}
       
  1124 
       
  1125 
       
  1126 // CMMFObject
       
  1127 
       
  1128 /**
       
  1129 Constructor.
       
  1130 
       
  1131 @param  aInterfaceId
       
  1132         The UID of the interface provided by this object.
       
  1133 @since 7.0s
       
  1134 */
       
  1135 EXPORT_C CMMFObject::CMMFObject(TUid aInterfaceId)
       
  1136 	: iHandle(aInterfaceId, KMMFObjectHandleNull)
       
  1137 	{
       
  1138 	}
       
  1139 
       
  1140 /**
       
  1141 Destructor.
       
  1142 */
       
  1143 EXPORT_C CMMFObject::~CMMFObject()
       
  1144 	{
       
  1145 	}
       
  1146 
       
  1147 /**
       
  1148 Returns the handle of the object.
       
  1149 
       
  1150 @return The handle of this object.
       
  1151 
       
  1152 @since  7.0s
       
  1153 */
       
  1154 EXPORT_C const TMMFMessageDestination& CMMFObject::Handle()
       
  1155 	{
       
  1156 	return iHandle;
       
  1157 	}
       
  1158 
       
  1159 /**
       
  1160 Compares two CMMFObjects by comparing their handles.
       
  1161 
       
  1162 @param  aOther
       
  1163         The object to be compared with this object.
       
  1164 
       
  1165 @return A boolean indicating if the two CMMFObjects are the same. ETrue if they are the same,
       
  1166         EFalse if the objects are different.
       
  1167 @since  7.0s
       
  1168 */
       
  1169 EXPORT_C TBool CMMFObject::operator==(const CMMFObject& aOther)
       
  1170 	{
       
  1171 	return (iHandle==aOther.iHandle);
       
  1172 	}
       
  1173 
       
  1174 void CMMFObject::SetHandle(const TMMFMessageDestination& aNewHandle)
       
  1175 	{
       
  1176 	iHandle = aNewHandle;
       
  1177 	}
       
  1178 
       
  1179 
       
  1180 // CMMFDataSourceHolder
       
  1181 
       
  1182 /**
       
  1183 Constructor.
       
  1184 
       
  1185 @param  aDataSource
       
  1186         The data source to be wrapped.
       
  1187 
       
  1188 @since  7.0s
       
  1189 */
       
  1190 EXPORT_C CMMFDataSourceHolder::CMMFDataSourceHolder(MDataSource& aDataSource)
       
  1191 	: CMMFObject(KUidInterfaceMMFDataSourceHolder), iDataSource(&aDataSource)
       
  1192 	{
       
  1193 	}
       
  1194 
       
  1195 /**
       
  1196 Destructor.
       
  1197 
       
  1198 Note: This deletes the data source.
       
  1199 
       
  1200 @since 7.0s
       
  1201 */
       
  1202 EXPORT_C CMMFDataSourceHolder::~CMMFDataSourceHolder()
       
  1203 	{
       
  1204 	delete iDataSource;
       
  1205 	}
       
  1206 
       
  1207 /**
       
  1208 Returns a reference to the data source.
       
  1209 
       
  1210 @return The data source.
       
  1211 
       
  1212 @since  7.0s
       
  1213 */
       
  1214 EXPORT_C MDataSource& CMMFDataSourceHolder::DataSource()
       
  1215 	{
       
  1216 	return *iDataSource;
       
  1217 	}
       
  1218 
       
  1219 /**
       
  1220 Implementation of the pure virtual function inherited from CMMFObject.
       
  1221 
       
  1222 Passes the request directly to the data source.
       
  1223 
       
  1224 @param  aMessage
       
  1225         The message to be handled.
       
  1226 
       
  1227 @since  7.0s
       
  1228 */
       
  1229 EXPORT_C void CMMFDataSourceHolder::HandleRequest(TMMFMessage& aMessage)
       
  1230 	{
       
  1231 	iDataSource->SourceCustomCommand(aMessage);
       
  1232 	}
       
  1233 
       
  1234 
       
  1235 // CMMFDataSinkHolder
       
  1236 
       
  1237 /**
       
  1238 Constructor.
       
  1239 
       
  1240 @param  aDataSink
       
  1241         The data sink to be wrapped.
       
  1242 @since 7.0s
       
  1243 */
       
  1244 EXPORT_C CMMFDataSinkHolder::CMMFDataSinkHolder(MDataSink& aDataSink)
       
  1245 	: CMMFObject(KUidInterfaceMMFDataSinkHolder), iDataSink(&aDataSink)
       
  1246 	{
       
  1247 	}
       
  1248 
       
  1249 /**
       
  1250 Destructor.
       
  1251 
       
  1252 Note: This deletes the data sink.
       
  1253 
       
  1254 @since  7.0s
       
  1255 */
       
  1256 EXPORT_C CMMFDataSinkHolder::~CMMFDataSinkHolder()
       
  1257 	{
       
  1258 	delete iDataSink;
       
  1259 	}
       
  1260 
       
  1261 /**
       
  1262 Returns a reference to the data sink.
       
  1263 
       
  1264 @return The data sink.
       
  1265 @since 7.0s
       
  1266 */
       
  1267 EXPORT_C MDataSink& CMMFDataSinkHolder::DataSink()
       
  1268 	{
       
  1269 	return *iDataSink;
       
  1270 	}
       
  1271 
       
  1272 /**
       
  1273 Implementation of the pure virtual function inherited from CMMFObject.
       
  1274 
       
  1275 Passes the request directly to the data sink.
       
  1276 
       
  1277 @param  aMessage
       
  1278         The message to be handled.
       
  1279 
       
  1280 @since  7.0s
       
  1281 */
       
  1282 EXPORT_C void CMMFDataSinkHolder::HandleRequest(TMMFMessage& aMessage)
       
  1283 	{
       
  1284 	iDataSink->SinkCustomCommand(aMessage);
       
  1285 	}
       
  1286 
       
  1287 
       
  1288 // CMMFCustomCommandParserBase
       
  1289 EXPORT_C TUid CMMFCustomCommandParserBase::InterfaceId()
       
  1290 	{
       
  1291 	return iInterfaceId;
       
  1292 	}
       
  1293 
       
  1294 EXPORT_C CMMFCustomCommandParserBase::~CMMFCustomCommandParserBase()
       
  1295 	{
       
  1296 	}
       
  1297 
       
  1298 EXPORT_C CMMFCustomCommandParserBase::CMMFCustomCommandParserBase(TUid aInterfaceId)
       
  1299 	: iInterfaceId(aInterfaceId)
       
  1300 	{
       
  1301 	}
       
  1302 
       
  1303 
       
  1304 // CMMFObjectContainer
       
  1305 
       
  1306 /**
       
  1307 Constructor.
       
  1308 
       
  1309 @since  7.0s
       
  1310 */
       
  1311 EXPORT_C CMMFObjectContainer::CMMFObjectContainer()
       
  1312 	{
       
  1313 	iNextObjectHandle = KMMFObjectHandleFirstValid;
       
  1314 	}
       
  1315 
       
  1316 /**
       
  1317 Destructor.
       
  1318 
       
  1319 Deletes all objects owned by the container.
       
  1320 
       
  1321 @since  7.0s
       
  1322 */
       
  1323 EXPORT_C CMMFObjectContainer::~CMMFObjectContainer()
       
  1324 	{
       
  1325 	iObjects.ResetAndDestroy();
       
  1326 	iObjects.Close();
       
  1327 	}
       
  1328 
       
  1329 /**
       
  1330 Add an object to the container.
       
  1331 
       
  1332 Once the object has been added, its ownership is transferred to the container.
       
  1333 
       
  1334 @param  aObject
       
  1335         A reference to the object to be added to the container.
       
  1336 
       
  1337 @return	An error code indicating if the function call was successful. If the return code is not KErrNone, then
       
  1338 		ownership of the object still remains with the caller.
       
  1339 @since  7.0s
       
  1340 */
       
  1341 EXPORT_C TInt CMMFObjectContainer::AddMMFObject(CMMFObject& aObject)
       
  1342 	{
       
  1343 	// Check the object isn't already added
       
  1344 	if (aObject.Handle().DestinationHandle() != KMMFObjectHandleNull)
       
  1345 		return KErrAlreadyExists;
       
  1346 
       
  1347 	TMMFMessageDestination newHandle(aObject.Handle().InterfaceId(), GenerateObjectHandle());
       
  1348 	// Set the object's handle
       
  1349 	aObject.SetHandle(newHandle);
       
  1350 	// Append the object to the array
       
  1351 	TInt error = iObjects.Append(&aObject);
       
  1352 	// If error occurred, reset object handle to NULL
       
  1353 	if (error)
       
  1354 		{
       
  1355 		TMMFMessageDestination evenNewerHandle(aObject.Handle().InterfaceId(), KMMFObjectHandleNull);
       
  1356 		aObject.SetHandle(evenNewerHandle);
       
  1357 		}
       
  1358 	return error;
       
  1359 	}
       
  1360 
       
  1361 /**
       
  1362 Removes and destroys an object from the container.
       
  1363 
       
  1364 This method ensures that the object is no longer in the container, and that it gets deleted.
       
  1365 Even if the object is not found in the container's array of objects, it will be deleted.
       
  1366 
       
  1367 @param  aObject
       
  1368         A reference to the object to be deleted.
       
  1369 
       
  1370 @since  7.0s
       
  1371 */
       
  1372 EXPORT_C void CMMFObjectContainer::RemoveAndDestroyMMFObject(CMMFObject& aObject)
       
  1373 	{
       
  1374 	TInt positionOfObjectInArray;
       
  1375 	TInt error = FindMMFObject(aObject, positionOfObjectInArray);
       
  1376 	if (!error)
       
  1377 		{
       
  1378 		iObjects.Remove(positionOfObjectInArray);
       
  1379 		}
       
  1380 	//else, we don't care since we're just saying we'll make sure the object
       
  1381 	//isn't in the array, and that it gets deleted.
       
  1382 	delete (&aObject);
       
  1383 	}
       
  1384 
       
  1385 /**
       
  1386 Removes and destroys all objects from the container.
       
  1387 
       
  1388 @since	7.0s
       
  1389 */
       
  1390 EXPORT_C void CMMFObjectContainer::DeleteAllObjects()
       
  1391 	{
       
  1392 	iObjects.ResetAndDestroy();
       
  1393 	}
       
  1394 
       
  1395 /**
       
  1396 Finds an object in the container using a handle.
       
  1397 
       
  1398 @param  aObjectHandle
       
  1399         The handle of the object to be located.
       
  1400 @param  aObjectFound
       
  1401         A reference to a pointer to the object found in the container.
       
  1402 
       
  1403 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
  1404         another of the system-wide error codes.
       
  1405 @since	7.0s
       
  1406 */
       
  1407 EXPORT_C TInt CMMFObjectContainer::FindMMFObject(const TMMFMessageDestination& aObjectHandle, CMMFObject*& aObjectFound)
       
  1408 	{
       
  1409 	// Need to find the appropriate object in the array of CMMFObjects
       
  1410 	TInt error = KErrNotFound;
       
  1411 	for (TInt i=0; i<iObjects.Count(); i++)
       
  1412 		{
       
  1413 		CMMFObject* obj = iObjects[i];
       
  1414 		if (obj->Handle() == aObjectHandle)
       
  1415 			{
       
  1416 			error = KErrNone;
       
  1417 			aObjectFound = obj;
       
  1418 			break;
       
  1419 			}
       
  1420 		}
       
  1421 	return error;
       
  1422 	}
       
  1423 
       
  1424 const RPointerArray<CMMFObject>& CMMFObjectContainer::MMFObjects()
       
  1425 	{
       
  1426 	return iObjects;
       
  1427 	}
       
  1428 	
       
  1429 TInt CMMFObjectContainer::FindMMFObject(const CMMFObject& aObject, TInt& aPositionInArray)
       
  1430 	{
       
  1431 	TInt error = KErrNotFound;
       
  1432 	for (TInt i=0; i<iObjects.Count(); i++)
       
  1433 		{
       
  1434 		CMMFObject* obj = iObjects[i];
       
  1435 		if (*obj == aObject)
       
  1436 			{
       
  1437 			error = KErrNone;
       
  1438 			aPositionInArray = i;
       
  1439 			break;
       
  1440 			}
       
  1441 		}
       
  1442 	return error;
       
  1443 	}
       
  1444 
       
  1445 TInt CMMFObjectContainer::GenerateObjectHandle()
       
  1446 	{
       
  1447 	return iNextObjectHandle++;
       
  1448 	}
       
  1449 
       
  1450 
       
  1451 CLogonMonitor::CLogonMonitor(MLogonMonitorObserver* aLogonMonitorObserver) 
       
  1452 : CActive(EPriorityStandard)
       
  1453 	{
       
  1454 	iLogonMonitorObserver = aLogonMonitorObserver;
       
  1455 	}
       
  1456 	
       
  1457 void CLogonMonitor::ConstructL()
       
  1458 	{
       
  1459 	if (CActiveScheduler::Current()==0)
       
  1460 		{
       
  1461 		iScheduler = new (ELeave) CActiveScheduler;
       
  1462 		CActiveScheduler::Install(iScheduler);
       
  1463 		}
       
  1464 		
       
  1465 	CActiveScheduler::Add(this);
       
  1466 	}
       
  1467 	
       
  1468 CLogonMonitor* CLogonMonitor::NewL(MLogonMonitorObserver* aLogonMonitorObserver)
       
  1469 	{
       
  1470 	CLogonMonitor* self = new (ELeave) CLogonMonitor(aLogonMonitorObserver);
       
  1471 	CleanupStack::PushL(self);
       
  1472 	self->ConstructL();
       
  1473 	CleanupStack::Pop(self);
       
  1474 	return self;
       
  1475 	}
       
  1476 
       
  1477 CLogonMonitor::~CLogonMonitor()
       
  1478 	{
       
  1479 	Cancel();
       
  1480 	
       
  1481 	if (iScheduler)
       
  1482 		{
       
  1483 		CActiveScheduler::Install(NULL);
       
  1484 		delete iScheduler;
       
  1485 		}
       
  1486 	}
       
  1487 
       
  1488 void CLogonMonitor::StartMonitoring(RThread& aThread)
       
  1489 	{
       
  1490 	ASSERT(!iThread);
       
  1491 	
       
  1492 	iThread = &aThread;
       
  1493 	iThread->Logon(iStatus);
       
  1494 	SetActive();
       
  1495 	}
       
  1496 
       
  1497 void CLogonMonitor::RunL()
       
  1498 	{
       
  1499 	iServer.Close();
       
  1500 	iLogonMonitorObserver->ThreadTerminated();
       
  1501 	}
       
  1502 
       
  1503 void CLogonMonitor::DoCancel()
       
  1504 	{
       
  1505 	ASSERT(iThread);
       
  1506 	
       
  1507 	iThread->LogonCancel(iStatus);
       
  1508 	iThread = NULL;
       
  1509 	}
       
  1510 
       
  1511 RServer2& CLogonMonitor::Server()
       
  1512 	{
       
  1513 	return iServer;
       
  1514 	}
       
  1515 	
       
  1516 CMMFControllerExtendedData::CMMFControllerExtendedData()
       
  1517 	: CMMFObject(KUidMMFControllerExtendedDataHolder), iSourceSinkInitData(NULL)
       
  1518 	{
       
  1519 	iClientThreadId = 0;
       
  1520 	iSecureDrmMode = EFalse;
       
  1521 	}
       
  1522 
       
  1523 CMMFControllerExtendedData::~CMMFControllerExtendedData()
       
  1524 	{
       
  1525 	ResetSourceSinkInitData();
       
  1526 	}
       
  1527 	
       
  1528 void CMMFControllerExtendedData::SetSourceSinkInitData(HBufC8* aSourceSinkInitData)
       
  1529 	{
       
  1530 	ResetSourceSinkInitData();
       
  1531 	iSourceSinkInitData = aSourceSinkInitData;
       
  1532 	}
       
  1533 
       
  1534 HBufC8* CMMFControllerExtendedData::SourceSinkInitData() const
       
  1535 	{
       
  1536 	return iSourceSinkInitData;
       
  1537 	}
       
  1538 
       
  1539 void CMMFControllerExtendedData::ResetSourceSinkInitData()
       
  1540 	{
       
  1541 	if (iSourceSinkInitData)
       
  1542 		{
       
  1543 		delete iSourceSinkInitData;
       
  1544 		iSourceSinkInitData = NULL;
       
  1545 		}
       
  1546 	}
       
  1547 
       
  1548 void CMMFControllerExtendedData::SetClientThreadId(TThreadId aClientThreadId)
       
  1549 	{
       
  1550 	iClientThreadId = aClientThreadId;
       
  1551 	}
       
  1552 
       
  1553 TThreadId CMMFControllerExtendedData::ClientThreadId() const
       
  1554 	{
       
  1555 	return iClientThreadId;
       
  1556 	}
       
  1557 
       
  1558 void CMMFControllerExtendedData::SetSecureDrmMode(TBool aSecureDrmMode)
       
  1559 	{
       
  1560 	iSecureDrmMode = aSecureDrmMode;
       
  1561 	}
       
  1562 
       
  1563 TBool CMMFControllerExtendedData::SecureDrmMode() const
       
  1564 	{
       
  1565 	return iSecureDrmMode;
       
  1566 	}
       
  1567 
       
  1568 void CMMFControllerExtendedData::HandleRequest(TMMFMessage& /*aMessage*/)
       
  1569 	{
       
  1570 	// This function is not suppose to be called.
       
  1571 #ifdef _DEBUG
       
  1572 	Panic(EPanicBadInvariant);
       
  1573 #endif
       
  1574 	}
       
  1575