williamr@2: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@2: // All rights reserved. williamr@2: // This component and the accompanying materials are made available williamr@2: // under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members williamr@2: // which accompanies this distribution, and is available williamr@2: // at the URL "http://www.symbianfoundation.org/legal/licencesv10.html". williamr@2: // williamr@2: // Initial Contributors: williamr@2: // Nokia Corporation - initial contribution. williamr@2: // williamr@2: // Contributors: williamr@2: // williamr@2: // Description: williamr@2: // williamr@2: williamr@2: #ifndef __MMFSUBTHREADBASE_H__ williamr@2: #define __MMFSUBTHREADBASE_H__ williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: /** williamr@2: @publishedAll williamr@2: @released williamr@2: williamr@2: Defines the maximum number of event messages that will be held server-side williamr@2: while waiting for the client to request the next message in the queue. williamr@2: */ williamr@2: static const TInt KMMFSubThreadMaxCachedMessages = 4; williamr@2: williamr@2: /** williamr@2: @publishedAll williamr@2: @released williamr@2: williamr@2: Defines the maximum heap size paramater used when creating the datapath subthread. williamr@2: */ williamr@2: static const TInt KMMFSubThreadMaxHeapSize = 0x100000;//1MB williamr@2: williamr@2: williamr@2: /** williamr@2: @publishedAll williamr@2: @released williamr@2: williamr@2: ITC message ID's used by the client to send commands to the datapath subthread server. williamr@2: */ williamr@2: enum TMMFSubThreadMessageIds williamr@2: { williamr@2: /** williamr@2: Message ID for message to request next event from the sub thread server. williamr@2: */ williamr@2: EMMFSubThreadReceiveEvents, williamr@2: /** williamr@2: Message ID for message to cancel a previous request to receive an event from the sub thread server. williamr@2: */ williamr@2: EMMFSubThreadCancelReceiveEvents, williamr@2: /** williamr@2: Message ID for message to request that the sub thread shuts itself down. williamr@2: */ williamr@2: EMMFSubThreadShutdown, williamr@2: /** williamr@2: Message ID for message to request the datapath subthread load a datapath. williamr@2: */ williamr@2: EMMFDataPathProxyLoadDataPathBy, williamr@2: /** williamr@2: Message ID for message to request the datapath subthread load a datapath with a specified williamr@2: media ID. williamr@2: */ williamr@2: EMMFDataPathProxyLoadDataPathByMediaId, williamr@2: /** williamr@2: Message ID for message to request the datapath subthread load a datapath with a specified codec. williamr@2: */ williamr@2: EMMFDataPathProxyLoadDataPathByCodecUid, williamr@2: /** williamr@2: Message ID for message to request the datapath subthread load a datapath with a specified media williamr@2: ID and codec. williamr@2: */ williamr@2: EMMFDataPathProxyLoadDataPathByMediaIdCodecUid, williamr@2: /** williamr@2: Message ID for message to add a data source to the datapath. williamr@2: */ williamr@2: EMMFDataPathProxyAddDataSource, williamr@2: /** williamr@2: Message ID for message to add a data sink to the datapath. williamr@2: */ williamr@2: EMMFDataPathProxyAddDataSink, williamr@2: /** williamr@2: Message ID for message to prime the datapath. williamr@2: */ williamr@2: EMMFDataPathProxyPrime, williamr@2: /** williamr@2: Message ID for message to start the datapath playing. williamr@2: */ williamr@2: EMMFDataPathProxyPlay, williamr@2: /** williamr@2: Message ID for message to pause the datapath. williamr@2: */ williamr@2: EMMFDataPathProxyPause, williamr@2: /** williamr@2: Message ID for message to stop the datapath. williamr@2: */ williamr@2: EMMFDataPathProxyStop, williamr@2: /** williamr@2: Message ID for message to get the datapath's position. williamr@2: */ williamr@2: EMMFDataPathProxyGetPosition, williamr@2: /** williamr@2: Message ID for message to set the datapath's position. williamr@2: */ williamr@2: EMMFDataPathProxySetPosition, williamr@2: /** williamr@2: Message ID for message to set the datapath's play window. williamr@2: */ williamr@2: EMMFDataPathProxySetPlayWindow, williamr@2: /** williamr@2: Message ID for message to clear the datapath's play window. williamr@2: */ williamr@2: EMMFDataPathProxyClearPlayWindow, williamr@2: /** williamr@2: Message ID for message to get the datapath's current state. williamr@2: */ williamr@2: EMMFDataPathProxyState, williamr@2: /** williamr@2: Unused. williamr@2: */ williamr@2: EMMFAudioPolicyProxyGetAudioPolicy williamr@2: }; williamr@2: williamr@2: williamr@2: class RMMFSubThreadBase; // declared here. williamr@2: /** williamr@2: @internalTechnology williamr@2: williamr@2: Base class for clients to MMF sub threads. williamr@2: Provides functionality to start the sub thread and transmit events from subthread to main thread. williamr@2: */ williamr@2: NONSHARABLE_CLASS( RMMFSubThreadBase ): public RMmfSessionBase williamr@2: { williamr@2: public: williamr@2: RMMFSubThreadBase(TTimeIntervalMicroSeconds32 aShutdownTimeout) : iShutdownTimeout(aShutdownTimeout) {}; williamr@2: /** williamr@2: Returns the id of the subthread, allowing a client to logon to the thread to receive notification of its death. williamr@2: */ williamr@2: TThreadId SubThreadId() {return iSubThread.Id();}; williamr@2: /** williamr@2: Allows a client to receive events from the subthread. williamr@2: */ williamr@2: IMPORT_C void ReceiveEvents(TMMFEventPckg& aEventPckg, TRequestStatus& aStatus); williamr@2: IMPORT_C TInt CancelReceiveEvents(); williamr@2: /** williamr@2: Signal to the subthread to exit. williamr@2: Note: This function will not return until the subthread has exited, or a timeout has occurred. williamr@2: */ williamr@2: IMPORT_C void Shutdown(); williamr@2: protected: williamr@2: /** williamr@2: Should be called by derived classes to start the subthread. williamr@2: */ williamr@2: TInt DoCreateSubThread(const TDesC& aName, TThreadFunction aFunction, TBool aUseNewHeap = EFalse); williamr@2: void Panic(TMMFSubThreadPanicCode aPanicCode); williamr@2: protected: williamr@2: RThread iSubThread; williamr@2: TTimeIntervalMicroSeconds32 iShutdownTimeout; williamr@2: private: williamr@2: /** williamr@2: Used to determine the success of a logon. If the status is not pending, the logon has failed williamr@2: and the thread should be closed. williamr@2: */ williamr@2: TRequestStatus iLogonStatus; williamr@2: /** williamr@2: This member is internal and not intended for use. williamr@2: */ williamr@2: TInt iReserved1; williamr@2: TInt iReserved2; williamr@2: TInt iReserved3; williamr@2: }; williamr@2: williamr@2: /** williamr@2: @internalTechnology williamr@2: williamr@2: Used to Kill the subthread either immediately or after a timeout. williamr@2: Used by the subthread on startup to prevent orphaning if no sessions are created to it. williamr@2: */ williamr@2: class CMMFSubThreadShutdown : public CTimer williamr@2: { williamr@2: enum {EMMFSubThreadShutdownDelay=1000000}; // 1s williamr@2: public: williamr@2: static CMMFSubThreadShutdown* NewL(); williamr@2: CMMFSubThreadShutdown(); williamr@2: void ConstructL(); williamr@2: void Start(); williamr@2: void ShutdownNow(); williamr@2: private: williamr@2: void RunL(); williamr@2: }; williamr@2: williamr@2: /** williamr@2: @internalTechnology williamr@2: williamr@2: Subthread server base class. williamr@2: Provides session counting and will kill the subthread immediately when the session count reaches zero. williamr@2: Starts the shutdown timer on construction to prevent orphaning if no sessions are created. williamr@2: */ williamr@2: class CMMFSubThreadServer : public CMmfIpcServer williamr@2: { williamr@2: public: williamr@2: virtual ~CMMFSubThreadServer(); williamr@2: virtual void SessionCreated(); williamr@2: virtual TInt RunError(TInt aError); williamr@2: virtual void ShutdownNow(); williamr@2: protected: williamr@2: virtual CMmfIpcSession* NewSessionL(const TVersion& aVersion) const = 0; williamr@2: CMMFSubThreadServer(TInt aPriority); williamr@2: void ConstructL(); williamr@2: private: williamr@2: CMMFSubThreadShutdown* iShutdownTimer; williamr@2: }; williamr@2: williamr@2: /** williamr@2: @internalTechnology williamr@2: williamr@2: Used to hold on to an RMessage so we can complete it asynchronously to send an event to the main thread. williamr@2: */ williamr@2: class CMMFSubThreadEventReceiver : public CBase williamr@2: { williamr@2: public: williamr@2: static CMMFSubThreadEventReceiver* NewL(const RMmfIpcMessage& aMessage); williamr@2: ~CMMFSubThreadEventReceiver(); williamr@2: void SendEvent(const TMMFEvent& aEvent); williamr@2: private: williamr@2: CMMFSubThreadEventReceiver(const RMmfIpcMessage& aMessage); williamr@2: private: williamr@2: RMmfIpcMessage iMessage; williamr@2: TBool iNeedToCompleteMessage; williamr@2: }; williamr@2: williamr@2: /** williamr@2: @internalTechnology williamr@2: williamr@2: Subthread session base class. williamr@2: Derived classes must implement the ServiceL() method. williamr@2: */ williamr@2: class CMMFSubThreadSession : public CMmfIpcSession, public MAsyncEventHandler williamr@2: { williamr@2: public: williamr@2: virtual ~CMMFSubThreadSession(); williamr@2: void CreateL(const CMmfIpcServer& aServer); williamr@2: virtual void ServiceL(const RMmfIpcMessage& aMessage) = 0; williamr@2: //from MAsyncEventHandler williamr@2: TInt SendEventToClient(const TMMFEvent& aEvent); williamr@2: protected: williamr@2: CMMFSubThreadSession() {}; williamr@2: TBool ReceiveEventsL(const RMmfIpcMessage& aMessage); williamr@2: TBool CancelReceiveEvents(); williamr@2: TBool ShutDown(); williamr@2: protected: williamr@2: CMMFSubThreadServer* iServer; williamr@2: private: williamr@2: CMMFSubThreadEventReceiver* iEventReceiver; williamr@2: RArray iEvents; williamr@2: }; williamr@2: williamr@2: williamr@2: williamr@2: #endif