os/mm/mmlibs/mmfw/src/ControllerFramework/MMFControllerFramework.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/mmlibs/mmfw/src/ControllerFramework/MMFControllerFramework.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1575 @@
     1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <e32math.h>
    1.20 +#include <mmf/server/mmfdrmpluginserverproxy.h>
    1.21 +#include "mmfcontrollerframework.h"
    1.22 +#include "mmfcontroller.h"
    1.23 +#include "mmfcontrollerheap.h"
    1.24 +#include "mmfcontrollerframeworkpriv.h"
    1.25 +#include "mmfcontrollerpatchdata.h"
    1.26 +
    1.27 +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    1.28 +#include <mmf/common/mmfcontrollerextendeddata.h>
    1.29 +#include <mmf/common/mmfcustomcommandparsermanager.h>
    1.30 +#include <mmf/common/mmfcontrollerframeworkclasses.h>
    1.31 +#endif
    1.32 +
    1.33 +// Panic
    1.34 +   
    1.35 +enum
    1.36 +	{
    1.37 +	EPanicHeapHalfOpen=1,
    1.38 +	EPanicHeapOpenWithoutTls,
    1.39 +	EPanicReleaseWithoutRegister,
    1.40 +	EPanicBadInvariant
    1.41 +	};
    1.42 +	
    1.43 +#ifdef _DEBUG
    1.44 +static void Panic(TInt aReason)
    1.45 +	{
    1.46 +	_LIT(KControllerFramework, "ControllerFramework");
    1.47 +	User::Panic(KControllerFramework, aReason);
    1.48 +	}
    1.49 +#endif
    1.50 +
    1.51 +EXPORT_C RMMFControllerProxy::RMMFControllerProxy() :
    1.52 +	iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFControllerProxy, KMMFObjectHandleControllerProxy)),
    1.53 +	iLogonAO(NULL), iThreadPriority(static_cast<TThreadPriority>(KDefaultMMFControllerThreadPriority)), iFlags(0)
    1.54 +	{
    1.55 +	iSubThread.Close();//iSubThread is automatically initialised to be a handle to this thread!
    1.56 +	}
    1.57 +
    1.58 +TInt RMMFControllerProxy::LoadController(
    1.59 +	TUid aControllerUid, 
    1.60 + 	const CMMFControllerImplementationInformation& aControllerInfo,
    1.61 + 	TBool aUseSharedHeap,
    1.62 + 	TBool aNoDRMCap)
    1.63 +	{
    1.64 +	// First check that we haven't already created the subthread
    1.65 +	if (iSubThread.Handle() != 0)
    1.66 +		return KErrAlreadyExists;
    1.67 +	
    1.68 +#ifdef SYMBIAN_FORCE_USE_SHARED_HEAP
    1.69 +	aUseSharedHeap = ETrue;
    1.70 +#endif
    1.71 +
    1.72 +	//determine what maximum heap size this thread should be created with
    1.73 +	TUint maxHeapSize =0;
    1.74 +	TInt error = KErrNone;
    1.75 +	maxHeapSize = aControllerInfo.HeapSpaceRequired();
    1.76 +	TUint stackSize = aControllerInfo.StackSize();
    1.77 +	
    1.78 +	ASSERT(!iLogonAO);
    1.79 +	TRAP(error, iLogonAO = CLogonMonitor::NewL(this));
    1.80 +	
    1.81 +	if (!error)
    1.82 +		{
    1.83 +		if (aNoDRMCap && aControllerInfo.SupportsSecureDRMProcessMode())
    1.84 +			{
    1.85 +			error = DoCreateSessionForNoDRMCapClient(maxHeapSize, aUseSharedHeap, stackSize);
    1.86 +			}
    1.87 +		else
    1.88 +			{
    1.89 +			// server2 will be set in this function call
    1.90 +			error = DoCreateSubThread(&iLogonAO->Server(), maxHeapSize, aUseSharedHeap, stackSize);
    1.91 +		
    1.92 +			// Now create a session with the controller proxy server running in the subthread
    1.93 +			if (!error)
    1.94 +				{
    1.95 +				// create a session with iServer2 (local server)
    1.96 +				error = CreateSession(iLogonAO->Server(), KMMFControllerProxyVersion);
    1.97 +				}
    1.98 +			}
    1.99 +		}
   1.100 +
   1.101 +	// Finally, tell the controller proxy server to load the relevant plugin
   1.102 +	if (!error)
   1.103 +		{
   1.104 +		TMMFUidPckg uidPckg(aControllerUid);
   1.105 +		error = SendSync(iDestinationPckg, 
   1.106 +						 EMMFControllerProxyLoadControllerPluginByUid, 
   1.107 +						 uidPckg, 
   1.108 +						 KNullDesC8);
   1.109 +		}
   1.110 +
   1.111 +	// If an error occurred with any of the above, close all the handles
   1.112 +	if (error)
   1.113 +		Close();
   1.114 +
   1.115 +	return error;
   1.116 +	}
   1.117 +
   1.118 +
   1.119 +EXPORT_C TInt RMMFControllerProxy::LoadController(TUid aControllerUid, TBool aUseSharedHeap)
   1.120 +	{
   1.121 + 	CMMFControllerImplementationInformation* controllerInfo = NULL;
   1.122 + 	
   1.123 + 	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
   1.124 +	if (!err && controllerInfo)
   1.125 +		{
   1.126 +		err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, EFalse);
   1.127 +		delete controllerInfo;
   1.128 +		}
   1.129 + 	return err;
   1.130 +	}
   1.131 +
   1.132 +EXPORT_C TInt RMMFControllerProxy::LoadController(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
   1.133 +	{
   1.134 +	return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, EFalse);
   1.135 +	}
   1.136 +
   1.137 +EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(TUid aControllerUid, TBool aUseSharedHeap)
   1.138 +	{
   1.139 +	CMMFControllerImplementationInformation* controllerInfo = NULL;
   1.140 +	
   1.141 +	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
   1.142 +	if (!err && controllerInfo)
   1.143 +		{
   1.144 +		err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, ETrue);
   1.145 +		delete controllerInfo;
   1.146 +		}
   1.147 +	return err;
   1.148 +	}
   1.149 +	
   1.150 +EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
   1.151 +	{
   1.152 +	return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, ETrue);
   1.153 +	}
   1.154 +
   1.155 +TUint RMMFControllerProxy::ControllersMaxHeapSizeL(TUid aControllerUid)
   1.156 +	{
   1.157 +	CMMFControllerImplementationInformation* controllerInfo = NULL;
   1.158 +
   1.159 +	TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
   1.160 +
   1.161 +
   1.162 +	TUint maxHeapSize = KMMFDefaultControllerThreadHeapSize;
   1.163 +	
   1.164 +	if((err != KErrNone) && (err != KErrCorrupt))
   1.165 +		{
   1.166 +		delete controllerInfo;
   1.167 +		User::Leave(err);
   1.168 +		}
   1.169 +
   1.170 +
   1.171 +	if(controllerInfo && (err == KErrNone))
   1.172 +		maxHeapSize = controllerInfo->HeapSpaceRequired();
   1.173 +
   1.174 +	delete controllerInfo;
   1.175 +
   1.176 +	return maxHeapSize;
   1.177 +	}
   1.178 +
   1.179 +
   1.180 +TInt RMMFControllerProxy::DoCreateSubThread(RServer2* aServer2, TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
   1.181 +	{
   1.182 +	TInt error = KErrNone;
   1.183 +
   1.184 +	TControllerProxyServerParams params;
   1.185 +	params.iServer = aServer2;
   1.186 +	params.iUsingSharedHeap = aUseSharedHeap;
   1.187 +
   1.188 +#ifdef SYMBIAN_USE_CLIENT_HEAP
   1.189 +	// controller threads share the *client* heap (intended for out of memory testing)
   1.190 +	error = iSubThread.Create(_L(""), &CMMFControllerProxyServer::StartThread, 
   1.191 +			aStackSize, NULL, &params, EOwnerThread);
   1.192 +#else
   1.193 +	if( aUseSharedHeap )
   1.194 +		{
   1.195 +		//controller threads all share a controller heap
   1.196 +		CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
   1.197 +		if(contHeap == NULL)
   1.198 +			{
   1.199 +			TRAP(error, contHeap = CMMFControllerHeap::NewL());
   1.200 +			if(error)
   1.201 +				{			
   1.202 +				return error;	
   1.203 +				}
   1.204 +				
   1.205 +			Dll::SetTls(contHeap);
   1.206 +			}
   1.207 +			
   1.208 +		__ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap)==0, Panic(EPanicHeapHalfOpen));
   1.209 +			
   1.210 +		RHeap* sharedHeap = contHeap->RegisterHeap();
   1.211 +		// We've registered, so record the fact so can "unregister" on close or error
   1.212 +		iFlags |= EFlagOpenedSharedHeap; 
   1.213 +		
   1.214 +		error = iSubThread.Create(KNullDesC, &CMMFControllerProxyServer::StartThread,
   1.215 +				aStackSize, sharedHeap, 						
   1.216 +				&params, EOwnerThread);		
   1.217 +		}
   1.218 +	else
   1.219 +		{	
   1.220 +		// Threads create own heap (default behaviour)
   1.221 +		if(aMaxHeapSize < static_cast<TUint>(KMinHeapSize))
   1.222 +			aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic
   1.223 +		else if(aMaxHeapSize >  static_cast<TUint>(KMMFControllerProxyMaxHeapSize))
   1.224 +			aMaxHeapSize = KMMFControllerProxyMaxHeapSize;
   1.225 +		
   1.226 +		TThreadCreateInfo threadSettings (KNullDesC, &CMMFControllerProxyServer::StartThread,
   1.227 +										  aStackSize, &params);
   1.228 +		threadSettings.SetCreateHeap(KMinHeapSize, aMaxHeapSize);
   1.229 +		threadSettings.SetOwner(EOwnerThread);
   1.230 +		threadSettings.SetPaging(TThreadCreateInfo::EUnpaged);
   1.231 +		
   1.232 +		error = iSubThread.Create(threadSettings);
   1.233 +		}
   1.234 +#endif
   1.235 +
   1.236 +	if (error)
   1.237 +		{
   1.238 +		return error;
   1.239 +		}
   1.240 +
   1.241 +	TRequestStatus rendezvous;
   1.242 +	iSubThread.Rendezvous(rendezvous);
   1.243 +	if (rendezvous != KRequestPending)
   1.244 +		{
   1.245 +		iSubThread.Kill(0);
   1.246 +		}
   1.247 +	else
   1.248 +		{
   1.249 +		iLogonAO->StartMonitoring(iSubThread);
   1.250 +		if (iLogonAO->iStatus != KRequestPending)
   1.251 +			{
   1.252 +			// Failed to logon
   1.253 +			iSubThread.RendezvousCancel(rendezvous);
   1.254 +			User::WaitForRequest(rendezvous);
   1.255 +			iSubThread.Kill(0);
   1.256 +			iSubThread.Close();
   1.257 +			return iLogonAO->iStatus.Int();
   1.258 +			}
   1.259 +		else
   1.260 +			{
   1.261 +			iSubThread.SetPriority(iThreadPriority);
   1.262 +			iSubThread.Resume();
   1.263 +			}
   1.264 +		}
   1.265 +		
   1.266 +	User::WaitForRequest(rendezvous); // wait for startup or death
   1.267 +	
   1.268 +	if (rendezvous != KErrNone)
   1.269 +		{
   1.270 +		iLogonAO->Cancel();
   1.271 +		iSubThread.Close();
   1.272 +		// if open failed, but we registered the heap, need to release
   1.273 +		if((iFlags&EFlagOpenedSharedHeap))
   1.274 +			{
   1.275 +			ReleaseHeap();
   1.276 +			}		
   1.277 +		}
   1.278 +		
   1.279 +	return rendezvous.Int();
   1.280 +	}
   1.281 +
   1.282 +EXPORT_C void RMMFControllerProxy::Close()
   1.283 +	{
   1.284 +#ifdef _DEBUG
   1.285 +	_LIT(KMMFClientThreadPanic, "MMFClientThread");
   1.286 +#endif
   1.287 +	// check if thread was created
   1.288 +	TBool subThreadCreated = EFalse;
   1.289 +	TRequestStatus logoffStatus;
   1.290 +	TBool logoffFailed = EFalse;
   1.291 +	if (iSubThread.Handle() != KNullHandle)
   1.292 +		{
   1.293 +		subThreadCreated = ETrue;
   1.294 +		iLogonAO->Cancel();
   1.295 +		iSubThread.Logon(logoffStatus);
   1.296 +		
   1.297 +		if (logoffStatus == KErrNoMemory && iSubThread.ExitType() == EExitPending)
   1.298 +			{
   1.299 +			// Logon() call has failed because of a lack of memory
   1.300 +			logoffFailed = ETrue;
   1.301 +			}
   1.302 +		}
   1.303 +
   1.304 +	// Close the controller and wait for its exit.
   1.305 +	// Close the session to signal the controller proxy server to shut down.
   1.306 +	RHandleBase::Close();
   1.307 +	
   1.308 +	// Now wait for the death of the subthread if we have a valid handle...
   1.309 +	if (subThreadCreated)
   1.310 +		{
   1.311 +		RProcess thisProcess;
   1.312 +		RProcess controllerProcess;
   1.313 +		iSubThread.Process(controllerProcess);	// ignore error, best try
   1.314 +		TBool secureDrmMode = thisProcess.Id() != controllerProcess.Id();
   1.315 +		thisProcess.Close();
   1.316 +		controllerProcess.Close();
   1.317 +				
   1.318 +		RTimer timer;
   1.319 +		TInt err = timer.CreateLocal();
   1.320 +		// If we managed to create the timer and logon to the thread, 
   1.321 +		// wait for both the death and the timeout to minimise the risk of deadlock
   1.322 +		if (!err && !logoffFailed)
   1.323 +			{
   1.324 +			TRequestStatus timeout;
   1.325 +			timer.After(timeout, KMmfControllerThreadShutdownTimeout);
   1.326 +			User::WaitForRequest(logoffStatus, timeout);
   1.327 +			if (logoffStatus == KRequestPending)
   1.328 +				{
   1.329 +				// we have timed out.  Kill the controller thread
   1.330 +				iSubThread.LogonCancel(logoffStatus);
   1.331 +				User::WaitForRequest(logoffStatus);
   1.332 +				
   1.333 +				if (!secureDrmMode)
   1.334 +					{
   1.335 +					// Controller server thread is created in current process
   1.336 +				#ifdef _DEBUG
   1.337 +					iSubThread.Panic(KMMFClientThreadPanic,KErrDied);
   1.338 +				#else
   1.339 +					iSubThread.Kill(KErrDied);
   1.340 +				#endif
   1.341 +					}
   1.342 +				else
   1.343 +					{
   1.344 +					// Controller server thread is created through DRM plugin server
   1.345 +					RMMFDRMPluginServerProxy server;
   1.346 +					// ignore all RMMFDRMPluginServerProxy errors, best try
   1.347 +					err = server.Open();
   1.348 +					if (err == KErrNone)
   1.349 +						{
   1.350 +					#ifdef _DEBUG
   1.351 +						server.PanicControllerThread(iSubThread.Id(), KMMFClientThreadPanic, KErrDied);
   1.352 +					#else
   1.353 +						server.KillControllerThread(iSubThread.Id(), KErrDied);
   1.354 +					#endif
   1.355 +						server.Close();
   1.356 +						}
   1.357 +					}
   1.358 +				}
   1.359 +			else
   1.360 +				{
   1.361 +				// subthread has exited. Cancel the timer.
   1.362 +				timer.Cancel();
   1.363 +				User::WaitForRequest(timeout);
   1.364 +				}
   1.365 +			}
   1.366 +		else
   1.367 +			{
   1.368 +			// We have no timer or we can't logon to the thread so we'll just poll the thread status a maximum
   1.369 +			// of 10 times and kill the thread if it hasn't exited after the polling
   1.370 +			for (TInt i=0; i<10 && iSubThread.ExitType() == EExitPending; ++i)
   1.371 +				{
   1.372 +				User::After(KMmfControllerThreadShutdownTimeout/10);	// wait for a while
   1.373 +				}
   1.374 +				
   1.375 +			if (iSubThread.ExitType() == EExitPending)
   1.376 +				{
   1.377 +				// The polling hasn't been succesful so we kill the thread
   1.378 +				if (!secureDrmMode)
   1.379 +					{
   1.380 +					iSubThread.Kill(KErrDied);
   1.381 +					}
   1.382 +				else
   1.383 +					{
   1.384 +					// Controller server thread is created through DRM plugin server
   1.385 +					RMMFDRMPluginServerProxy server;
   1.386 +					// ignore all RMMFDRMPluginServerProxy errors, best try
   1.387 +					err = server.Open();
   1.388 +					if (err == KErrNone)
   1.389 +						{
   1.390 +						server.KillControllerThread(iSubThread.Id(), KErrDied);
   1.391 +						}
   1.392 +					}
   1.393 +				}
   1.394 +				
   1.395 +			User::WaitForRequest(logoffStatus);
   1.396 +			}
   1.397 +		timer.Close();
   1.398 +		}
   1.399 +
   1.400 +	// Close the handle to the controller thread
   1.401 +	iSubThread.Close();
   1.402 +	// Delete the Logon AO
   1.403 +	if (iLogonAO)
   1.404 +		{
   1.405 +		delete iLogonAO;
   1.406 +		iLogonAO = NULL;
   1.407 +		}
   1.408 +	// if this is last thread to be killed delete shared heap
   1.409 +	if((iFlags&EFlagOpenedSharedHeap))
   1.410 +		{
   1.411 +		ReleaseHeap();
   1.412 +		}	
   1.413 +	}
   1.414 +
   1.415 +// Release the shared heap, should only be called if has previously been registered
   1.416 +// by this thread
   1.417 +void RMMFControllerProxy::ReleaseHeap()
   1.418 +	{
   1.419 +	__ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap), Panic(EPanicReleaseWithoutRegister));
   1.420 +
   1.421 +	CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
   1.422 +	__ASSERT_DEBUG(contHeap!=NULL, Panic(EPanicHeapOpenWithoutTls));
   1.423 +	
   1.424 +	if(contHeap != NULL)
   1.425 +		{
   1.426 +		TInt refCount = contHeap->ReleaseHeap();
   1.427 +		if(refCount == 0)
   1.428 +			{  //no other controllers using the heap
   1.429 +			delete contHeap;
   1.430 +			Dll::SetTls(NULL);
   1.431 +			}
   1.432 +		}
   1.433 +		
   1.434 +	iFlags &= ~EFlagOpenedSharedHeap; // clear flag since we've released the heap
   1.435 +	}
   1.436 +
   1.437 +EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) const
   1.438 +	{
   1.439 +	// Make sure we have been opened
   1.440 +	if (iSubThread.Handle() == 0)
   1.441 +		{
   1.442 +		return KErrNotReady;
   1.443 +		}
   1.444 +	else
   1.445 +		return SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom);
   1.446 +	}
   1.447 +
   1.448 +
   1.449 +EXPORT_C TInt RMMFControllerProxy::SendSync(TInt aFunction, const TIpcArgs& aIpcArgs) const
   1.450 +	{
   1.451 +	// Make sure we have been opened
   1.452 +	if (iSubThread.Handle() == 0)
   1.453 +		{
   1.454 +		return KErrNotReady;
   1.455 +		}
   1.456 +	else
   1.457 +		return RSessionBase::SendReceive(aFunction, aIpcArgs);
   1.458 +	}
   1.459 +	
   1.460 +EXPORT_C void RMMFControllerProxy::SendAsync(TInt aFunction, const TIpcArgs& aIpcArgs, TRequestStatus& aStatus) const
   1.461 +	{
   1.462 +	// Make sure we have been opened
   1.463 +	if (iSubThread.Handle() == 0)
   1.464 +		{
   1.465 +		TRequestStatus* status = &aStatus;
   1.466 +		User::RequestComplete(status, KErrNotReady);
   1.467 +		}
   1.468 +	else
   1.469 +		RSessionBase::SendReceive(aFunction, aIpcArgs, aStatus);
   1.470 +	}
   1.471 +
   1.472 +
   1.473 +
   1.474 +EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) const
   1.475 +	{
   1.476 +	// Make sure we have been opened
   1.477 +	if (iSubThread.Handle() == 0)
   1.478 +		{
   1.479 +		return KErrNotReady;
   1.480 +		}
   1.481 +	else
   1.482 +		return SendReceive(aFunction, aDestination, aDataTo1, aDataTo2);
   1.483 +	}
   1.484 +
   1.485 +EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) const
   1.486 +	{
   1.487 +	if (iSubThread.Handle() == 0)
   1.488 +		{
   1.489 +		TRequestStatus* stat = &aStatus;
   1.490 +		User::RequestComplete(stat, KErrNotReady);
   1.491 +		}
   1.492 +	else
   1.493 +		SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom, aStatus);
   1.494 +	}
   1.495 +
   1.496 +EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) const
   1.497 +	{
   1.498 +	if (iSubThread.Handle() == 0)
   1.499 +		{
   1.500 +		TRequestStatus* stat = &aStatus;
   1.501 +		User::RequestComplete(stat, KErrNotReady);
   1.502 +		}
   1.503 +	else
   1.504 +		SendReceive(aFunction, aDestination, aDataTo1, aDataTo2, aStatus);
   1.505 +	}
   1.506 +
   1.507 +EXPORT_C void RMMFControllerProxy::ReceiveEvents(TMMFEventPckg& aEvent, TRequestStatus& aStatus)
   1.508 +	{
   1.509 +	SendAsync(iDestinationPckg, EMMFControllerProxyReceiveEvents, KNullDesC8, KNullDesC8, aEvent, aStatus);
   1.510 +	}
   1.511 +
   1.512 +EXPORT_C TInt RMMFControllerProxy::CancelReceiveEvents()
   1.513 +	{
   1.514 +	return SendSync(iDestinationPckg, EMMFControllerProxyCancelReceiveEvents, KNullDesC8, KNullDesC8);
   1.515 +	}
   1.516 +
   1.517 +EXPORT_C TInt RMMFControllerProxy::SetThreadPriority(const TThreadPriority& aPriority) const
   1.518 +	{
   1.519 +	TInt err = KErrNone;
   1.520 +
   1.521 +	if (iSubThread.Handle() == 0)
   1.522 +		{
   1.523 +		err = KErrNotReady;
   1.524 +		}
   1.525 +	else
   1.526 +		{
   1.527 +		if (iThreadPriority != aPriority)
   1.528 +			{
   1.529 +			// This is a const method so cast it away to store the priority
   1.530 +			RMMFControllerProxy* nonConstThis = const_cast<RMMFControllerProxy*>(this);
   1.531 +			nonConstThis->iThreadPriority = aPriority;
   1.532 +			}
   1.533 +			
   1.534 +		// check controller thread creation location
   1.535 +		RProcess thisProcess;
   1.536 +		RProcess controllerProcess;
   1.537 +		err = iSubThread.Process(controllerProcess);
   1.538 +		
   1.539 +		if (err == KErrNone)
   1.540 +			{
   1.541 +			if (thisProcess.Id() == controllerProcess.Id())
   1.542 +				{
   1.543 +				// Controller server thread is created in current process
   1.544 +				if (iSubThread.Priority() != iThreadPriority)
   1.545 +					{
   1.546 +					iSubThread.Suspend();
   1.547 +					iSubThread.SetPriority(iThreadPriority);
   1.548 +					iSubThread.Resume();
   1.549 +					}
   1.550 +				}
   1.551 +			else
   1.552 +				{
   1.553 +				// Controller server thread is created through DRM plugin server
   1.554 +				RMMFDRMPluginServerProxy server;
   1.555 +				err = server.Open();
   1.556 +				if (err == KErrNone)
   1.557 +					{
   1.558 +					err = server.SetThreadPriority(iSubThread.Id(), iThreadPriority);
   1.559 +					server.Close();
   1.560 +					}
   1.561 +				}
   1.562 +			}
   1.563 +		thisProcess.Close();
   1.564 +		controllerProcess.Close();
   1.565 +		}
   1.566 +	return err;
   1.567 +	}
   1.568 +	
   1.569 +void RMMFControllerProxy::ThreadTerminated()
   1.570 +	{
   1.571 +	// The controller subthread has died and the controller should be closed
   1.572 +	iSubThread.Close();
   1.573 +	}
   1.574 +
   1.575 +TInt RMMFControllerProxy::DoCreateSessionForNoDRMCapClient(TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
   1.576 +	{
   1.577 +	TThreadId tid;
   1.578 +	RMMFDRMPluginServerProxy server;
   1.579 +    TInt error = server.Open();
   1.580 +    
   1.581 +    if(!error)
   1.582 +    	{
   1.583 +    	error = server.LaunchControllerServer(aMaxHeapSize, aUseSharedHeap, tid, aStackSize);
   1.584 +    	}		    
   1.585 +    if(!error)
   1.586 +		{
   1.587 +		error = iSubThread.Open(tid, EOwnerThread);
   1.588 +		if(!error)
   1.589 +			{
   1.590 +			iLogonAO->StartMonitoring(iSubThread);
   1.591 +			if (iLogonAO->iStatus != KRequestPending)
   1.592 +				{
   1.593 +				// Failed to logon
   1.594 +				server.KillControllerThread(tid, 0);
   1.595 +				iSubThread.Close();
   1.596 +				error = iLogonAO->iStatus.Int();
   1.597 +				}
   1.598 +			}
   1.599 +		else
   1.600 +			{
   1.601 +			// Failed to open thread handle
   1.602 +			server.KillControllerThread(tid, 0);
   1.603 +			}
   1.604 +		}
   1.605 +	if(!error)
   1.606 +		{
   1.607 +		error = server.SetThreadPriority(tid, iThreadPriority);
   1.608 +		if(!error)
   1.609 +			{
   1.610 +			error = SetReturnedHandle(server.GetControllerSessionHandle());	
   1.611 +			}
   1.612 +		if(error)
   1.613 +			{
   1.614 +			// Failed to create session with controller
   1.615 +			iLogonAO->Cancel();
   1.616 +			server.KillControllerThread(tid, 0);
   1.617 +			iSubThread.Close();
   1.618 +			}
   1.619 +		}
   1.620 +    server.Close();
   1.621 +    return error;
   1.622 +	}
   1.623 +
   1.624 +
   1.625 +// RMMFCustomCommandsBase
   1.626 +
   1.627 +/**
   1.628 +Constructor.
   1.629 +
   1.630 +@param  aController
   1.631 +        A reference to the controller client class that will be used to send
   1.632 +        custom commands to the controller plugin.
   1.633 +@param  aInterfaceId
   1.634 +        The UID of the custom command interface that is provided by this client
   1.635 +        API class.
   1.636 +
   1.637 +@since 7.0s
   1.638 +*/
   1.639 +EXPORT_C RMMFCustomCommandsBase::RMMFCustomCommandsBase(RMMFController& aController, TUid aInterfaceId)
   1.640 +	: iController(aController), iDestinationPckg(aInterfaceId)
   1.641 +	{
   1.642 +	}
   1.643 +
   1.644 +
   1.645 +// TMMFMessageDestination
   1.646 +EXPORT_C TMMFMessageDestination::TMMFMessageDestination()
   1.647 +	: iInterfaceId(KNullUid), iDestinationHandle(KMMFObjectHandleController)
   1.648 +	{
   1.649 +	}
   1.650 +
   1.651 +EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId)
   1.652 +	: iInterfaceId(aInterfaceId), iDestinationHandle(KMMFObjectHandleController)
   1.653 +	{
   1.654 +	}
   1.655 +
   1.656 +EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId, TInt aDestinationHandle)
   1.657 +	: iInterfaceId(aInterfaceId), iDestinationHandle(aDestinationHandle)
   1.658 +	{
   1.659 +	}
   1.660 +
   1.661 +EXPORT_C TMMFMessageDestination::TMMFMessageDestination(const TMMFMessageDestination& aOther)
   1.662 +	: iInterfaceId(aOther.iInterfaceId), iDestinationHandle(aOther.iDestinationHandle)
   1.663 +	{
   1.664 +	}
   1.665 +
   1.666 +EXPORT_C TUid TMMFMessageDestination::InterfaceId() const
   1.667 +	{
   1.668 +	return iInterfaceId;
   1.669 +	}
   1.670 +
   1.671 +EXPORT_C TInt TMMFMessageDestination::DestinationHandle() const
   1.672 +	{
   1.673 +	return iDestinationHandle;
   1.674 +	}
   1.675 +
   1.676 +EXPORT_C TBool TMMFMessageDestination::operator==(const TMMFMessageDestination& aOther) const
   1.677 +	{
   1.678 +	return ((iInterfaceId==aOther.iInterfaceId) && (iDestinationHandle==aOther.iDestinationHandle));
   1.679 +	}
   1.680 +
   1.681 +
   1.682 +
   1.683 +// CMMFControllerProxySession
   1.684 +CMMFControllerProxySession* CMMFControllerProxySession::NewL()
   1.685 +	{
   1.686 +	CMMFControllerProxySession* s = new(ELeave) CMMFControllerProxySession;
   1.687 +	return s;
   1.688 +	}
   1.689 +
   1.690 +void CMMFControllerProxySession::CreateL(const CMmfIpcServer& aServer)
   1.691 +	{
   1.692 +	CMmfIpcSession::CreateL(aServer);
   1.693 +	iServer = STATIC_CAST(CMMFControllerProxyServer*, (CONST_CAST(CMmfIpcServer*, &aServer)));
   1.694 +	iServer->SessionCreated();
   1.695 +	}
   1.696 +
   1.697 +CMMFControllerProxySession::~CMMFControllerProxySession()
   1.698 +	{
   1.699 +	delete iController;
   1.700 +	delete iEventReceiver;
   1.701 +	iEvents.Close();
   1.702 +	iServer->SessionDestroyed();
   1.703 +	}
   1.704 +
   1.705 +
   1.706 +
   1.707 +void CMMFControllerProxySession::ServiceL(const RMmfIpcMessage& aMessage)
   1.708 +	{
   1.709 +	TMMFMessage message(aMessage);
   1.710 +	// Get the destination info from the client.
   1.711 +	message.FetchDestinationL();
   1.712 +
   1.713 +	if (message.Destination().InterfaceId() == KUidInterfaceMMFControllerProxy)
   1.714 +		{
   1.715 +		// Message for controller proxy so decode here
   1.716 +		TBool complete = EFalse;
   1.717 +		switch (message.Function())
   1.718 +			{
   1.719 +		case EMMFControllerProxyReceiveEvents:
   1.720 +			complete = ReceiveEventsL(message);
   1.721 +			break;
   1.722 +		case EMMFControllerProxyCancelReceiveEvents:
   1.723 +			complete = CancelReceiveEvents(message);
   1.724 +			break;
   1.725 +		case EMMFControllerProxyLoadControllerPluginByUid:
   1.726 +			complete = LoadControllerL(message);
   1.727 +			break;
   1.728 +		default:
   1.729 +			User::Leave(KErrNotSupported);
   1.730 +			}
   1.731 +		if (complete)
   1.732 +			message.Complete(KErrNone);
   1.733 +		}
   1.734 +	else
   1.735 +		{
   1.736 +		// Message for controller so forward on to controller baseclass
   1.737 +		if (iController)
   1.738 +			iController->HandleRequestL(message);
   1.739 +		else
   1.740 +			User::Leave(KErrNotReady);
   1.741 +		}
   1.742 +	}
   1.743 +
   1.744 +CMMFControllerProxySession::CMMFControllerProxySession()
   1.745 +	{
   1.746 +	}
   1.747 +
   1.748 +TBool CMMFControllerProxySession::ReceiveEventsL(TMMFMessage& aMessage)
   1.749 +	{
   1.750 +	if (iEventReceiver)
   1.751 +		User::Leave(KErrAlreadyExists);
   1.752 +	iEventReceiver = CMMFEventReceiver::NewL(aMessage);
   1.753 +	//send the next cached event (if any) to the client
   1.754 +	if (iEvents.Count() > 0)
   1.755 +		{
   1.756 +		TMMFEvent& event = iEvents[0];
   1.757 +		iEventReceiver->SendEvent(event);
   1.758 +		delete iEventReceiver;
   1.759 +		iEventReceiver=NULL;
   1.760 +		iEvents.Remove(0);
   1.761 +		}
   1.762 +	return EFalse;
   1.763 +	}
   1.764 +
   1.765 +TBool CMMFControllerProxySession::CancelReceiveEvents(TMMFMessage& /*aMessage*/)
   1.766 +	{
   1.767 +	delete iEventReceiver;
   1.768 +	iEventReceiver = NULL;
   1.769 +	return ETrue;
   1.770 +	}
   1.771 +
   1.772 +TInt CMMFControllerProxySession::SendEventToClient(const TMMFEvent& aEvent)
   1.773 +	{
   1.774 +	TInt error = KErrNone;
   1.775 +	if (iEventReceiver)
   1.776 +		{
   1.777 +		//send event to client now
   1.778 +		iEventReceiver->SendEvent(aEvent);
   1.779 +		delete iEventReceiver;
   1.780 +		iEventReceiver=NULL;
   1.781 +		error = KErrNone;
   1.782 +		}
   1.783 +	else
   1.784 +		{
   1.785 +		//queue the request for later
   1.786 +		TMMFEvent event(aEvent);
   1.787 +		//if we've exceeded the max number of cached messages, delete the first and append this one to the end
   1.788 +		if (iEvents.Count() >= KMMFControllerProxyMaxCachedMessages)
   1.789 +			iEvents.Remove(0);
   1.790 +		error = iEvents.Append(event);
   1.791 +		}
   1.792 +	return error;
   1.793 +	}
   1.794 +
   1.795 +TBool CMMFControllerProxySession::LoadControllerL(TMMFMessage& aMessage)
   1.796 +	{
   1.797 +	TMMFUidPckg pckg;
   1.798 +	aMessage.ReadData1FromClientL(pckg);
   1.799 +	
   1.800 +	RThread clientThread;
   1.801 +	aMessage.iMessage.ClientL(clientThread);
   1.802 +	CleanupClosePushL(clientThread);
   1.803 +	iController = CMMFController::NewL(pckg(), *this, clientThread.Id());
   1.804 +	CleanupStack::PopAndDestroy(&clientThread);
   1.805 +	return ETrue;
   1.806 +	}
   1.807 +
   1.808 +
   1.809 +
   1.810 +CMMFControllerProxyServer* CMMFControllerProxyServer::NewL(RServer2* aServer2)
   1.811 +	{
   1.812 +	CMMFControllerProxyServer* s = new(ELeave) CMMFControllerProxyServer();
   1.813 +	CleanupStack::PushL(s);
   1.814 +	s->ConstructL(aServer2);
   1.815 +	CleanupStack::Pop(s);
   1.816 +	return s;
   1.817 +	}
   1.818 +
   1.819 +CMMFControllerProxyServer::CMMFControllerProxyServer() :
   1.820 +	CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions)
   1.821 +	{
   1.822 +	}
   1.823 +
   1.824 +void CMMFControllerProxyServer::ConstructL(RServer2* aServer2)
   1.825 +	{
   1.826 +	SetPinClientDescriptors(ETrue);
   1.827 +	
   1.828 +	StartL(KNullDesC);
   1.829 +	*aServer2 = CServer2::Server();
   1.830 +	
   1.831 +	iShutdownTimer = CMMFControllerProxyShutdown::NewL();
   1.832 +	iShutdownTimer->Start();
   1.833 +	}
   1.834 +
   1.835 +CMMFControllerProxyServer::~CMMFControllerProxyServer()
   1.836 +	{
   1.837 +	delete iShutdownTimer;
   1.838 +	}
   1.839 +
   1.840 +EXPORT_C TInt CMMFControllerProxyServer::StartThread(TAny* aParam)
   1.841 +	{
   1.842 +	TInt err = KErrNone;
   1.843 +	//create cleanupstack
   1.844 +	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
   1.845 +	if (!cleanup)
   1.846 +		err = KErrNoMemory;
   1.847 +	if (!err)
   1.848 +		{
   1.849 +		TRAP(err, DoStartThreadL(aParam));
   1.850 +		}
   1.851 +	delete cleanup;
   1.852 +	return err;
   1.853 +	}
   1.854 +	
   1.855 +void CMMFControllerProxyServer::RenameControllerProxyThread()
   1.856 +	{
   1.857 +	RThread thread;
   1.858 +	TThreadId threadId;
   1.859 +	TName name;
   1.860 +	name.Append(KMMFControllerProxyServerName);
   1.861 +	threadId = thread.Id();
   1.862 +	name.AppendNum(threadId.Id(),EHex);
   1.863 +	User::RenameThread(name);
   1.864 +	}
   1.865 +
   1.866 +void CMMFControllerProxyServer::DoStartThreadL(TAny* aParam)
   1.867 +	{
   1.868 +	TControllerProxyServerParams* params = static_cast<TControllerProxyServerParams*>(aParam);
   1.869 +	
   1.870 +	//Rename Current thread to unique name
   1.871 +	RenameControllerProxyThread();
   1.872 +	
   1.873 +#ifndef SYMBIAN_USE_CLIENT_HEAP
   1.874 +	TBool usingSharedHeap = params->iUsingSharedHeap; // take copy since params invalid after Rendezvous
   1.875 +	
   1.876 +	if( ! usingSharedHeap )
   1.877 +		{
   1.878 +		__UHEAP_MARK;
   1.879 +		}
   1.880 +
   1.881 +#endif
   1.882 +	// create and install the active scheduler we need
   1.883 +	CActiveScheduler* s=new(ELeave) CActiveScheduler;
   1.884 +	CleanupStack::PushL(s);
   1.885 +	CActiveScheduler::Install(s);
   1.886 +	// create the server (leave it on the cleanup stack)
   1.887 +	CleanupStack::PushL(CMMFControllerProxyServer::NewL( params->iServer ) );
   1.888 +	// Initialisation complete, now signal the client
   1.889 +	RThread::Rendezvous(KErrNone);
   1.890 +	// Ready to run
   1.891 +	CActiveScheduler::Start();
   1.892 +	
   1.893 +	REComSession::FinalClose();
   1.894 +	
   1.895 +	// Cleanup the server and scheduler
   1.896 +	CleanupStack::PopAndDestroy(2, s);
   1.897 +#ifndef SYMBIAN_USE_CLIENT_HEAP
   1.898 +	if( ! usingSharedHeap )
   1.899 +		{
   1.900 +		__UHEAP_MARKEND;
   1.901 +		}
   1.902 +#endif
   1.903 +	}
   1.904 +
   1.905 +TInt CMMFControllerProxyServer::RunError(TInt aError)
   1.906 +	{
   1.907 +	// Send error to the client
   1.908 +	Message().Complete(aError);
   1.909 +	ReStart();
   1.910 +	return KErrNone;
   1.911 +	}
   1.912 +
   1.913 +CMmfIpcSession* CMMFControllerProxyServer::NewSessionL(const TVersion& aVersion) const
   1.914 +	{
   1.915 +	// Only one session is allowed to connect to us
   1.916 +	if (iHaveSession)
   1.917 +		User::Leave(KErrAlreadyExists);
   1.918 +	// Check that the version number of the client is correct
   1.919 +	if (!User::QueryVersionSupported(KMMFControllerProxyVersion, aVersion))
   1.920 +		User::Leave(KErrNotSupported);
   1.921 +
   1.922 +	return CMMFControllerProxySession::NewL();
   1.923 +	}
   1.924 +
   1.925 +void CMMFControllerProxyServer::SessionCreated()
   1.926 +	{
   1.927 +	iHaveSession = ETrue;
   1.928 +	// Stop the shutdown timer
   1.929 +	iShutdownTimer->Cancel();
   1.930 +	}
   1.931 +
   1.932 +void CMMFControllerProxyServer::SessionDestroyed()
   1.933 +	{
   1.934 +	// Need to shut down
   1.935 +	iShutdownTimer->ShutdownNow();
   1.936 +	}
   1.937 +
   1.938 +CMMFControllerProxyShutdown* CMMFControllerProxyShutdown::NewL() 
   1.939 +	{
   1.940 +	CMMFControllerProxyShutdown* s = new(ELeave) CMMFControllerProxyShutdown();
   1.941 +	CleanupStack::PushL(s);
   1.942 +	s->ConstructL();
   1.943 +	CleanupStack::Pop(s);
   1.944 +	return s;
   1.945 +	}
   1.946 +
   1.947 +CMMFControllerProxyShutdown::CMMFControllerProxyShutdown() : 
   1.948 +	CTimer(EPriorityLow)
   1.949 +	{
   1.950 +	CActiveScheduler::Add(this);
   1.951 +	}
   1.952 +
   1.953 +void CMMFControllerProxyShutdown::ConstructL()
   1.954 +	{
   1.955 +	CTimer::ConstructL();
   1.956 +	}
   1.957 +
   1.958 +void CMMFControllerProxyShutdown::Start()
   1.959 +	{
   1.960 +	After(EMMFControllerProxyShutdownDelay);
   1.961 +	}
   1.962 +
   1.963 +void CMMFControllerProxyShutdown::RunL()
   1.964 +	{
   1.965 +	ShutdownNow();
   1.966 +	}
   1.967 +
   1.968 +void CMMFControllerProxyShutdown::ShutdownNow()
   1.969 +	{
   1.970 +	CActiveScheduler::Stop();
   1.971 +	}
   1.972 +
   1.973 +
   1.974 +
   1.975 +
   1.976 +
   1.977 +
   1.978 +
   1.979 +CMMFEventReceiver* CMMFEventReceiver::NewL(const TMMFMessage& aMessage)
   1.980 +	{
   1.981 +	return new(ELeave) CMMFEventReceiver(aMessage);
   1.982 +	}
   1.983 +
   1.984 +CMMFEventReceiver::~CMMFEventReceiver()
   1.985 +	{
   1.986 +	if (!(iMessage.IsCompleted()))
   1.987 +		iMessage.Complete(KErrDied);
   1.988 +	}
   1.989 +
   1.990 +void CMMFEventReceiver::SendEvent(const TMMFEvent& aEvent)
   1.991 +	{
   1.992 +	TMMFEventPckg eventpckg(aEvent);
   1.993 +	TInt err = iMessage.WriteDataToClient(eventpckg);
   1.994 +	iMessage.Complete(err);
   1.995 +	}
   1.996 +
   1.997 +CMMFEventReceiver::CMMFEventReceiver(const TMMFMessage& aMessage) : iMessage(aMessage)
   1.998 +	{
   1.999 +	}
  1.1000 +
  1.1001 +
  1.1002 +
  1.1003 +// TMMFMessage
  1.1004 +EXPORT_C TMMFMessage::TMMFMessage(const TMMFMessage& aMessage) :
  1.1005 +	iMessage(aMessage.iMessage), 
  1.1006 +#ifdef __MMF_USE_IPC_V2__
  1.1007 +	iFunction(aMessage.iFunction),
  1.1008 +#endif  // __MMF_USE_IPC_V2__
  1.1009 +	iDestination(aMessage.iDestination), 
  1.1010 +	iAmCompleted(aMessage.iAmCompleted)
  1.1011 +	{
  1.1012 +	}
  1.1013 +
  1.1014 +EXPORT_C const TMMFMessageDestination& TMMFMessage::Destination()
  1.1015 +	{
  1.1016 +	return iDestination;
  1.1017 +	}
  1.1018 +
  1.1019 +EXPORT_C TInt TMMFMessage::Function()
  1.1020 +	{
  1.1021 +#ifdef __MMF_USE_IPC_V2__
  1.1022 +	return iFunction;
  1.1023 +#else
  1.1024 +	return iMessage.Function();
  1.1025 +#endif // __MMF_USE_IPC_V2__
  1.1026 +	}
  1.1027 +
  1.1028 +EXPORT_C TInt TMMFMessage::SizeOfData1FromClient()
  1.1029 +	{
  1.1030 +#ifdef __MMF_USE_IPC_V2__
  1.1031 +	return iMessage.GetDesLength(1);
  1.1032 +#else
  1.1033 +	return iMessage.Client().GetDesLength(iMessage.Ptr1());
  1.1034 +#endif // __MMF_USE_IPC_V2__
  1.1035 +	}
  1.1036 +
  1.1037 +EXPORT_C void TMMFMessage::ReadData1FromClientL(TDes8& aDes)
  1.1038 +	{
  1.1039 +#ifdef __MMF_USE_IPC_V2__
  1.1040 +	iMessage.ReadL(1, aDes);
  1.1041 +#else
  1.1042 +	iMessage.ReadL(iMessage.Ptr1(), aDes);
  1.1043 +#endif // __MMF_USE_IPC_V2__
  1.1044 +	}
  1.1045 +
  1.1046 +EXPORT_C TInt TMMFMessage::ReadData1FromClient(TDes8& aDes)
  1.1047 +	{
  1.1048 +	TRAPD(err, ReadData1FromClientL(aDes));
  1.1049 +	return err;
  1.1050 +	}
  1.1051 +
  1.1052 +EXPORT_C TInt TMMFMessage::SizeOfData2FromClient()
  1.1053 +	{
  1.1054 +#ifdef __MMF_USE_IPC_V2__
  1.1055 +	return iMessage.GetDesLength(2);
  1.1056 +#else
  1.1057 +	return iMessage.Client().GetDesLength(iMessage.Ptr2());
  1.1058 +#endif // __MMF_USE_IPC_V2__
  1.1059 +	}
  1.1060 +
  1.1061 +EXPORT_C void TMMFMessage::ReadData2FromClientL(TDes8& aDes)
  1.1062 +	{
  1.1063 +#ifdef __MMF_USE_IPC_V2__
  1.1064 +	iMessage.ReadL(2, aDes);
  1.1065 +#else
  1.1066 +	iMessage.ReadL(iMessage.Ptr2(), aDes);
  1.1067 +#endif // __MMF_USE_IPC_V2__
  1.1068 +	}
  1.1069 +
  1.1070 +EXPORT_C TInt TMMFMessage::ReadData2FromClient(TDes8& aDes)
  1.1071 +	{
  1.1072 +	TRAPD(err, ReadData2FromClientL(aDes));
  1.1073 +	return err;
  1.1074 +	}
  1.1075 +
  1.1076 +EXPORT_C void TMMFMessage::WriteDataToClientL(const TDesC8& aDes)
  1.1077 +	{
  1.1078 +#ifdef __MMF_USE_IPC_V2__
  1.1079 +	iMessage.WriteL(3, aDes);
  1.1080 +#else
  1.1081 +	iMessage.WriteL(iMessage.Ptr3(), aDes);
  1.1082 +#endif // __MMF_USE_IPC_V2__
  1.1083 +	}
  1.1084 +
  1.1085 +EXPORT_C TInt TMMFMessage::WriteDataToClient(const TDesC8& aDes)
  1.1086 +	{
  1.1087 +	TRAPD(err, WriteDataToClientL(aDes));
  1.1088 +	return err;
  1.1089 +	}
  1.1090 +
  1.1091 +EXPORT_C void TMMFMessage::Complete(TInt aReason)
  1.1092 +	{
  1.1093 +	iMessage.Complete(aReason);
  1.1094 +	iAmCompleted = ETrue;
  1.1095 +	}
  1.1096 +
  1.1097 +EXPORT_C TBool TMMFMessage::IsCompleted()
  1.1098 +	{
  1.1099 +	return iAmCompleted;
  1.1100 +	}
  1.1101 +	
  1.1102 +EXPORT_C void TMMFMessage::AdoptFileHandleFromClientL(TInt aFsHandleIndex, TInt aFileHandleIndex, RFile& aFile)
  1.1103 +	{
  1.1104 +	User::LeaveIfError(aFile.AdoptFromClient(RMessage2(iMessage) , aFsHandleIndex, aFileHandleIndex));
  1.1105 +	}
  1.1106 +
  1.1107 +EXPORT_C TMMFMessage::TMMFMessage(const RMmfIpcMessage& aMessage) :
  1.1108 +	iMessage(aMessage), 
  1.1109 +#ifdef __MMF_USE_IPC_V2__
  1.1110 +	iFunction(aMessage.Function()),
  1.1111 +#endif // __MMF_USE_IPC_V2__
  1.1112 +	iAmCompleted(EFalse)
  1.1113 +	{
  1.1114 +	}
  1.1115 +
  1.1116 +EXPORT_C void TMMFMessage::FetchDestinationL()
  1.1117 +	{
  1.1118 +	// Read the destination info from the client
  1.1119 +	TMMFMessageDestinationPckg pckg;
  1.1120 +#ifdef __MMF_USE_IPC_V2__
  1.1121 +	iMessage.ReadL(0, pckg);
  1.1122 +#else
  1.1123 +	iMessage.ReadL(iMessage.Ptr0(), pckg);
  1.1124 +#endif // __MMF_USE_IPC_V2__
  1.1125 +	iDestination = pckg();
  1.1126 +	}
  1.1127 +
  1.1128 +
  1.1129 +// CMMFObject
  1.1130 +
  1.1131 +/**
  1.1132 +Constructor.
  1.1133 +
  1.1134 +@param  aInterfaceId
  1.1135 +        The UID of the interface provided by this object.
  1.1136 +@since 7.0s
  1.1137 +*/
  1.1138 +EXPORT_C CMMFObject::CMMFObject(TUid aInterfaceId)
  1.1139 +	: iHandle(aInterfaceId, KMMFObjectHandleNull)
  1.1140 +	{
  1.1141 +	}
  1.1142 +
  1.1143 +/**
  1.1144 +Destructor.
  1.1145 +*/
  1.1146 +EXPORT_C CMMFObject::~CMMFObject()
  1.1147 +	{
  1.1148 +	}
  1.1149 +
  1.1150 +/**
  1.1151 +Returns the handle of the object.
  1.1152 +
  1.1153 +@return The handle of this object.
  1.1154 +
  1.1155 +@since  7.0s
  1.1156 +*/
  1.1157 +EXPORT_C const TMMFMessageDestination& CMMFObject::Handle()
  1.1158 +	{
  1.1159 +	return iHandle;
  1.1160 +	}
  1.1161 +
  1.1162 +/**
  1.1163 +Compares two CMMFObjects by comparing their handles.
  1.1164 +
  1.1165 +@param  aOther
  1.1166 +        The object to be compared with this object.
  1.1167 +
  1.1168 +@return A boolean indicating if the two CMMFObjects are the same. ETrue if they are the same,
  1.1169 +        EFalse if the objects are different.
  1.1170 +@since  7.0s
  1.1171 +*/
  1.1172 +EXPORT_C TBool CMMFObject::operator==(const CMMFObject& aOther)
  1.1173 +	{
  1.1174 +	return (iHandle==aOther.iHandle);
  1.1175 +	}
  1.1176 +
  1.1177 +void CMMFObject::SetHandle(const TMMFMessageDestination& aNewHandle)
  1.1178 +	{
  1.1179 +	iHandle = aNewHandle;
  1.1180 +	}
  1.1181 +
  1.1182 +
  1.1183 +// CMMFDataSourceHolder
  1.1184 +
  1.1185 +/**
  1.1186 +Constructor.
  1.1187 +
  1.1188 +@param  aDataSource
  1.1189 +        The data source to be wrapped.
  1.1190 +
  1.1191 +@since  7.0s
  1.1192 +*/
  1.1193 +EXPORT_C CMMFDataSourceHolder::CMMFDataSourceHolder(MDataSource& aDataSource)
  1.1194 +	: CMMFObject(KUidInterfaceMMFDataSourceHolder), iDataSource(&aDataSource)
  1.1195 +	{
  1.1196 +	}
  1.1197 +
  1.1198 +/**
  1.1199 +Destructor.
  1.1200 +
  1.1201 +Note: This deletes the data source.
  1.1202 +
  1.1203 +@since 7.0s
  1.1204 +*/
  1.1205 +EXPORT_C CMMFDataSourceHolder::~CMMFDataSourceHolder()
  1.1206 +	{
  1.1207 +	delete iDataSource;
  1.1208 +	}
  1.1209 +
  1.1210 +/**
  1.1211 +Returns a reference to the data source.
  1.1212 +
  1.1213 +@return The data source.
  1.1214 +
  1.1215 +@since  7.0s
  1.1216 +*/
  1.1217 +EXPORT_C MDataSource& CMMFDataSourceHolder::DataSource()
  1.1218 +	{
  1.1219 +	return *iDataSource;
  1.1220 +	}
  1.1221 +
  1.1222 +/**
  1.1223 +Implementation of the pure virtual function inherited from CMMFObject.
  1.1224 +
  1.1225 +Passes the request directly to the data source.
  1.1226 +
  1.1227 +@param  aMessage
  1.1228 +        The message to be handled.
  1.1229 +
  1.1230 +@since  7.0s
  1.1231 +*/
  1.1232 +EXPORT_C void CMMFDataSourceHolder::HandleRequest(TMMFMessage& aMessage)
  1.1233 +	{
  1.1234 +	iDataSource->SourceCustomCommand(aMessage);
  1.1235 +	}
  1.1236 +
  1.1237 +
  1.1238 +// CMMFDataSinkHolder
  1.1239 +
  1.1240 +/**
  1.1241 +Constructor.
  1.1242 +
  1.1243 +@param  aDataSink
  1.1244 +        The data sink to be wrapped.
  1.1245 +@since 7.0s
  1.1246 +*/
  1.1247 +EXPORT_C CMMFDataSinkHolder::CMMFDataSinkHolder(MDataSink& aDataSink)
  1.1248 +	: CMMFObject(KUidInterfaceMMFDataSinkHolder), iDataSink(&aDataSink)
  1.1249 +	{
  1.1250 +	}
  1.1251 +
  1.1252 +/**
  1.1253 +Destructor.
  1.1254 +
  1.1255 +Note: This deletes the data sink.
  1.1256 +
  1.1257 +@since  7.0s
  1.1258 +*/
  1.1259 +EXPORT_C CMMFDataSinkHolder::~CMMFDataSinkHolder()
  1.1260 +	{
  1.1261 +	delete iDataSink;
  1.1262 +	}
  1.1263 +
  1.1264 +/**
  1.1265 +Returns a reference to the data sink.
  1.1266 +
  1.1267 +@return The data sink.
  1.1268 +@since 7.0s
  1.1269 +*/
  1.1270 +EXPORT_C MDataSink& CMMFDataSinkHolder::DataSink()
  1.1271 +	{
  1.1272 +	return *iDataSink;
  1.1273 +	}
  1.1274 +
  1.1275 +/**
  1.1276 +Implementation of the pure virtual function inherited from CMMFObject.
  1.1277 +
  1.1278 +Passes the request directly to the data sink.
  1.1279 +
  1.1280 +@param  aMessage
  1.1281 +        The message to be handled.
  1.1282 +
  1.1283 +@since  7.0s
  1.1284 +*/
  1.1285 +EXPORT_C void CMMFDataSinkHolder::HandleRequest(TMMFMessage& aMessage)
  1.1286 +	{
  1.1287 +	iDataSink->SinkCustomCommand(aMessage);
  1.1288 +	}
  1.1289 +
  1.1290 +
  1.1291 +// CMMFCustomCommandParserBase
  1.1292 +EXPORT_C TUid CMMFCustomCommandParserBase::InterfaceId()
  1.1293 +	{
  1.1294 +	return iInterfaceId;
  1.1295 +	}
  1.1296 +
  1.1297 +EXPORT_C CMMFCustomCommandParserBase::~CMMFCustomCommandParserBase()
  1.1298 +	{
  1.1299 +	}
  1.1300 +
  1.1301 +EXPORT_C CMMFCustomCommandParserBase::CMMFCustomCommandParserBase(TUid aInterfaceId)
  1.1302 +	: iInterfaceId(aInterfaceId)
  1.1303 +	{
  1.1304 +	}
  1.1305 +
  1.1306 +
  1.1307 +// CMMFObjectContainer
  1.1308 +
  1.1309 +/**
  1.1310 +Constructor.
  1.1311 +
  1.1312 +@since  7.0s
  1.1313 +*/
  1.1314 +EXPORT_C CMMFObjectContainer::CMMFObjectContainer()
  1.1315 +	{
  1.1316 +	iNextObjectHandle = KMMFObjectHandleFirstValid;
  1.1317 +	}
  1.1318 +
  1.1319 +/**
  1.1320 +Destructor.
  1.1321 +
  1.1322 +Deletes all objects owned by the container.
  1.1323 +
  1.1324 +@since  7.0s
  1.1325 +*/
  1.1326 +EXPORT_C CMMFObjectContainer::~CMMFObjectContainer()
  1.1327 +	{
  1.1328 +	iObjects.ResetAndDestroy();
  1.1329 +	iObjects.Close();
  1.1330 +	}
  1.1331 +
  1.1332 +/**
  1.1333 +Add an object to the container.
  1.1334 +
  1.1335 +Once the object has been added, its ownership is transferred to the container.
  1.1336 +
  1.1337 +@param  aObject
  1.1338 +        A reference to the object to be added to the container.
  1.1339 +
  1.1340 +@return	An error code indicating if the function call was successful. If the return code is not KErrNone, then
  1.1341 +		ownership of the object still remains with the caller.
  1.1342 +@since  7.0s
  1.1343 +*/
  1.1344 +EXPORT_C TInt CMMFObjectContainer::AddMMFObject(CMMFObject& aObject)
  1.1345 +	{
  1.1346 +	// Check the object isn't already added
  1.1347 +	if (aObject.Handle().DestinationHandle() != KMMFObjectHandleNull)
  1.1348 +		return KErrAlreadyExists;
  1.1349 +
  1.1350 +	TMMFMessageDestination newHandle(aObject.Handle().InterfaceId(), GenerateObjectHandle());
  1.1351 +	// Set the object's handle
  1.1352 +	aObject.SetHandle(newHandle);
  1.1353 +	// Append the object to the array
  1.1354 +	TInt error = iObjects.Append(&aObject);
  1.1355 +	// If error occurred, reset object handle to NULL
  1.1356 +	if (error)
  1.1357 +		{
  1.1358 +		TMMFMessageDestination evenNewerHandle(aObject.Handle().InterfaceId(), KMMFObjectHandleNull);
  1.1359 +		aObject.SetHandle(evenNewerHandle);
  1.1360 +		}
  1.1361 +	return error;
  1.1362 +	}
  1.1363 +
  1.1364 +/**
  1.1365 +Removes and destroys an object from the container.
  1.1366 +
  1.1367 +This method ensures that the object is no longer in the container, and that it gets deleted.
  1.1368 +Even if the object is not found in the container's array of objects, it will be deleted.
  1.1369 +
  1.1370 +@param  aObject
  1.1371 +        A reference to the object to be deleted.
  1.1372 +
  1.1373 +@since  7.0s
  1.1374 +*/
  1.1375 +EXPORT_C void CMMFObjectContainer::RemoveAndDestroyMMFObject(CMMFObject& aObject)
  1.1376 +	{
  1.1377 +	TInt positionOfObjectInArray;
  1.1378 +	TInt error = FindMMFObject(aObject, positionOfObjectInArray);
  1.1379 +	if (!error)
  1.1380 +		{
  1.1381 +		iObjects.Remove(positionOfObjectInArray);
  1.1382 +		}
  1.1383 +	//else, we don't care since we're just saying we'll make sure the object
  1.1384 +	//isn't in the array, and that it gets deleted.
  1.1385 +	delete (&aObject);
  1.1386 +	}
  1.1387 +
  1.1388 +/**
  1.1389 +Removes and destroys all objects from the container.
  1.1390 +
  1.1391 +@since	7.0s
  1.1392 +*/
  1.1393 +EXPORT_C void CMMFObjectContainer::DeleteAllObjects()
  1.1394 +	{
  1.1395 +	iObjects.ResetAndDestroy();
  1.1396 +	}
  1.1397 +
  1.1398 +/**
  1.1399 +Finds an object in the container using a handle.
  1.1400 +
  1.1401 +@param  aObjectHandle
  1.1402 +        The handle of the object to be located.
  1.1403 +@param  aObjectFound
  1.1404 +        A reference to a pointer to the object found in the container.
  1.1405 +
  1.1406 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
  1.1407 +        another of the system-wide error codes.
  1.1408 +@since	7.0s
  1.1409 +*/
  1.1410 +EXPORT_C TInt CMMFObjectContainer::FindMMFObject(const TMMFMessageDestination& aObjectHandle, CMMFObject*& aObjectFound)
  1.1411 +	{
  1.1412 +	// Need to find the appropriate object in the array of CMMFObjects
  1.1413 +	TInt error = KErrNotFound;
  1.1414 +	for (TInt i=0; i<iObjects.Count(); i++)
  1.1415 +		{
  1.1416 +		CMMFObject* obj = iObjects[i];
  1.1417 +		if (obj->Handle() == aObjectHandle)
  1.1418 +			{
  1.1419 +			error = KErrNone;
  1.1420 +			aObjectFound = obj;
  1.1421 +			break;
  1.1422 +			}
  1.1423 +		}
  1.1424 +	return error;
  1.1425 +	}
  1.1426 +
  1.1427 +const RPointerArray<CMMFObject>& CMMFObjectContainer::MMFObjects()
  1.1428 +	{
  1.1429 +	return iObjects;
  1.1430 +	}
  1.1431 +	
  1.1432 +TInt CMMFObjectContainer::FindMMFObject(const CMMFObject& aObject, TInt& aPositionInArray)
  1.1433 +	{
  1.1434 +	TInt error = KErrNotFound;
  1.1435 +	for (TInt i=0; i<iObjects.Count(); i++)
  1.1436 +		{
  1.1437 +		CMMFObject* obj = iObjects[i];
  1.1438 +		if (*obj == aObject)
  1.1439 +			{
  1.1440 +			error = KErrNone;
  1.1441 +			aPositionInArray = i;
  1.1442 +			break;
  1.1443 +			}
  1.1444 +		}
  1.1445 +	return error;
  1.1446 +	}
  1.1447 +
  1.1448 +TInt CMMFObjectContainer::GenerateObjectHandle()
  1.1449 +	{
  1.1450 +	return iNextObjectHandle++;
  1.1451 +	}
  1.1452 +
  1.1453 +
  1.1454 +CLogonMonitor::CLogonMonitor(MLogonMonitorObserver* aLogonMonitorObserver) 
  1.1455 +: CActive(EPriorityStandard)
  1.1456 +	{
  1.1457 +	iLogonMonitorObserver = aLogonMonitorObserver;
  1.1458 +	}
  1.1459 +	
  1.1460 +void CLogonMonitor::ConstructL()
  1.1461 +	{
  1.1462 +	if (CActiveScheduler::Current()==0)
  1.1463 +		{
  1.1464 +		iScheduler = new (ELeave) CActiveScheduler;
  1.1465 +		CActiveScheduler::Install(iScheduler);
  1.1466 +		}
  1.1467 +		
  1.1468 +	CActiveScheduler::Add(this);
  1.1469 +	}
  1.1470 +	
  1.1471 +CLogonMonitor* CLogonMonitor::NewL(MLogonMonitorObserver* aLogonMonitorObserver)
  1.1472 +	{
  1.1473 +	CLogonMonitor* self = new (ELeave) CLogonMonitor(aLogonMonitorObserver);
  1.1474 +	CleanupStack::PushL(self);
  1.1475 +	self->ConstructL();
  1.1476 +	CleanupStack::Pop(self);
  1.1477 +	return self;
  1.1478 +	}
  1.1479 +
  1.1480 +CLogonMonitor::~CLogonMonitor()
  1.1481 +	{
  1.1482 +	Cancel();
  1.1483 +	
  1.1484 +	if (iScheduler)
  1.1485 +		{
  1.1486 +		CActiveScheduler::Install(NULL);
  1.1487 +		delete iScheduler;
  1.1488 +		}
  1.1489 +	}
  1.1490 +
  1.1491 +void CLogonMonitor::StartMonitoring(RThread& aThread)
  1.1492 +	{
  1.1493 +	ASSERT(!iThread);
  1.1494 +	
  1.1495 +	iThread = &aThread;
  1.1496 +	iThread->Logon(iStatus);
  1.1497 +	SetActive();
  1.1498 +	}
  1.1499 +
  1.1500 +void CLogonMonitor::RunL()
  1.1501 +	{
  1.1502 +	iServer.Close();
  1.1503 +	iLogonMonitorObserver->ThreadTerminated();
  1.1504 +	}
  1.1505 +
  1.1506 +void CLogonMonitor::DoCancel()
  1.1507 +	{
  1.1508 +	ASSERT(iThread);
  1.1509 +	
  1.1510 +	iThread->LogonCancel(iStatus);
  1.1511 +	iThread = NULL;
  1.1512 +	}
  1.1513 +
  1.1514 +RServer2& CLogonMonitor::Server()
  1.1515 +	{
  1.1516 +	return iServer;
  1.1517 +	}
  1.1518 +	
  1.1519 +CMMFControllerExtendedData::CMMFControllerExtendedData()
  1.1520 +	: CMMFObject(KUidMMFControllerExtendedDataHolder), iSourceSinkInitData(NULL)
  1.1521 +	{
  1.1522 +	iClientThreadId = 0;
  1.1523 +	iSecureDrmMode = EFalse;
  1.1524 +	}
  1.1525 +
  1.1526 +CMMFControllerExtendedData::~CMMFControllerExtendedData()
  1.1527 +	{
  1.1528 +	ResetSourceSinkInitData();
  1.1529 +	}
  1.1530 +	
  1.1531 +void CMMFControllerExtendedData::SetSourceSinkInitData(HBufC8* aSourceSinkInitData)
  1.1532 +	{
  1.1533 +	ResetSourceSinkInitData();
  1.1534 +	iSourceSinkInitData = aSourceSinkInitData;
  1.1535 +	}
  1.1536 +
  1.1537 +HBufC8* CMMFControllerExtendedData::SourceSinkInitData() const
  1.1538 +	{
  1.1539 +	return iSourceSinkInitData;
  1.1540 +	}
  1.1541 +
  1.1542 +void CMMFControllerExtendedData::ResetSourceSinkInitData()
  1.1543 +	{
  1.1544 +	if (iSourceSinkInitData)
  1.1545 +		{
  1.1546 +		delete iSourceSinkInitData;
  1.1547 +		iSourceSinkInitData = NULL;
  1.1548 +		}
  1.1549 +	}
  1.1550 +
  1.1551 +void CMMFControllerExtendedData::SetClientThreadId(TThreadId aClientThreadId)
  1.1552 +	{
  1.1553 +	iClientThreadId = aClientThreadId;
  1.1554 +	}
  1.1555 +
  1.1556 +TThreadId CMMFControllerExtendedData::ClientThreadId() const
  1.1557 +	{
  1.1558 +	return iClientThreadId;
  1.1559 +	}
  1.1560 +
  1.1561 +void CMMFControllerExtendedData::SetSecureDrmMode(TBool aSecureDrmMode)
  1.1562 +	{
  1.1563 +	iSecureDrmMode = aSecureDrmMode;
  1.1564 +	}
  1.1565 +
  1.1566 +TBool CMMFControllerExtendedData::SecureDrmMode() const
  1.1567 +	{
  1.1568 +	return iSecureDrmMode;
  1.1569 +	}
  1.1570 +
  1.1571 +void CMMFControllerExtendedData::HandleRequest(TMMFMessage& /*aMessage*/)
  1.1572 +	{
  1.1573 +	// This function is not suppose to be called.
  1.1574 +#ifdef _DEBUG
  1.1575 +	Panic(EPanicBadInvariant);
  1.1576 +#endif
  1.1577 +	}
  1.1578 +