First public contribution.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include <mmf/server/mmfdrmpluginserverproxy.h>
18 #include "mmfcontrollerframework.h"
19 #include "mmfcontroller.h"
20 #include "mmfcontrollerheap.h"
21 #include "mmfcontrollerframeworkpriv.h"
22 #include "mmfcontrollerpatchdata.h"
24 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
25 #include <mmf/common/mmfcontrollerextendeddata.h>
26 #include <mmf/common/mmfcustomcommandparsermanager.h>
27 #include <mmf/common/mmfcontrollerframeworkclasses.h>
35 EPanicHeapOpenWithoutTls,
36 EPanicReleaseWithoutRegister,
41 static void Panic(TInt aReason)
43 _LIT(KControllerFramework, "ControllerFramework");
44 User::Panic(KControllerFramework, aReason);
48 EXPORT_C RMMFControllerProxy::RMMFControllerProxy() :
49 iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFControllerProxy, KMMFObjectHandleControllerProxy)),
50 iLogonAO(NULL), iThreadPriority(static_cast<TThreadPriority>(KDefaultMMFControllerThreadPriority)), iFlags(0)
52 iSubThread.Close();//iSubThread is automatically initialised to be a handle to this thread!
55 TInt RMMFControllerProxy::LoadController(
57 const CMMFControllerImplementationInformation& aControllerInfo,
61 // First check that we haven't already created the subthread
62 if (iSubThread.Handle() != 0)
63 return KErrAlreadyExists;
65 #ifdef SYMBIAN_FORCE_USE_SHARED_HEAP
66 aUseSharedHeap = ETrue;
69 //determine what maximum heap size this thread should be created with
71 TInt error = KErrNone;
72 maxHeapSize = aControllerInfo.HeapSpaceRequired();
73 TUint stackSize = aControllerInfo.StackSize();
76 TRAP(error, iLogonAO = CLogonMonitor::NewL(this));
80 if (aNoDRMCap && aControllerInfo.SupportsSecureDRMProcessMode())
82 error = DoCreateSessionForNoDRMCapClient(maxHeapSize, aUseSharedHeap, stackSize);
86 // server2 will be set in this function call
87 error = DoCreateSubThread(&iLogonAO->Server(), maxHeapSize, aUseSharedHeap, stackSize);
89 // Now create a session with the controller proxy server running in the subthread
92 // create a session with iServer2 (local server)
93 error = CreateSession(iLogonAO->Server(), KMMFControllerProxyVersion);
98 // Finally, tell the controller proxy server to load the relevant plugin
101 TMMFUidPckg uidPckg(aControllerUid);
102 error = SendSync(iDestinationPckg,
103 EMMFControllerProxyLoadControllerPluginByUid,
108 // If an error occurred with any of the above, close all the handles
116 EXPORT_C TInt RMMFControllerProxy::LoadController(TUid aControllerUid, TBool aUseSharedHeap)
118 CMMFControllerImplementationInformation* controllerInfo = NULL;
120 TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
121 if (!err && controllerInfo)
123 err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, EFalse);
124 delete controllerInfo;
129 EXPORT_C TInt RMMFControllerProxy::LoadController(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
131 return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, EFalse);
134 EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(TUid aControllerUid, TBool aUseSharedHeap)
136 CMMFControllerImplementationInformation* controllerInfo = NULL;
138 TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
139 if (!err && controllerInfo)
141 err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, ETrue);
142 delete controllerInfo;
147 EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap)
149 return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, ETrue);
152 TUint RMMFControllerProxy::ControllersMaxHeapSizeL(TUid aControllerUid)
154 CMMFControllerImplementationInformation* controllerInfo = NULL;
156 TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid));
159 TUint maxHeapSize = KMMFDefaultControllerThreadHeapSize;
161 if((err != KErrNone) && (err != KErrCorrupt))
163 delete controllerInfo;
168 if(controllerInfo && (err == KErrNone))
169 maxHeapSize = controllerInfo->HeapSpaceRequired();
171 delete controllerInfo;
177 TInt RMMFControllerProxy::DoCreateSubThread(RServer2* aServer2, TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
179 TInt error = KErrNone;
181 TControllerProxyServerParams params;
182 params.iServer = aServer2;
183 params.iUsingSharedHeap = aUseSharedHeap;
185 #ifdef SYMBIAN_USE_CLIENT_HEAP
186 // controller threads share the *client* heap (intended for out of memory testing)
187 error = iSubThread.Create(_L(""), &CMMFControllerProxyServer::StartThread,
188 aStackSize, NULL, ¶ms, EOwnerThread);
192 //controller threads all share a controller heap
193 CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
196 TRAP(error, contHeap = CMMFControllerHeap::NewL());
202 Dll::SetTls(contHeap);
205 __ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap)==0, Panic(EPanicHeapHalfOpen));
207 RHeap* sharedHeap = contHeap->RegisterHeap();
208 // We've registered, so record the fact so can "unregister" on close or error
209 iFlags |= EFlagOpenedSharedHeap;
211 error = iSubThread.Create(KNullDesC, &CMMFControllerProxyServer::StartThread,
212 aStackSize, sharedHeap,
213 ¶ms, EOwnerThread);
217 // Threads create own heap (default behaviour)
218 if(aMaxHeapSize < static_cast<TUint>(KMinHeapSize))
219 aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic
220 else if(aMaxHeapSize > static_cast<TUint>(KMMFControllerProxyMaxHeapSize))
221 aMaxHeapSize = KMMFControllerProxyMaxHeapSize;
223 TThreadCreateInfo threadSettings (KNullDesC, &CMMFControllerProxyServer::StartThread,
224 aStackSize, ¶ms);
225 threadSettings.SetCreateHeap(KMinHeapSize, aMaxHeapSize);
226 threadSettings.SetOwner(EOwnerThread);
227 threadSettings.SetPaging(TThreadCreateInfo::EUnpaged);
229 error = iSubThread.Create(threadSettings);
238 TRequestStatus rendezvous;
239 iSubThread.Rendezvous(rendezvous);
240 if (rendezvous != KRequestPending)
246 iLogonAO->StartMonitoring(iSubThread);
247 if (iLogonAO->iStatus != KRequestPending)
250 iSubThread.RendezvousCancel(rendezvous);
251 User::WaitForRequest(rendezvous);
254 return iLogonAO->iStatus.Int();
258 iSubThread.SetPriority(iThreadPriority);
263 User::WaitForRequest(rendezvous); // wait for startup or death
265 if (rendezvous != KErrNone)
269 // if open failed, but we registered the heap, need to release
270 if((iFlags&EFlagOpenedSharedHeap))
276 return rendezvous.Int();
279 EXPORT_C void RMMFControllerProxy::Close()
282 _LIT(KMMFClientThreadPanic, "MMFClientThread");
284 // check if thread was created
285 TBool subThreadCreated = EFalse;
286 TRequestStatus logoffStatus;
287 TBool logoffFailed = EFalse;
288 if (iSubThread.Handle() != KNullHandle)
290 subThreadCreated = ETrue;
292 iSubThread.Logon(logoffStatus);
294 if (logoffStatus == KErrNoMemory && iSubThread.ExitType() == EExitPending)
296 // Logon() call has failed because of a lack of memory
297 logoffFailed = ETrue;
301 // Close the controller and wait for its exit.
302 // Close the session to signal the controller proxy server to shut down.
303 RHandleBase::Close();
305 // Now wait for the death of the subthread if we have a valid handle...
306 if (subThreadCreated)
308 RProcess thisProcess;
309 RProcess controllerProcess;
310 iSubThread.Process(controllerProcess); // ignore error, best try
311 TBool secureDrmMode = thisProcess.Id() != controllerProcess.Id();
313 controllerProcess.Close();
316 TInt err = timer.CreateLocal();
317 // If we managed to create the timer and logon to the thread,
318 // wait for both the death and the timeout to minimise the risk of deadlock
319 if (!err && !logoffFailed)
321 TRequestStatus timeout;
322 timer.After(timeout, KMmfControllerThreadShutdownTimeout);
323 User::WaitForRequest(logoffStatus, timeout);
324 if (logoffStatus == KRequestPending)
326 // we have timed out. Kill the controller thread
327 iSubThread.LogonCancel(logoffStatus);
328 User::WaitForRequest(logoffStatus);
332 // Controller server thread is created in current process
334 iSubThread.Panic(KMMFClientThreadPanic,KErrDied);
336 iSubThread.Kill(KErrDied);
341 // Controller server thread is created through DRM plugin server
342 RMMFDRMPluginServerProxy server;
343 // ignore all RMMFDRMPluginServerProxy errors, best try
348 server.PanicControllerThread(iSubThread.Id(), KMMFClientThreadPanic, KErrDied);
350 server.KillControllerThread(iSubThread.Id(), KErrDied);
358 // subthread has exited. Cancel the timer.
360 User::WaitForRequest(timeout);
365 // We have no timer or we can't logon to the thread so we'll just poll the thread status a maximum
366 // of 10 times and kill the thread if it hasn't exited after the polling
367 for (TInt i=0; i<10 && iSubThread.ExitType() == EExitPending; ++i)
369 User::After(KMmfControllerThreadShutdownTimeout/10); // wait for a while
372 if (iSubThread.ExitType() == EExitPending)
374 // The polling hasn't been succesful so we kill the thread
377 iSubThread.Kill(KErrDied);
381 // Controller server thread is created through DRM plugin server
382 RMMFDRMPluginServerProxy server;
383 // ignore all RMMFDRMPluginServerProxy errors, best try
387 server.KillControllerThread(iSubThread.Id(), KErrDied);
392 User::WaitForRequest(logoffStatus);
397 // Close the handle to the controller thread
399 // Delete the Logon AO
405 // if this is last thread to be killed delete shared heap
406 if((iFlags&EFlagOpenedSharedHeap))
412 // Release the shared heap, should only be called if has previously been registered
414 void RMMFControllerProxy::ReleaseHeap()
416 __ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap), Panic(EPanicReleaseWithoutRegister));
418 CMMFControllerHeap* contHeap = static_cast<CMMFControllerHeap*>(Dll::Tls());
419 __ASSERT_DEBUG(contHeap!=NULL, Panic(EPanicHeapOpenWithoutTls));
423 TInt refCount = contHeap->ReleaseHeap();
425 { //no other controllers using the heap
431 iFlags &= ~EFlagOpenedSharedHeap; // clear flag since we've released the heap
434 EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) const
436 // Make sure we have been opened
437 if (iSubThread.Handle() == 0)
442 return SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom);
446 EXPORT_C TInt RMMFControllerProxy::SendSync(TInt aFunction, const TIpcArgs& aIpcArgs) const
448 // Make sure we have been opened
449 if (iSubThread.Handle() == 0)
454 return RSessionBase::SendReceive(aFunction, aIpcArgs);
457 EXPORT_C void RMMFControllerProxy::SendAsync(TInt aFunction, const TIpcArgs& aIpcArgs, TRequestStatus& aStatus) const
459 // Make sure we have been opened
460 if (iSubThread.Handle() == 0)
462 TRequestStatus* status = &aStatus;
463 User::RequestComplete(status, KErrNotReady);
466 RSessionBase::SendReceive(aFunction, aIpcArgs, aStatus);
471 EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) const
473 // Make sure we have been opened
474 if (iSubThread.Handle() == 0)
479 return SendReceive(aFunction, aDestination, aDataTo1, aDataTo2);
482 EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) const
484 if (iSubThread.Handle() == 0)
486 TRequestStatus* stat = &aStatus;
487 User::RequestComplete(stat, KErrNotReady);
490 SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom, aStatus);
493 EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) const
495 if (iSubThread.Handle() == 0)
497 TRequestStatus* stat = &aStatus;
498 User::RequestComplete(stat, KErrNotReady);
501 SendReceive(aFunction, aDestination, aDataTo1, aDataTo2, aStatus);
504 EXPORT_C void RMMFControllerProxy::ReceiveEvents(TMMFEventPckg& aEvent, TRequestStatus& aStatus)
506 SendAsync(iDestinationPckg, EMMFControllerProxyReceiveEvents, KNullDesC8, KNullDesC8, aEvent, aStatus);
509 EXPORT_C TInt RMMFControllerProxy::CancelReceiveEvents()
511 return SendSync(iDestinationPckg, EMMFControllerProxyCancelReceiveEvents, KNullDesC8, KNullDesC8);
514 EXPORT_C TInt RMMFControllerProxy::SetThreadPriority(const TThreadPriority& aPriority) const
518 if (iSubThread.Handle() == 0)
524 if (iThreadPriority != aPriority)
526 // This is a const method so cast it away to store the priority
527 RMMFControllerProxy* nonConstThis = const_cast<RMMFControllerProxy*>(this);
528 nonConstThis->iThreadPriority = aPriority;
531 // check controller thread creation location
532 RProcess thisProcess;
533 RProcess controllerProcess;
534 err = iSubThread.Process(controllerProcess);
538 if (thisProcess.Id() == controllerProcess.Id())
540 // Controller server thread is created in current process
541 if (iSubThread.Priority() != iThreadPriority)
543 iSubThread.Suspend();
544 iSubThread.SetPriority(iThreadPriority);
550 // Controller server thread is created through DRM plugin server
551 RMMFDRMPluginServerProxy server;
555 err = server.SetThreadPriority(iSubThread.Id(), iThreadPriority);
561 controllerProcess.Close();
566 void RMMFControllerProxy::ThreadTerminated()
568 // The controller subthread has died and the controller should be closed
572 TInt RMMFControllerProxy::DoCreateSessionForNoDRMCapClient(TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize)
575 RMMFDRMPluginServerProxy server;
576 TInt error = server.Open();
580 error = server.LaunchControllerServer(aMaxHeapSize, aUseSharedHeap, tid, aStackSize);
584 error = iSubThread.Open(tid, EOwnerThread);
587 iLogonAO->StartMonitoring(iSubThread);
588 if (iLogonAO->iStatus != KRequestPending)
591 server.KillControllerThread(tid, 0);
593 error = iLogonAO->iStatus.Int();
598 // Failed to open thread handle
599 server.KillControllerThread(tid, 0);
604 error = server.SetThreadPriority(tid, iThreadPriority);
607 error = SetReturnedHandle(server.GetControllerSessionHandle());
611 // Failed to create session with controller
613 server.KillControllerThread(tid, 0);
622 // RMMFCustomCommandsBase
628 A reference to the controller client class that will be used to send
629 custom commands to the controller plugin.
631 The UID of the custom command interface that is provided by this client
636 EXPORT_C RMMFCustomCommandsBase::RMMFCustomCommandsBase(RMMFController& aController, TUid aInterfaceId)
637 : iController(aController), iDestinationPckg(aInterfaceId)
642 // TMMFMessageDestination
643 EXPORT_C TMMFMessageDestination::TMMFMessageDestination()
644 : iInterfaceId(KNullUid), iDestinationHandle(KMMFObjectHandleController)
648 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId)
649 : iInterfaceId(aInterfaceId), iDestinationHandle(KMMFObjectHandleController)
653 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId, TInt aDestinationHandle)
654 : iInterfaceId(aInterfaceId), iDestinationHandle(aDestinationHandle)
658 EXPORT_C TMMFMessageDestination::TMMFMessageDestination(const TMMFMessageDestination& aOther)
659 : iInterfaceId(aOther.iInterfaceId), iDestinationHandle(aOther.iDestinationHandle)
663 EXPORT_C TUid TMMFMessageDestination::InterfaceId() const
668 EXPORT_C TInt TMMFMessageDestination::DestinationHandle() const
670 return iDestinationHandle;
673 EXPORT_C TBool TMMFMessageDestination::operator==(const TMMFMessageDestination& aOther) const
675 return ((iInterfaceId==aOther.iInterfaceId) && (iDestinationHandle==aOther.iDestinationHandle));
680 // CMMFControllerProxySession
681 CMMFControllerProxySession* CMMFControllerProxySession::NewL()
683 CMMFControllerProxySession* s = new(ELeave) CMMFControllerProxySession;
687 void CMMFControllerProxySession::CreateL(const CMmfIpcServer& aServer)
689 CMmfIpcSession::CreateL(aServer);
690 iServer = STATIC_CAST(CMMFControllerProxyServer*, (CONST_CAST(CMmfIpcServer*, &aServer)));
691 iServer->SessionCreated();
694 CMMFControllerProxySession::~CMMFControllerProxySession()
697 delete iEventReceiver;
699 iServer->SessionDestroyed();
704 void CMMFControllerProxySession::ServiceL(const RMmfIpcMessage& aMessage)
706 TMMFMessage message(aMessage);
707 // Get the destination info from the client.
708 message.FetchDestinationL();
710 if (message.Destination().InterfaceId() == KUidInterfaceMMFControllerProxy)
712 // Message for controller proxy so decode here
713 TBool complete = EFalse;
714 switch (message.Function())
716 case EMMFControllerProxyReceiveEvents:
717 complete = ReceiveEventsL(message);
719 case EMMFControllerProxyCancelReceiveEvents:
720 complete = CancelReceiveEvents(message);
722 case EMMFControllerProxyLoadControllerPluginByUid:
723 complete = LoadControllerL(message);
726 User::Leave(KErrNotSupported);
729 message.Complete(KErrNone);
733 // Message for controller so forward on to controller baseclass
735 iController->HandleRequestL(message);
737 User::Leave(KErrNotReady);
741 CMMFControllerProxySession::CMMFControllerProxySession()
745 TBool CMMFControllerProxySession::ReceiveEventsL(TMMFMessage& aMessage)
748 User::Leave(KErrAlreadyExists);
749 iEventReceiver = CMMFEventReceiver::NewL(aMessage);
750 //send the next cached event (if any) to the client
751 if (iEvents.Count() > 0)
753 TMMFEvent& event = iEvents[0];
754 iEventReceiver->SendEvent(event);
755 delete iEventReceiver;
762 TBool CMMFControllerProxySession::CancelReceiveEvents(TMMFMessage& /*aMessage*/)
764 delete iEventReceiver;
765 iEventReceiver = NULL;
769 TInt CMMFControllerProxySession::SendEventToClient(const TMMFEvent& aEvent)
771 TInt error = KErrNone;
774 //send event to client now
775 iEventReceiver->SendEvent(aEvent);
776 delete iEventReceiver;
782 //queue the request for later
783 TMMFEvent event(aEvent);
784 //if we've exceeded the max number of cached messages, delete the first and append this one to the end
785 if (iEvents.Count() >= KMMFControllerProxyMaxCachedMessages)
787 error = iEvents.Append(event);
792 TBool CMMFControllerProxySession::LoadControllerL(TMMFMessage& aMessage)
795 aMessage.ReadData1FromClientL(pckg);
797 RThread clientThread;
798 aMessage.iMessage.ClientL(clientThread);
799 CleanupClosePushL(clientThread);
800 iController = CMMFController::NewL(pckg(), *this, clientThread.Id());
801 CleanupStack::PopAndDestroy(&clientThread);
807 CMMFControllerProxyServer* CMMFControllerProxyServer::NewL(RServer2* aServer2)
809 CMMFControllerProxyServer* s = new(ELeave) CMMFControllerProxyServer();
810 CleanupStack::PushL(s);
811 s->ConstructL(aServer2);
812 CleanupStack::Pop(s);
816 CMMFControllerProxyServer::CMMFControllerProxyServer() :
817 CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions)
821 void CMMFControllerProxyServer::ConstructL(RServer2* aServer2)
823 SetPinClientDescriptors(ETrue);
826 *aServer2 = CServer2::Server();
828 iShutdownTimer = CMMFControllerProxyShutdown::NewL();
829 iShutdownTimer->Start();
832 CMMFControllerProxyServer::~CMMFControllerProxyServer()
834 delete iShutdownTimer;
837 EXPORT_C TInt CMMFControllerProxyServer::StartThread(TAny* aParam)
840 //create cleanupstack
841 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
846 TRAP(err, DoStartThreadL(aParam));
852 void CMMFControllerProxyServer::RenameControllerProxyThread()
857 name.Append(KMMFControllerProxyServerName);
858 threadId = thread.Id();
859 name.AppendNum(threadId.Id(),EHex);
860 User::RenameThread(name);
863 void CMMFControllerProxyServer::DoStartThreadL(TAny* aParam)
865 TControllerProxyServerParams* params = static_cast<TControllerProxyServerParams*>(aParam);
867 //Rename Current thread to unique name
868 RenameControllerProxyThread();
870 #ifndef SYMBIAN_USE_CLIENT_HEAP
871 TBool usingSharedHeap = params->iUsingSharedHeap; // take copy since params invalid after Rendezvous
873 if( ! usingSharedHeap )
879 // create and install the active scheduler we need
880 CActiveScheduler* s=new(ELeave) CActiveScheduler;
881 CleanupStack::PushL(s);
882 CActiveScheduler::Install(s);
883 // create the server (leave it on the cleanup stack)
884 CleanupStack::PushL(CMMFControllerProxyServer::NewL( params->iServer ) );
885 // Initialisation complete, now signal the client
886 RThread::Rendezvous(KErrNone);
888 CActiveScheduler::Start();
890 REComSession::FinalClose();
892 // Cleanup the server and scheduler
893 CleanupStack::PopAndDestroy(2, s);
894 #ifndef SYMBIAN_USE_CLIENT_HEAP
895 if( ! usingSharedHeap )
902 TInt CMMFControllerProxyServer::RunError(TInt aError)
904 // Send error to the client
905 Message().Complete(aError);
910 CMmfIpcSession* CMMFControllerProxyServer::NewSessionL(const TVersion& aVersion) const
912 // Only one session is allowed to connect to us
914 User::Leave(KErrAlreadyExists);
915 // Check that the version number of the client is correct
916 if (!User::QueryVersionSupported(KMMFControllerProxyVersion, aVersion))
917 User::Leave(KErrNotSupported);
919 return CMMFControllerProxySession::NewL();
922 void CMMFControllerProxyServer::SessionCreated()
924 iHaveSession = ETrue;
925 // Stop the shutdown timer
926 iShutdownTimer->Cancel();
929 void CMMFControllerProxyServer::SessionDestroyed()
932 iShutdownTimer->ShutdownNow();
935 CMMFControllerProxyShutdown* CMMFControllerProxyShutdown::NewL()
937 CMMFControllerProxyShutdown* s = new(ELeave) CMMFControllerProxyShutdown();
938 CleanupStack::PushL(s);
940 CleanupStack::Pop(s);
944 CMMFControllerProxyShutdown::CMMFControllerProxyShutdown() :
947 CActiveScheduler::Add(this);
950 void CMMFControllerProxyShutdown::ConstructL()
952 CTimer::ConstructL();
955 void CMMFControllerProxyShutdown::Start()
957 After(EMMFControllerProxyShutdownDelay);
960 void CMMFControllerProxyShutdown::RunL()
965 void CMMFControllerProxyShutdown::ShutdownNow()
967 CActiveScheduler::Stop();
976 CMMFEventReceiver* CMMFEventReceiver::NewL(const TMMFMessage& aMessage)
978 return new(ELeave) CMMFEventReceiver(aMessage);
981 CMMFEventReceiver::~CMMFEventReceiver()
983 if (!(iMessage.IsCompleted()))
984 iMessage.Complete(KErrDied);
987 void CMMFEventReceiver::SendEvent(const TMMFEvent& aEvent)
989 TMMFEventPckg eventpckg(aEvent);
990 TInt err = iMessage.WriteDataToClient(eventpckg);
991 iMessage.Complete(err);
994 CMMFEventReceiver::CMMFEventReceiver(const TMMFMessage& aMessage) : iMessage(aMessage)
1001 EXPORT_C TMMFMessage::TMMFMessage(const TMMFMessage& aMessage) :
1002 iMessage(aMessage.iMessage),
1003 #ifdef __MMF_USE_IPC_V2__
1004 iFunction(aMessage.iFunction),
1005 #endif // __MMF_USE_IPC_V2__
1006 iDestination(aMessage.iDestination),
1007 iAmCompleted(aMessage.iAmCompleted)
1011 EXPORT_C const TMMFMessageDestination& TMMFMessage::Destination()
1013 return iDestination;
1016 EXPORT_C TInt TMMFMessage::Function()
1018 #ifdef __MMF_USE_IPC_V2__
1021 return iMessage.Function();
1022 #endif // __MMF_USE_IPC_V2__
1025 EXPORT_C TInt TMMFMessage::SizeOfData1FromClient()
1027 #ifdef __MMF_USE_IPC_V2__
1028 return iMessage.GetDesLength(1);
1030 return iMessage.Client().GetDesLength(iMessage.Ptr1());
1031 #endif // __MMF_USE_IPC_V2__
1034 EXPORT_C void TMMFMessage::ReadData1FromClientL(TDes8& aDes)
1036 #ifdef __MMF_USE_IPC_V2__
1037 iMessage.ReadL(1, aDes);
1039 iMessage.ReadL(iMessage.Ptr1(), aDes);
1040 #endif // __MMF_USE_IPC_V2__
1043 EXPORT_C TInt TMMFMessage::ReadData1FromClient(TDes8& aDes)
1045 TRAPD(err, ReadData1FromClientL(aDes));
1049 EXPORT_C TInt TMMFMessage::SizeOfData2FromClient()
1051 #ifdef __MMF_USE_IPC_V2__
1052 return iMessage.GetDesLength(2);
1054 return iMessage.Client().GetDesLength(iMessage.Ptr2());
1055 #endif // __MMF_USE_IPC_V2__
1058 EXPORT_C void TMMFMessage::ReadData2FromClientL(TDes8& aDes)
1060 #ifdef __MMF_USE_IPC_V2__
1061 iMessage.ReadL(2, aDes);
1063 iMessage.ReadL(iMessage.Ptr2(), aDes);
1064 #endif // __MMF_USE_IPC_V2__
1067 EXPORT_C TInt TMMFMessage::ReadData2FromClient(TDes8& aDes)
1069 TRAPD(err, ReadData2FromClientL(aDes));
1073 EXPORT_C void TMMFMessage::WriteDataToClientL(const TDesC8& aDes)
1075 #ifdef __MMF_USE_IPC_V2__
1076 iMessage.WriteL(3, aDes);
1078 iMessage.WriteL(iMessage.Ptr3(), aDes);
1079 #endif // __MMF_USE_IPC_V2__
1082 EXPORT_C TInt TMMFMessage::WriteDataToClient(const TDesC8& aDes)
1084 TRAPD(err, WriteDataToClientL(aDes));
1088 EXPORT_C void TMMFMessage::Complete(TInt aReason)
1090 iMessage.Complete(aReason);
1091 iAmCompleted = ETrue;
1094 EXPORT_C TBool TMMFMessage::IsCompleted()
1096 return iAmCompleted;
1099 EXPORT_C void TMMFMessage::AdoptFileHandleFromClientL(TInt aFsHandleIndex, TInt aFileHandleIndex, RFile& aFile)
1101 User::LeaveIfError(aFile.AdoptFromClient(RMessage2(iMessage) , aFsHandleIndex, aFileHandleIndex));
1104 EXPORT_C TMMFMessage::TMMFMessage(const RMmfIpcMessage& aMessage) :
1106 #ifdef __MMF_USE_IPC_V2__
1107 iFunction(aMessage.Function()),
1108 #endif // __MMF_USE_IPC_V2__
1109 iAmCompleted(EFalse)
1113 EXPORT_C void TMMFMessage::FetchDestinationL()
1115 // Read the destination info from the client
1116 TMMFMessageDestinationPckg pckg;
1117 #ifdef __MMF_USE_IPC_V2__
1118 iMessage.ReadL(0, pckg);
1120 iMessage.ReadL(iMessage.Ptr0(), pckg);
1121 #endif // __MMF_USE_IPC_V2__
1122 iDestination = pckg();
1132 The UID of the interface provided by this object.
1135 EXPORT_C CMMFObject::CMMFObject(TUid aInterfaceId)
1136 : iHandle(aInterfaceId, KMMFObjectHandleNull)
1143 EXPORT_C CMMFObject::~CMMFObject()
1148 Returns the handle of the object.
1150 @return The handle of this object.
1154 EXPORT_C const TMMFMessageDestination& CMMFObject::Handle()
1160 Compares two CMMFObjects by comparing their handles.
1163 The object to be compared with this object.
1165 @return A boolean indicating if the two CMMFObjects are the same. ETrue if they are the same,
1166 EFalse if the objects are different.
1169 EXPORT_C TBool CMMFObject::operator==(const CMMFObject& aOther)
1171 return (iHandle==aOther.iHandle);
1174 void CMMFObject::SetHandle(const TMMFMessageDestination& aNewHandle)
1176 iHandle = aNewHandle;
1180 // CMMFDataSourceHolder
1186 The data source to be wrapped.
1190 EXPORT_C CMMFDataSourceHolder::CMMFDataSourceHolder(MDataSource& aDataSource)
1191 : CMMFObject(KUidInterfaceMMFDataSourceHolder), iDataSource(&aDataSource)
1198 Note: This deletes the data source.
1202 EXPORT_C CMMFDataSourceHolder::~CMMFDataSourceHolder()
1208 Returns a reference to the data source.
1210 @return The data source.
1214 EXPORT_C MDataSource& CMMFDataSourceHolder::DataSource()
1216 return *iDataSource;
1220 Implementation of the pure virtual function inherited from CMMFObject.
1222 Passes the request directly to the data source.
1225 The message to be handled.
1229 EXPORT_C void CMMFDataSourceHolder::HandleRequest(TMMFMessage& aMessage)
1231 iDataSource->SourceCustomCommand(aMessage);
1235 // CMMFDataSinkHolder
1241 The data sink to be wrapped.
1244 EXPORT_C CMMFDataSinkHolder::CMMFDataSinkHolder(MDataSink& aDataSink)
1245 : CMMFObject(KUidInterfaceMMFDataSinkHolder), iDataSink(&aDataSink)
1252 Note: This deletes the data sink.
1256 EXPORT_C CMMFDataSinkHolder::~CMMFDataSinkHolder()
1262 Returns a reference to the data sink.
1264 @return The data sink.
1267 EXPORT_C MDataSink& CMMFDataSinkHolder::DataSink()
1273 Implementation of the pure virtual function inherited from CMMFObject.
1275 Passes the request directly to the data sink.
1278 The message to be handled.
1282 EXPORT_C void CMMFDataSinkHolder::HandleRequest(TMMFMessage& aMessage)
1284 iDataSink->SinkCustomCommand(aMessage);
1288 // CMMFCustomCommandParserBase
1289 EXPORT_C TUid CMMFCustomCommandParserBase::InterfaceId()
1291 return iInterfaceId;
1294 EXPORT_C CMMFCustomCommandParserBase::~CMMFCustomCommandParserBase()
1298 EXPORT_C CMMFCustomCommandParserBase::CMMFCustomCommandParserBase(TUid aInterfaceId)
1299 : iInterfaceId(aInterfaceId)
1304 // CMMFObjectContainer
1311 EXPORT_C CMMFObjectContainer::CMMFObjectContainer()
1313 iNextObjectHandle = KMMFObjectHandleFirstValid;
1319 Deletes all objects owned by the container.
1323 EXPORT_C CMMFObjectContainer::~CMMFObjectContainer()
1325 iObjects.ResetAndDestroy();
1330 Add an object to the container.
1332 Once the object has been added, its ownership is transferred to the container.
1335 A reference to the object to be added to the container.
1337 @return An error code indicating if the function call was successful. If the return code is not KErrNone, then
1338 ownership of the object still remains with the caller.
1341 EXPORT_C TInt CMMFObjectContainer::AddMMFObject(CMMFObject& aObject)
1343 // Check the object isn't already added
1344 if (aObject.Handle().DestinationHandle() != KMMFObjectHandleNull)
1345 return KErrAlreadyExists;
1347 TMMFMessageDestination newHandle(aObject.Handle().InterfaceId(), GenerateObjectHandle());
1348 // Set the object's handle
1349 aObject.SetHandle(newHandle);
1350 // Append the object to the array
1351 TInt error = iObjects.Append(&aObject);
1352 // If error occurred, reset object handle to NULL
1355 TMMFMessageDestination evenNewerHandle(aObject.Handle().InterfaceId(), KMMFObjectHandleNull);
1356 aObject.SetHandle(evenNewerHandle);
1362 Removes and destroys an object from the container.
1364 This method ensures that the object is no longer in the container, and that it gets deleted.
1365 Even if the object is not found in the container's array of objects, it will be deleted.
1368 A reference to the object to be deleted.
1372 EXPORT_C void CMMFObjectContainer::RemoveAndDestroyMMFObject(CMMFObject& aObject)
1374 TInt positionOfObjectInArray;
1375 TInt error = FindMMFObject(aObject, positionOfObjectInArray);
1378 iObjects.Remove(positionOfObjectInArray);
1380 //else, we don't care since we're just saying we'll make sure the object
1381 //isn't in the array, and that it gets deleted.
1386 Removes and destroys all objects from the container.
1390 EXPORT_C void CMMFObjectContainer::DeleteAllObjects()
1392 iObjects.ResetAndDestroy();
1396 Finds an object in the container using a handle.
1398 @param aObjectHandle
1399 The handle of the object to be located.
1401 A reference to a pointer to the object found in the container.
1403 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
1404 another of the system-wide error codes.
1407 EXPORT_C TInt CMMFObjectContainer::FindMMFObject(const TMMFMessageDestination& aObjectHandle, CMMFObject*& aObjectFound)
1409 // Need to find the appropriate object in the array of CMMFObjects
1410 TInt error = KErrNotFound;
1411 for (TInt i=0; i<iObjects.Count(); i++)
1413 CMMFObject* obj = iObjects[i];
1414 if (obj->Handle() == aObjectHandle)
1424 const RPointerArray<CMMFObject>& CMMFObjectContainer::MMFObjects()
1429 TInt CMMFObjectContainer::FindMMFObject(const CMMFObject& aObject, TInt& aPositionInArray)
1431 TInt error = KErrNotFound;
1432 for (TInt i=0; i<iObjects.Count(); i++)
1434 CMMFObject* obj = iObjects[i];
1435 if (*obj == aObject)
1438 aPositionInArray = i;
1445 TInt CMMFObjectContainer::GenerateObjectHandle()
1447 return iNextObjectHandle++;
1451 CLogonMonitor::CLogonMonitor(MLogonMonitorObserver* aLogonMonitorObserver)
1452 : CActive(EPriorityStandard)
1454 iLogonMonitorObserver = aLogonMonitorObserver;
1457 void CLogonMonitor::ConstructL()
1459 if (CActiveScheduler::Current()==0)
1461 iScheduler = new (ELeave) CActiveScheduler;
1462 CActiveScheduler::Install(iScheduler);
1465 CActiveScheduler::Add(this);
1468 CLogonMonitor* CLogonMonitor::NewL(MLogonMonitorObserver* aLogonMonitorObserver)
1470 CLogonMonitor* self = new (ELeave) CLogonMonitor(aLogonMonitorObserver);
1471 CleanupStack::PushL(self);
1473 CleanupStack::Pop(self);
1477 CLogonMonitor::~CLogonMonitor()
1483 CActiveScheduler::Install(NULL);
1488 void CLogonMonitor::StartMonitoring(RThread& aThread)
1493 iThread->Logon(iStatus);
1497 void CLogonMonitor::RunL()
1500 iLogonMonitorObserver->ThreadTerminated();
1503 void CLogonMonitor::DoCancel()
1507 iThread->LogonCancel(iStatus);
1511 RServer2& CLogonMonitor::Server()
1516 CMMFControllerExtendedData::CMMFControllerExtendedData()
1517 : CMMFObject(KUidMMFControllerExtendedDataHolder), iSourceSinkInitData(NULL)
1519 iClientThreadId = 0;
1520 iSecureDrmMode = EFalse;
1523 CMMFControllerExtendedData::~CMMFControllerExtendedData()
1525 ResetSourceSinkInitData();
1528 void CMMFControllerExtendedData::SetSourceSinkInitData(HBufC8* aSourceSinkInitData)
1530 ResetSourceSinkInitData();
1531 iSourceSinkInitData = aSourceSinkInitData;
1534 HBufC8* CMMFControllerExtendedData::SourceSinkInitData() const
1536 return iSourceSinkInitData;
1539 void CMMFControllerExtendedData::ResetSourceSinkInitData()
1541 if (iSourceSinkInitData)
1543 delete iSourceSinkInitData;
1544 iSourceSinkInitData = NULL;
1548 void CMMFControllerExtendedData::SetClientThreadId(TThreadId aClientThreadId)
1550 iClientThreadId = aClientThreadId;
1553 TThreadId CMMFControllerExtendedData::ClientThreadId() const
1555 return iClientThreadId;
1558 void CMMFControllerExtendedData::SetSecureDrmMode(TBool aSecureDrmMode)
1560 iSecureDrmMode = aSecureDrmMode;
1563 TBool CMMFControllerExtendedData::SecureDrmMode() const
1565 return iSecureDrmMode;
1568 void CMMFControllerExtendedData::HandleRequest(TMMFMessage& /*aMessage*/)
1570 // This function is not suppose to be called.
1572 Panic(EPanicBadInvariant);