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, ¶ms, 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 + ¶ms, 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, ¶ms);
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 +