sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include "mmfcontrollerframework.h" sl@0: #include "mmfcontroller.h" sl@0: #include "mmfcontrollerheap.h" sl@0: #include "mmfcontrollerframeworkpriv.h" sl@0: #include "mmfcontrollerpatchdata.h" sl@0: sl@0: #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS sl@0: #include sl@0: #include sl@0: #include sl@0: #endif sl@0: sl@0: // Panic sl@0: sl@0: enum sl@0: { sl@0: EPanicHeapHalfOpen=1, sl@0: EPanicHeapOpenWithoutTls, sl@0: EPanicReleaseWithoutRegister, sl@0: EPanicBadInvariant sl@0: }; sl@0: sl@0: #ifdef _DEBUG sl@0: static void Panic(TInt aReason) sl@0: { sl@0: _LIT(KControllerFramework, "ControllerFramework"); sl@0: User::Panic(KControllerFramework, aReason); sl@0: } sl@0: #endif sl@0: sl@0: EXPORT_C RMMFControllerProxy::RMMFControllerProxy() : sl@0: iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFControllerProxy, KMMFObjectHandleControllerProxy)), sl@0: iLogonAO(NULL), iThreadPriority(static_cast(KDefaultMMFControllerThreadPriority)), iFlags(0) sl@0: { sl@0: iSubThread.Close();//iSubThread is automatically initialised to be a handle to this thread! sl@0: } sl@0: sl@0: TInt RMMFControllerProxy::LoadController( sl@0: TUid aControllerUid, sl@0: const CMMFControllerImplementationInformation& aControllerInfo, sl@0: TBool aUseSharedHeap, sl@0: TBool aNoDRMCap) sl@0: { sl@0: // First check that we haven't already created the subthread sl@0: if (iSubThread.Handle() != 0) sl@0: return KErrAlreadyExists; sl@0: sl@0: #ifdef SYMBIAN_FORCE_USE_SHARED_HEAP sl@0: aUseSharedHeap = ETrue; sl@0: #endif sl@0: sl@0: //determine what maximum heap size this thread should be created with sl@0: TUint maxHeapSize =0; sl@0: TInt error = KErrNone; sl@0: maxHeapSize = aControllerInfo.HeapSpaceRequired(); sl@0: TUint stackSize = aControllerInfo.StackSize(); sl@0: sl@0: ASSERT(!iLogonAO); sl@0: TRAP(error, iLogonAO = CLogonMonitor::NewL(this)); sl@0: sl@0: if (!error) sl@0: { sl@0: if (aNoDRMCap && aControllerInfo.SupportsSecureDRMProcessMode()) sl@0: { sl@0: error = DoCreateSessionForNoDRMCapClient(maxHeapSize, aUseSharedHeap, stackSize); sl@0: } sl@0: else sl@0: { sl@0: // server2 will be set in this function call sl@0: error = DoCreateSubThread(&iLogonAO->Server(), maxHeapSize, aUseSharedHeap, stackSize); sl@0: sl@0: // Now create a session with the controller proxy server running in the subthread sl@0: if (!error) sl@0: { sl@0: // create a session with iServer2 (local server) sl@0: error = CreateSession(iLogonAO->Server(), KMMFControllerProxyVersion); sl@0: } sl@0: } sl@0: } sl@0: sl@0: // Finally, tell the controller proxy server to load the relevant plugin sl@0: if (!error) sl@0: { sl@0: TMMFUidPckg uidPckg(aControllerUid); sl@0: error = SendSync(iDestinationPckg, sl@0: EMMFControllerProxyLoadControllerPluginByUid, sl@0: uidPckg, sl@0: KNullDesC8); sl@0: } sl@0: sl@0: // If an error occurred with any of the above, close all the handles sl@0: if (error) sl@0: Close(); sl@0: sl@0: return error; sl@0: } sl@0: sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::LoadController(TUid aControllerUid, TBool aUseSharedHeap) sl@0: { sl@0: CMMFControllerImplementationInformation* controllerInfo = NULL; sl@0: sl@0: TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid)); sl@0: if (!err && controllerInfo) sl@0: { sl@0: err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, EFalse); sl@0: delete controllerInfo; sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::LoadController(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap) sl@0: { sl@0: return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, EFalse); sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(TUid aControllerUid, TBool aUseSharedHeap) sl@0: { sl@0: CMMFControllerImplementationInformation* controllerInfo = NULL; sl@0: sl@0: TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid)); sl@0: if (!err && controllerInfo) sl@0: { sl@0: err = LoadController(aControllerUid, *controllerInfo, aUseSharedHeap, ETrue); sl@0: delete controllerInfo; sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::LoadControllerInSecureDRMProcess(const CMMFControllerImplementationInformation& aControllerInfo, TBool aUseSharedHeap) sl@0: { sl@0: return LoadController(aControllerInfo.Uid(), aControllerInfo, aUseSharedHeap, ETrue); sl@0: } sl@0: sl@0: TUint RMMFControllerProxy::ControllersMaxHeapSizeL(TUid aControllerUid) sl@0: { sl@0: CMMFControllerImplementationInformation* controllerInfo = NULL; sl@0: sl@0: TRAPD(err, controllerInfo = CMMFControllerImplementationInformation::NewL(aControllerUid)); sl@0: sl@0: sl@0: TUint maxHeapSize = KMMFDefaultControllerThreadHeapSize; sl@0: sl@0: if((err != KErrNone) && (err != KErrCorrupt)) sl@0: { sl@0: delete controllerInfo; sl@0: User::Leave(err); sl@0: } sl@0: sl@0: sl@0: if(controllerInfo && (err == KErrNone)) sl@0: maxHeapSize = controllerInfo->HeapSpaceRequired(); sl@0: sl@0: delete controllerInfo; sl@0: sl@0: return maxHeapSize; sl@0: } sl@0: sl@0: sl@0: TInt RMMFControllerProxy::DoCreateSubThread(RServer2* aServer2, TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize) sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: TControllerProxyServerParams params; sl@0: params.iServer = aServer2; sl@0: params.iUsingSharedHeap = aUseSharedHeap; sl@0: sl@0: #ifdef SYMBIAN_USE_CLIENT_HEAP sl@0: // controller threads share the *client* heap (intended for out of memory testing) sl@0: error = iSubThread.Create(_L(""), &CMMFControllerProxyServer::StartThread, sl@0: aStackSize, NULL, ¶ms, EOwnerThread); sl@0: #else sl@0: if( aUseSharedHeap ) sl@0: { sl@0: //controller threads all share a controller heap sl@0: CMMFControllerHeap* contHeap = static_cast(Dll::Tls()); sl@0: if(contHeap == NULL) sl@0: { sl@0: TRAP(error, contHeap = CMMFControllerHeap::NewL()); sl@0: if(error) sl@0: { sl@0: return error; sl@0: } sl@0: sl@0: Dll::SetTls(contHeap); sl@0: } sl@0: sl@0: __ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap)==0, Panic(EPanicHeapHalfOpen)); sl@0: sl@0: RHeap* sharedHeap = contHeap->RegisterHeap(); sl@0: // We've registered, so record the fact so can "unregister" on close or error sl@0: iFlags |= EFlagOpenedSharedHeap; sl@0: sl@0: error = iSubThread.Create(KNullDesC, &CMMFControllerProxyServer::StartThread, sl@0: aStackSize, sharedHeap, sl@0: ¶ms, EOwnerThread); sl@0: } sl@0: else sl@0: { sl@0: // Threads create own heap (default behaviour) sl@0: if(aMaxHeapSize < static_cast(KMinHeapSize)) sl@0: aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic sl@0: else if(aMaxHeapSize > static_cast(KMMFControllerProxyMaxHeapSize)) sl@0: aMaxHeapSize = KMMFControllerProxyMaxHeapSize; sl@0: sl@0: TThreadCreateInfo threadSettings (KNullDesC, &CMMFControllerProxyServer::StartThread, sl@0: aStackSize, ¶ms); sl@0: threadSettings.SetCreateHeap(KMinHeapSize, aMaxHeapSize); sl@0: threadSettings.SetOwner(EOwnerThread); sl@0: threadSettings.SetPaging(TThreadCreateInfo::EUnpaged); sl@0: sl@0: error = iSubThread.Create(threadSettings); sl@0: } sl@0: #endif sl@0: sl@0: if (error) sl@0: { sl@0: return error; sl@0: } sl@0: sl@0: TRequestStatus rendezvous; sl@0: iSubThread.Rendezvous(rendezvous); sl@0: if (rendezvous != KRequestPending) sl@0: { sl@0: iSubThread.Kill(0); sl@0: } sl@0: else sl@0: { sl@0: iLogonAO->StartMonitoring(iSubThread); sl@0: if (iLogonAO->iStatus != KRequestPending) sl@0: { sl@0: // Failed to logon sl@0: iSubThread.RendezvousCancel(rendezvous); sl@0: User::WaitForRequest(rendezvous); sl@0: iSubThread.Kill(0); sl@0: iSubThread.Close(); sl@0: return iLogonAO->iStatus.Int(); sl@0: } sl@0: else sl@0: { sl@0: iSubThread.SetPriority(iThreadPriority); sl@0: iSubThread.Resume(); sl@0: } sl@0: } sl@0: sl@0: User::WaitForRequest(rendezvous); // wait for startup or death sl@0: sl@0: if (rendezvous != KErrNone) sl@0: { sl@0: iLogonAO->Cancel(); sl@0: iSubThread.Close(); sl@0: // if open failed, but we registered the heap, need to release sl@0: if((iFlags&EFlagOpenedSharedHeap)) sl@0: { sl@0: ReleaseHeap(); sl@0: } sl@0: } sl@0: sl@0: return rendezvous.Int(); sl@0: } sl@0: sl@0: EXPORT_C void RMMFControllerProxy::Close() sl@0: { sl@0: #ifdef _DEBUG sl@0: _LIT(KMMFClientThreadPanic, "MMFClientThread"); sl@0: #endif sl@0: // check if thread was created sl@0: TBool subThreadCreated = EFalse; sl@0: TRequestStatus logoffStatus; sl@0: TBool logoffFailed = EFalse; sl@0: if (iSubThread.Handle() != KNullHandle) sl@0: { sl@0: subThreadCreated = ETrue; sl@0: iLogonAO->Cancel(); sl@0: iSubThread.Logon(logoffStatus); sl@0: sl@0: if (logoffStatus == KErrNoMemory && iSubThread.ExitType() == EExitPending) sl@0: { sl@0: // Logon() call has failed because of a lack of memory sl@0: logoffFailed = ETrue; sl@0: } sl@0: } sl@0: sl@0: // Close the controller and wait for its exit. sl@0: // Close the session to signal the controller proxy server to shut down. sl@0: RHandleBase::Close(); sl@0: sl@0: // Now wait for the death of the subthread if we have a valid handle... sl@0: if (subThreadCreated) sl@0: { sl@0: RProcess thisProcess; sl@0: RProcess controllerProcess; sl@0: iSubThread.Process(controllerProcess); // ignore error, best try sl@0: TBool secureDrmMode = thisProcess.Id() != controllerProcess.Id(); sl@0: thisProcess.Close(); sl@0: controllerProcess.Close(); sl@0: sl@0: RTimer timer; sl@0: TInt err = timer.CreateLocal(); sl@0: // If we managed to create the timer and logon to the thread, sl@0: // wait for both the death and the timeout to minimise the risk of deadlock sl@0: if (!err && !logoffFailed) sl@0: { sl@0: TRequestStatus timeout; sl@0: timer.After(timeout, KMmfControllerThreadShutdownTimeout); sl@0: User::WaitForRequest(logoffStatus, timeout); sl@0: if (logoffStatus == KRequestPending) sl@0: { sl@0: // we have timed out. Kill the controller thread sl@0: iSubThread.LogonCancel(logoffStatus); sl@0: User::WaitForRequest(logoffStatus); sl@0: sl@0: if (!secureDrmMode) sl@0: { sl@0: // Controller server thread is created in current process sl@0: #ifdef _DEBUG sl@0: iSubThread.Panic(KMMFClientThreadPanic,KErrDied); sl@0: #else sl@0: iSubThread.Kill(KErrDied); sl@0: #endif sl@0: } sl@0: else sl@0: { sl@0: // Controller server thread is created through DRM plugin server sl@0: RMMFDRMPluginServerProxy server; sl@0: // ignore all RMMFDRMPluginServerProxy errors, best try sl@0: err = server.Open(); sl@0: if (err == KErrNone) sl@0: { sl@0: #ifdef _DEBUG sl@0: server.PanicControllerThread(iSubThread.Id(), KMMFClientThreadPanic, KErrDied); sl@0: #else sl@0: server.KillControllerThread(iSubThread.Id(), KErrDied); sl@0: #endif sl@0: server.Close(); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // subthread has exited. Cancel the timer. sl@0: timer.Cancel(); sl@0: User::WaitForRequest(timeout); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // We have no timer or we can't logon to the thread so we'll just poll the thread status a maximum sl@0: // of 10 times and kill the thread if it hasn't exited after the polling sl@0: for (TInt i=0; i<10 && iSubThread.ExitType() == EExitPending; ++i) sl@0: { sl@0: User::After(KMmfControllerThreadShutdownTimeout/10); // wait for a while sl@0: } sl@0: sl@0: if (iSubThread.ExitType() == EExitPending) sl@0: { sl@0: // The polling hasn't been succesful so we kill the thread sl@0: if (!secureDrmMode) sl@0: { sl@0: iSubThread.Kill(KErrDied); sl@0: } sl@0: else sl@0: { sl@0: // Controller server thread is created through DRM plugin server sl@0: RMMFDRMPluginServerProxy server; sl@0: // ignore all RMMFDRMPluginServerProxy errors, best try sl@0: err = server.Open(); sl@0: if (err == KErrNone) sl@0: { sl@0: server.KillControllerThread(iSubThread.Id(), KErrDied); sl@0: } sl@0: } sl@0: } sl@0: sl@0: User::WaitForRequest(logoffStatus); sl@0: } sl@0: timer.Close(); sl@0: } sl@0: sl@0: // Close the handle to the controller thread sl@0: iSubThread.Close(); sl@0: // Delete the Logon AO sl@0: if (iLogonAO) sl@0: { sl@0: delete iLogonAO; sl@0: iLogonAO = NULL; sl@0: } sl@0: // if this is last thread to be killed delete shared heap sl@0: if((iFlags&EFlagOpenedSharedHeap)) sl@0: { sl@0: ReleaseHeap(); sl@0: } sl@0: } sl@0: sl@0: // Release the shared heap, should only be called if has previously been registered sl@0: // by this thread sl@0: void RMMFControllerProxy::ReleaseHeap() sl@0: { sl@0: __ASSERT_DEBUG((iFlags&EFlagOpenedSharedHeap), Panic(EPanicReleaseWithoutRegister)); sl@0: sl@0: CMMFControllerHeap* contHeap = static_cast(Dll::Tls()); sl@0: __ASSERT_DEBUG(contHeap!=NULL, Panic(EPanicHeapOpenWithoutTls)); sl@0: sl@0: if(contHeap != NULL) sl@0: { sl@0: TInt refCount = contHeap->ReleaseHeap(); sl@0: if(refCount == 0) sl@0: { //no other controllers using the heap sl@0: delete contHeap; sl@0: Dll::SetTls(NULL); sl@0: } sl@0: } sl@0: sl@0: iFlags &= ~EFlagOpenedSharedHeap; // clear flag since we've released the heap sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) const sl@0: { sl@0: // Make sure we have been opened sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: else sl@0: return SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom); sl@0: } sl@0: sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::SendSync(TInt aFunction, const TIpcArgs& aIpcArgs) const sl@0: { sl@0: // Make sure we have been opened sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: else sl@0: return RSessionBase::SendReceive(aFunction, aIpcArgs); sl@0: } sl@0: sl@0: EXPORT_C void RMMFControllerProxy::SendAsync(TInt aFunction, const TIpcArgs& aIpcArgs, TRequestStatus& aStatus) const sl@0: { sl@0: // Make sure we have been opened sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, KErrNotReady); sl@0: } sl@0: else sl@0: RSessionBase::SendReceive(aFunction, aIpcArgs, aStatus); sl@0: } sl@0: sl@0: sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::SendSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) const sl@0: { sl@0: // Make sure we have been opened sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: else sl@0: return SendReceive(aFunction, aDestination, aDataTo1, aDataTo2); sl@0: } sl@0: sl@0: EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) const sl@0: { sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: TRequestStatus* stat = &aStatus; sl@0: User::RequestComplete(stat, KErrNotReady); sl@0: } sl@0: else sl@0: SendReceiveResult(aFunction, aDestination, aDataTo1, aDataTo2, aDataFrom, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RMMFControllerProxy::SendAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) const sl@0: { sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: TRequestStatus* stat = &aStatus; sl@0: User::RequestComplete(stat, KErrNotReady); sl@0: } sl@0: else sl@0: SendReceive(aFunction, aDestination, aDataTo1, aDataTo2, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RMMFControllerProxy::ReceiveEvents(TMMFEventPckg& aEvent, TRequestStatus& aStatus) sl@0: { sl@0: SendAsync(iDestinationPckg, EMMFControllerProxyReceiveEvents, KNullDesC8, KNullDesC8, aEvent, aStatus); sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::CancelReceiveEvents() sl@0: { sl@0: return SendSync(iDestinationPckg, EMMFControllerProxyCancelReceiveEvents, KNullDesC8, KNullDesC8); sl@0: } sl@0: sl@0: EXPORT_C TInt RMMFControllerProxy::SetThreadPriority(const TThreadPriority& aPriority) const sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: if (iSubThread.Handle() == 0) sl@0: { sl@0: err = KErrNotReady; sl@0: } sl@0: else sl@0: { sl@0: if (iThreadPriority != aPriority) sl@0: { sl@0: // This is a const method so cast it away to store the priority sl@0: RMMFControllerProxy* nonConstThis = const_cast(this); sl@0: nonConstThis->iThreadPriority = aPriority; sl@0: } sl@0: sl@0: // check controller thread creation location sl@0: RProcess thisProcess; sl@0: RProcess controllerProcess; sl@0: err = iSubThread.Process(controllerProcess); sl@0: sl@0: if (err == KErrNone) sl@0: { sl@0: if (thisProcess.Id() == controllerProcess.Id()) sl@0: { sl@0: // Controller server thread is created in current process sl@0: if (iSubThread.Priority() != iThreadPriority) sl@0: { sl@0: iSubThread.Suspend(); sl@0: iSubThread.SetPriority(iThreadPriority); sl@0: iSubThread.Resume(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Controller server thread is created through DRM plugin server sl@0: RMMFDRMPluginServerProxy server; sl@0: err = server.Open(); sl@0: if (err == KErrNone) sl@0: { sl@0: err = server.SetThreadPriority(iSubThread.Id(), iThreadPriority); sl@0: server.Close(); sl@0: } sl@0: } sl@0: } sl@0: thisProcess.Close(); sl@0: controllerProcess.Close(); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void RMMFControllerProxy::ThreadTerminated() sl@0: { sl@0: // The controller subthread has died and the controller should be closed sl@0: iSubThread.Close(); sl@0: } sl@0: sl@0: TInt RMMFControllerProxy::DoCreateSessionForNoDRMCapClient(TUint aMaxHeapSize, TBool aUseSharedHeap, TUint aStackSize) sl@0: { sl@0: TThreadId tid; sl@0: RMMFDRMPluginServerProxy server; sl@0: TInt error = server.Open(); sl@0: sl@0: if(!error) sl@0: { sl@0: error = server.LaunchControllerServer(aMaxHeapSize, aUseSharedHeap, tid, aStackSize); sl@0: } sl@0: if(!error) sl@0: { sl@0: error = iSubThread.Open(tid, EOwnerThread); sl@0: if(!error) sl@0: { sl@0: iLogonAO->StartMonitoring(iSubThread); sl@0: if (iLogonAO->iStatus != KRequestPending) sl@0: { sl@0: // Failed to logon sl@0: server.KillControllerThread(tid, 0); sl@0: iSubThread.Close(); sl@0: error = iLogonAO->iStatus.Int(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Failed to open thread handle sl@0: server.KillControllerThread(tid, 0); sl@0: } sl@0: } sl@0: if(!error) sl@0: { sl@0: error = server.SetThreadPriority(tid, iThreadPriority); sl@0: if(!error) sl@0: { sl@0: error = SetReturnedHandle(server.GetControllerSessionHandle()); sl@0: } sl@0: if(error) sl@0: { sl@0: // Failed to create session with controller sl@0: iLogonAO->Cancel(); sl@0: server.KillControllerThread(tid, 0); sl@0: iSubThread.Close(); sl@0: } sl@0: } sl@0: server.Close(); sl@0: return error; sl@0: } sl@0: sl@0: sl@0: // RMMFCustomCommandsBase sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: @param aController sl@0: A reference to the controller client class that will be used to send sl@0: custom commands to the controller plugin. sl@0: @param aInterfaceId sl@0: The UID of the custom command interface that is provided by this client sl@0: API class. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C RMMFCustomCommandsBase::RMMFCustomCommandsBase(RMMFController& aController, TUid aInterfaceId) sl@0: : iController(aController), iDestinationPckg(aInterfaceId) sl@0: { sl@0: } sl@0: sl@0: sl@0: // TMMFMessageDestination sl@0: EXPORT_C TMMFMessageDestination::TMMFMessageDestination() sl@0: : iInterfaceId(KNullUid), iDestinationHandle(KMMFObjectHandleController) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId) sl@0: : iInterfaceId(aInterfaceId), iDestinationHandle(KMMFObjectHandleController) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TMMFMessageDestination::TMMFMessageDestination(TUid aInterfaceId, TInt aDestinationHandle) sl@0: : iInterfaceId(aInterfaceId), iDestinationHandle(aDestinationHandle) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TMMFMessageDestination::TMMFMessageDestination(const TMMFMessageDestination& aOther) sl@0: : iInterfaceId(aOther.iInterfaceId), iDestinationHandle(aOther.iDestinationHandle) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TUid TMMFMessageDestination::InterfaceId() const sl@0: { sl@0: return iInterfaceId; sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessageDestination::DestinationHandle() const sl@0: { sl@0: return iDestinationHandle; sl@0: } sl@0: sl@0: EXPORT_C TBool TMMFMessageDestination::operator==(const TMMFMessageDestination& aOther) const sl@0: { sl@0: return ((iInterfaceId==aOther.iInterfaceId) && (iDestinationHandle==aOther.iDestinationHandle)); sl@0: } sl@0: sl@0: sl@0: sl@0: // CMMFControllerProxySession sl@0: CMMFControllerProxySession* CMMFControllerProxySession::NewL() sl@0: { sl@0: CMMFControllerProxySession* s = new(ELeave) CMMFControllerProxySession; sl@0: return s; sl@0: } sl@0: sl@0: void CMMFControllerProxySession::CreateL(const CMmfIpcServer& aServer) sl@0: { sl@0: CMmfIpcSession::CreateL(aServer); sl@0: iServer = STATIC_CAST(CMMFControllerProxyServer*, (CONST_CAST(CMmfIpcServer*, &aServer))); sl@0: iServer->SessionCreated(); sl@0: } sl@0: sl@0: CMMFControllerProxySession::~CMMFControllerProxySession() sl@0: { sl@0: delete iController; sl@0: delete iEventReceiver; sl@0: iEvents.Close(); sl@0: iServer->SessionDestroyed(); sl@0: } sl@0: sl@0: sl@0: sl@0: void CMMFControllerProxySession::ServiceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFMessage message(aMessage); sl@0: // Get the destination info from the client. sl@0: message.FetchDestinationL(); sl@0: sl@0: if (message.Destination().InterfaceId() == KUidInterfaceMMFControllerProxy) sl@0: { sl@0: // Message for controller proxy so decode here sl@0: TBool complete = EFalse; sl@0: switch (message.Function()) sl@0: { sl@0: case EMMFControllerProxyReceiveEvents: sl@0: complete = ReceiveEventsL(message); sl@0: break; sl@0: case EMMFControllerProxyCancelReceiveEvents: sl@0: complete = CancelReceiveEvents(message); sl@0: break; sl@0: case EMMFControllerProxyLoadControllerPluginByUid: sl@0: complete = LoadControllerL(message); sl@0: break; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: if (complete) sl@0: message.Complete(KErrNone); sl@0: } sl@0: else sl@0: { sl@0: // Message for controller so forward on to controller baseclass sl@0: if (iController) sl@0: iController->HandleRequestL(message); sl@0: else sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: } sl@0: sl@0: CMMFControllerProxySession::CMMFControllerProxySession() sl@0: { sl@0: } sl@0: sl@0: TBool CMMFControllerProxySession::ReceiveEventsL(TMMFMessage& aMessage) sl@0: { sl@0: if (iEventReceiver) sl@0: User::Leave(KErrAlreadyExists); sl@0: iEventReceiver = CMMFEventReceiver::NewL(aMessage); sl@0: //send the next cached event (if any) to the client sl@0: if (iEvents.Count() > 0) sl@0: { sl@0: TMMFEvent& event = iEvents[0]; sl@0: iEventReceiver->SendEvent(event); sl@0: delete iEventReceiver; sl@0: iEventReceiver=NULL; sl@0: iEvents.Remove(0); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CMMFControllerProxySession::CancelReceiveEvents(TMMFMessage& /*aMessage*/) sl@0: { sl@0: delete iEventReceiver; sl@0: iEventReceiver = NULL; sl@0: return ETrue; sl@0: } sl@0: sl@0: TInt CMMFControllerProxySession::SendEventToClient(const TMMFEvent& aEvent) sl@0: { sl@0: TInt error = KErrNone; sl@0: if (iEventReceiver) sl@0: { sl@0: //send event to client now sl@0: iEventReceiver->SendEvent(aEvent); sl@0: delete iEventReceiver; sl@0: iEventReceiver=NULL; sl@0: error = KErrNone; sl@0: } sl@0: else sl@0: { sl@0: //queue the request for later sl@0: TMMFEvent event(aEvent); sl@0: //if we've exceeded the max number of cached messages, delete the first and append this one to the end sl@0: if (iEvents.Count() >= KMMFControllerProxyMaxCachedMessages) sl@0: iEvents.Remove(0); sl@0: error = iEvents.Append(event); sl@0: } sl@0: return error; sl@0: } sl@0: sl@0: TBool CMMFControllerProxySession::LoadControllerL(TMMFMessage& aMessage) sl@0: { sl@0: TMMFUidPckg pckg; sl@0: aMessage.ReadData1FromClientL(pckg); sl@0: sl@0: RThread clientThread; sl@0: aMessage.iMessage.ClientL(clientThread); sl@0: CleanupClosePushL(clientThread); sl@0: iController = CMMFController::NewL(pckg(), *this, clientThread.Id()); sl@0: CleanupStack::PopAndDestroy(&clientThread); sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: sl@0: CMMFControllerProxyServer* CMMFControllerProxyServer::NewL(RServer2* aServer2) sl@0: { sl@0: CMMFControllerProxyServer* s = new(ELeave) CMMFControllerProxyServer(); sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(aServer2); sl@0: CleanupStack::Pop(s); sl@0: return s; sl@0: } sl@0: sl@0: CMMFControllerProxyServer::CMMFControllerProxyServer() : sl@0: CMmfIpcServer(EPriorityStandard, EGlobalSharableSessions) sl@0: { sl@0: } sl@0: sl@0: void CMMFControllerProxyServer::ConstructL(RServer2* aServer2) sl@0: { sl@0: SetPinClientDescriptors(ETrue); sl@0: sl@0: StartL(KNullDesC); sl@0: *aServer2 = CServer2::Server(); sl@0: sl@0: iShutdownTimer = CMMFControllerProxyShutdown::NewL(); sl@0: iShutdownTimer->Start(); sl@0: } sl@0: sl@0: CMMFControllerProxyServer::~CMMFControllerProxyServer() sl@0: { sl@0: delete iShutdownTimer; sl@0: } sl@0: sl@0: EXPORT_C TInt CMMFControllerProxyServer::StartThread(TAny* aParam) sl@0: { sl@0: TInt err = KErrNone; sl@0: //create cleanupstack sl@0: CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack sl@0: if (!cleanup) sl@0: err = KErrNoMemory; sl@0: if (!err) sl@0: { sl@0: TRAP(err, DoStartThreadL(aParam)); sl@0: } sl@0: delete cleanup; sl@0: return err; sl@0: } sl@0: sl@0: void CMMFControllerProxyServer::RenameControllerProxyThread() sl@0: { sl@0: RThread thread; sl@0: TThreadId threadId; sl@0: TName name; sl@0: name.Append(KMMFControllerProxyServerName); sl@0: threadId = thread.Id(); sl@0: name.AppendNum(threadId.Id(),EHex); sl@0: User::RenameThread(name); sl@0: } sl@0: sl@0: void CMMFControllerProxyServer::DoStartThreadL(TAny* aParam) sl@0: { sl@0: TControllerProxyServerParams* params = static_cast(aParam); sl@0: sl@0: //Rename Current thread to unique name sl@0: RenameControllerProxyThread(); sl@0: sl@0: #ifndef SYMBIAN_USE_CLIENT_HEAP sl@0: TBool usingSharedHeap = params->iUsingSharedHeap; // take copy since params invalid after Rendezvous sl@0: sl@0: if( ! usingSharedHeap ) sl@0: { sl@0: __UHEAP_MARK; sl@0: } sl@0: sl@0: #endif sl@0: // create and install the active scheduler we need sl@0: CActiveScheduler* s=new(ELeave) CActiveScheduler; sl@0: CleanupStack::PushL(s); sl@0: CActiveScheduler::Install(s); sl@0: // create the server (leave it on the cleanup stack) sl@0: CleanupStack::PushL(CMMFControllerProxyServer::NewL( params->iServer ) ); sl@0: // Initialisation complete, now signal the client sl@0: RThread::Rendezvous(KErrNone); sl@0: // Ready to run sl@0: CActiveScheduler::Start(); sl@0: sl@0: REComSession::FinalClose(); sl@0: sl@0: // Cleanup the server and scheduler sl@0: CleanupStack::PopAndDestroy(2, s); sl@0: #ifndef SYMBIAN_USE_CLIENT_HEAP sl@0: if( ! usingSharedHeap ) sl@0: { sl@0: __UHEAP_MARKEND; sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: TInt CMMFControllerProxyServer::RunError(TInt aError) sl@0: { sl@0: // Send error to the client sl@0: Message().Complete(aError); sl@0: ReStart(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: CMmfIpcSession* CMMFControllerProxyServer::NewSessionL(const TVersion& aVersion) const sl@0: { sl@0: // Only one session is allowed to connect to us sl@0: if (iHaveSession) sl@0: User::Leave(KErrAlreadyExists); sl@0: // Check that the version number of the client is correct sl@0: if (!User::QueryVersionSupported(KMMFControllerProxyVersion, aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: return CMMFControllerProxySession::NewL(); sl@0: } sl@0: sl@0: void CMMFControllerProxyServer::SessionCreated() sl@0: { sl@0: iHaveSession = ETrue; sl@0: // Stop the shutdown timer sl@0: iShutdownTimer->Cancel(); sl@0: } sl@0: sl@0: void CMMFControllerProxyServer::SessionDestroyed() sl@0: { sl@0: // Need to shut down sl@0: iShutdownTimer->ShutdownNow(); sl@0: } sl@0: sl@0: CMMFControllerProxyShutdown* CMMFControllerProxyShutdown::NewL() sl@0: { sl@0: CMMFControllerProxyShutdown* s = new(ELeave) CMMFControllerProxyShutdown(); sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(); sl@0: CleanupStack::Pop(s); sl@0: return s; sl@0: } sl@0: sl@0: CMMFControllerProxyShutdown::CMMFControllerProxyShutdown() : sl@0: CTimer(EPriorityLow) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: void CMMFControllerProxyShutdown::ConstructL() sl@0: { sl@0: CTimer::ConstructL(); sl@0: } sl@0: sl@0: void CMMFControllerProxyShutdown::Start() sl@0: { sl@0: After(EMMFControllerProxyShutdownDelay); sl@0: } sl@0: sl@0: void CMMFControllerProxyShutdown::RunL() sl@0: { sl@0: ShutdownNow(); sl@0: } sl@0: sl@0: void CMMFControllerProxyShutdown::ShutdownNow() sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: CMMFEventReceiver* CMMFEventReceiver::NewL(const TMMFMessage& aMessage) sl@0: { sl@0: return new(ELeave) CMMFEventReceiver(aMessage); sl@0: } sl@0: sl@0: CMMFEventReceiver::~CMMFEventReceiver() sl@0: { sl@0: if (!(iMessage.IsCompleted())) sl@0: iMessage.Complete(KErrDied); sl@0: } sl@0: sl@0: void CMMFEventReceiver::SendEvent(const TMMFEvent& aEvent) sl@0: { sl@0: TMMFEventPckg eventpckg(aEvent); sl@0: TInt err = iMessage.WriteDataToClient(eventpckg); sl@0: iMessage.Complete(err); sl@0: } sl@0: sl@0: CMMFEventReceiver::CMMFEventReceiver(const TMMFMessage& aMessage) : iMessage(aMessage) sl@0: { sl@0: } sl@0: sl@0: sl@0: sl@0: // TMMFMessage sl@0: EXPORT_C TMMFMessage::TMMFMessage(const TMMFMessage& aMessage) : sl@0: iMessage(aMessage.iMessage), sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iFunction(aMessage.iFunction), sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: iDestination(aMessage.iDestination), sl@0: iAmCompleted(aMessage.iAmCompleted) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C const TMMFMessageDestination& TMMFMessage::Destination() sl@0: { sl@0: return iDestination; sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::Function() sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: return iFunction; sl@0: #else sl@0: return iMessage.Function(); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::SizeOfData1FromClient() sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: return iMessage.GetDesLength(1); sl@0: #else sl@0: return iMessage.Client().GetDesLength(iMessage.Ptr1()); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::ReadData1FromClientL(TDes8& aDes) sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iMessage.ReadL(1, aDes); sl@0: #else sl@0: iMessage.ReadL(iMessage.Ptr1(), aDes); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::ReadData1FromClient(TDes8& aDes) sl@0: { sl@0: TRAPD(err, ReadData1FromClientL(aDes)); sl@0: return err; sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::SizeOfData2FromClient() sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: return iMessage.GetDesLength(2); sl@0: #else sl@0: return iMessage.Client().GetDesLength(iMessage.Ptr2()); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::ReadData2FromClientL(TDes8& aDes) sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iMessage.ReadL(2, aDes); sl@0: #else sl@0: iMessage.ReadL(iMessage.Ptr2(), aDes); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::ReadData2FromClient(TDes8& aDes) sl@0: { sl@0: TRAPD(err, ReadData2FromClientL(aDes)); sl@0: return err; sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::WriteDataToClientL(const TDesC8& aDes) sl@0: { sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iMessage.WriteL(3, aDes); sl@0: #else sl@0: iMessage.WriteL(iMessage.Ptr3(), aDes); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: } sl@0: sl@0: EXPORT_C TInt TMMFMessage::WriteDataToClient(const TDesC8& aDes) sl@0: { sl@0: TRAPD(err, WriteDataToClientL(aDes)); sl@0: return err; sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::Complete(TInt aReason) sl@0: { sl@0: iMessage.Complete(aReason); sl@0: iAmCompleted = ETrue; sl@0: } sl@0: sl@0: EXPORT_C TBool TMMFMessage::IsCompleted() sl@0: { sl@0: return iAmCompleted; sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::AdoptFileHandleFromClientL(TInt aFsHandleIndex, TInt aFileHandleIndex, RFile& aFile) sl@0: { sl@0: User::LeaveIfError(aFile.AdoptFromClient(RMessage2(iMessage) , aFsHandleIndex, aFileHandleIndex)); sl@0: } sl@0: sl@0: EXPORT_C TMMFMessage::TMMFMessage(const RMmfIpcMessage& aMessage) : sl@0: iMessage(aMessage), sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iFunction(aMessage.Function()), sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: iAmCompleted(EFalse) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C void TMMFMessage::FetchDestinationL() sl@0: { sl@0: // Read the destination info from the client sl@0: TMMFMessageDestinationPckg pckg; sl@0: #ifdef __MMF_USE_IPC_V2__ sl@0: iMessage.ReadL(0, pckg); sl@0: #else sl@0: iMessage.ReadL(iMessage.Ptr0(), pckg); sl@0: #endif // __MMF_USE_IPC_V2__ sl@0: iDestination = pckg(); sl@0: } sl@0: sl@0: sl@0: // CMMFObject sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: @param aInterfaceId sl@0: The UID of the interface provided by this object. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFObject::CMMFObject(TUid aInterfaceId) sl@0: : iHandle(aInterfaceId, KMMFObjectHandleNull) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Destructor. sl@0: */ sl@0: EXPORT_C CMMFObject::~CMMFObject() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Returns the handle of the object. sl@0: sl@0: @return The handle of this object. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C const TMMFMessageDestination& CMMFObject::Handle() sl@0: { sl@0: return iHandle; sl@0: } sl@0: sl@0: /** sl@0: Compares two CMMFObjects by comparing their handles. sl@0: sl@0: @param aOther sl@0: The object to be compared with this object. sl@0: sl@0: @return A boolean indicating if the two CMMFObjects are the same. ETrue if they are the same, sl@0: EFalse if the objects are different. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C TBool CMMFObject::operator==(const CMMFObject& aOther) sl@0: { sl@0: return (iHandle==aOther.iHandle); sl@0: } sl@0: sl@0: void CMMFObject::SetHandle(const TMMFMessageDestination& aNewHandle) sl@0: { sl@0: iHandle = aNewHandle; sl@0: } sl@0: sl@0: sl@0: // CMMFDataSourceHolder sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: @param aDataSource sl@0: The data source to be wrapped. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFDataSourceHolder::CMMFDataSourceHolder(MDataSource& aDataSource) sl@0: : CMMFObject(KUidInterfaceMMFDataSourceHolder), iDataSource(&aDataSource) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Destructor. sl@0: sl@0: Note: This deletes the data source. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFDataSourceHolder::~CMMFDataSourceHolder() sl@0: { sl@0: delete iDataSource; sl@0: } sl@0: sl@0: /** sl@0: Returns a reference to the data source. sl@0: sl@0: @return The data source. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C MDataSource& CMMFDataSourceHolder::DataSource() sl@0: { sl@0: return *iDataSource; sl@0: } sl@0: sl@0: /** sl@0: Implementation of the pure virtual function inherited from CMMFObject. sl@0: sl@0: Passes the request directly to the data source. sl@0: sl@0: @param aMessage sl@0: The message to be handled. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C void CMMFDataSourceHolder::HandleRequest(TMMFMessage& aMessage) sl@0: { sl@0: iDataSource->SourceCustomCommand(aMessage); sl@0: } sl@0: sl@0: sl@0: // CMMFDataSinkHolder sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: @param aDataSink sl@0: The data sink to be wrapped. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFDataSinkHolder::CMMFDataSinkHolder(MDataSink& aDataSink) sl@0: : CMMFObject(KUidInterfaceMMFDataSinkHolder), iDataSink(&aDataSink) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Destructor. sl@0: sl@0: Note: This deletes the data sink. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFDataSinkHolder::~CMMFDataSinkHolder() sl@0: { sl@0: delete iDataSink; sl@0: } sl@0: sl@0: /** sl@0: Returns a reference to the data sink. sl@0: sl@0: @return The data sink. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C MDataSink& CMMFDataSinkHolder::DataSink() sl@0: { sl@0: return *iDataSink; sl@0: } sl@0: sl@0: /** sl@0: Implementation of the pure virtual function inherited from CMMFObject. sl@0: sl@0: Passes the request directly to the data sink. sl@0: sl@0: @param aMessage sl@0: The message to be handled. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C void CMMFDataSinkHolder::HandleRequest(TMMFMessage& aMessage) sl@0: { sl@0: iDataSink->SinkCustomCommand(aMessage); sl@0: } sl@0: sl@0: sl@0: // CMMFCustomCommandParserBase sl@0: EXPORT_C TUid CMMFCustomCommandParserBase::InterfaceId() sl@0: { sl@0: return iInterfaceId; sl@0: } sl@0: sl@0: EXPORT_C CMMFCustomCommandParserBase::~CMMFCustomCommandParserBase() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CMMFCustomCommandParserBase::CMMFCustomCommandParserBase(TUid aInterfaceId) sl@0: : iInterfaceId(aInterfaceId) sl@0: { sl@0: } sl@0: sl@0: sl@0: // CMMFObjectContainer sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFObjectContainer::CMMFObjectContainer() sl@0: { sl@0: iNextObjectHandle = KMMFObjectHandleFirstValid; sl@0: } sl@0: sl@0: /** sl@0: Destructor. sl@0: sl@0: Deletes all objects owned by the container. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C CMMFObjectContainer::~CMMFObjectContainer() sl@0: { sl@0: iObjects.ResetAndDestroy(); sl@0: iObjects.Close(); sl@0: } sl@0: sl@0: /** sl@0: Add an object to the container. sl@0: sl@0: Once the object has been added, its ownership is transferred to the container. sl@0: sl@0: @param aObject sl@0: A reference to the object to be added to the container. sl@0: sl@0: @return An error code indicating if the function call was successful. If the return code is not KErrNone, then sl@0: ownership of the object still remains with the caller. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C TInt CMMFObjectContainer::AddMMFObject(CMMFObject& aObject) sl@0: { sl@0: // Check the object isn't already added sl@0: if (aObject.Handle().DestinationHandle() != KMMFObjectHandleNull) sl@0: return KErrAlreadyExists; sl@0: sl@0: TMMFMessageDestination newHandle(aObject.Handle().InterfaceId(), GenerateObjectHandle()); sl@0: // Set the object's handle sl@0: aObject.SetHandle(newHandle); sl@0: // Append the object to the array sl@0: TInt error = iObjects.Append(&aObject); sl@0: // If error occurred, reset object handle to NULL sl@0: if (error) sl@0: { sl@0: TMMFMessageDestination evenNewerHandle(aObject.Handle().InterfaceId(), KMMFObjectHandleNull); sl@0: aObject.SetHandle(evenNewerHandle); sl@0: } sl@0: return error; sl@0: } sl@0: sl@0: /** sl@0: Removes and destroys an object from the container. sl@0: sl@0: This method ensures that the object is no longer in the container, and that it gets deleted. sl@0: Even if the object is not found in the container's array of objects, it will be deleted. sl@0: sl@0: @param aObject sl@0: A reference to the object to be deleted. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C void CMMFObjectContainer::RemoveAndDestroyMMFObject(CMMFObject& aObject) sl@0: { sl@0: TInt positionOfObjectInArray; sl@0: TInt error = FindMMFObject(aObject, positionOfObjectInArray); sl@0: if (!error) sl@0: { sl@0: iObjects.Remove(positionOfObjectInArray); sl@0: } sl@0: //else, we don't care since we're just saying we'll make sure the object sl@0: //isn't in the array, and that it gets deleted. sl@0: delete (&aObject); sl@0: } sl@0: sl@0: /** sl@0: Removes and destroys all objects from the container. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C void CMMFObjectContainer::DeleteAllObjects() sl@0: { sl@0: iObjects.ResetAndDestroy(); sl@0: } sl@0: sl@0: /** sl@0: Finds an object in the container using a handle. sl@0: sl@0: @param aObjectHandle sl@0: The handle of the object to be located. sl@0: @param aObjectFound sl@0: A reference to a pointer to the object found in the container. sl@0: sl@0: @return An error code indicating if the function call was successful. KErrNone on success, otherwise sl@0: another of the system-wide error codes. sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C TInt CMMFObjectContainer::FindMMFObject(const TMMFMessageDestination& aObjectHandle, CMMFObject*& aObjectFound) sl@0: { sl@0: // Need to find the appropriate object in the array of CMMFObjects sl@0: TInt error = KErrNotFound; sl@0: for (TInt i=0; iHandle() == aObjectHandle) sl@0: { sl@0: error = KErrNone; sl@0: aObjectFound = obj; sl@0: break; sl@0: } sl@0: } sl@0: return error; sl@0: } sl@0: sl@0: const RPointerArray& CMMFObjectContainer::MMFObjects() sl@0: { sl@0: return iObjects; sl@0: } sl@0: sl@0: TInt CMMFObjectContainer::FindMMFObject(const CMMFObject& aObject, TInt& aPositionInArray) sl@0: { sl@0: TInt error = KErrNotFound; sl@0: for (TInt i=0; iConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CLogonMonitor::~CLogonMonitor() sl@0: { sl@0: Cancel(); sl@0: sl@0: if (iScheduler) sl@0: { sl@0: CActiveScheduler::Install(NULL); sl@0: delete iScheduler; sl@0: } sl@0: } sl@0: sl@0: void CLogonMonitor::StartMonitoring(RThread& aThread) sl@0: { sl@0: ASSERT(!iThread); sl@0: sl@0: iThread = &aThread; sl@0: iThread->Logon(iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CLogonMonitor::RunL() sl@0: { sl@0: iServer.Close(); sl@0: iLogonMonitorObserver->ThreadTerminated(); sl@0: } sl@0: sl@0: void CLogonMonitor::DoCancel() sl@0: { sl@0: ASSERT(iThread); sl@0: sl@0: iThread->LogonCancel(iStatus); sl@0: iThread = NULL; sl@0: } sl@0: sl@0: RServer2& CLogonMonitor::Server() sl@0: { sl@0: return iServer; sl@0: } sl@0: sl@0: CMMFControllerExtendedData::CMMFControllerExtendedData() sl@0: : CMMFObject(KUidMMFControllerExtendedDataHolder), iSourceSinkInitData(NULL) sl@0: { sl@0: iClientThreadId = 0; sl@0: iSecureDrmMode = EFalse; sl@0: } sl@0: sl@0: CMMFControllerExtendedData::~CMMFControllerExtendedData() sl@0: { sl@0: ResetSourceSinkInitData(); sl@0: } sl@0: sl@0: void CMMFControllerExtendedData::SetSourceSinkInitData(HBufC8* aSourceSinkInitData) sl@0: { sl@0: ResetSourceSinkInitData(); sl@0: iSourceSinkInitData = aSourceSinkInitData; sl@0: } sl@0: sl@0: HBufC8* CMMFControllerExtendedData::SourceSinkInitData() const sl@0: { sl@0: return iSourceSinkInitData; sl@0: } sl@0: sl@0: void CMMFControllerExtendedData::ResetSourceSinkInitData() sl@0: { sl@0: if (iSourceSinkInitData) sl@0: { sl@0: delete iSourceSinkInitData; sl@0: iSourceSinkInitData = NULL; sl@0: } sl@0: } sl@0: sl@0: void CMMFControllerExtendedData::SetClientThreadId(TThreadId aClientThreadId) sl@0: { sl@0: iClientThreadId = aClientThreadId; sl@0: } sl@0: sl@0: TThreadId CMMFControllerExtendedData::ClientThreadId() const sl@0: { sl@0: return iClientThreadId; sl@0: } sl@0: sl@0: void CMMFControllerExtendedData::SetSecureDrmMode(TBool aSecureDrmMode) sl@0: { sl@0: iSecureDrmMode = aSecureDrmMode; sl@0: } sl@0: sl@0: TBool CMMFControllerExtendedData::SecureDrmMode() const sl@0: { sl@0: return iSecureDrmMode; sl@0: } sl@0: sl@0: void CMMFControllerExtendedData::HandleRequest(TMMFMessage& /*aMessage*/) sl@0: { sl@0: // This function is not suppose to be called. sl@0: #ifdef _DEBUG sl@0: Panic(EPanicBadInvariant); sl@0: #endif sl@0: } sl@0: