--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hwrmhaptics/hapticspluginmanager/src/hwrmhapticsservice.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,723 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Haptic service implementation.
+*
+*/
+
+
+#include <s32mem.h> // RDesReadStream
+#include <hwrmhaptics.h>
+#include <hwrmhapticsobserver.h>
+#include <hwrmlogicalactuators.h>
+#include <hwrmhapticscommands.h> // adaptation interface
+#include <hwrmhapticspacketizer.h>
+
+#include "hwrmhapticsclientserver.h" // panic codes, service ID
+#include "hwrmhapticsserver.h" // default case in ExecuteMessageL
+#include "hwrmhapticsservice.h"
+#include "hwrmhapticspluginmanager.h"
+#include "hwrmhapticsreservationhandler.h"
+#include "hwrmhapticscommondata.h"
+#include "hwrmhapticstrace.h"
+#include "hwrmhapticspluginrequestdata.h"
+
+_LIT( KPanicCategory, "HWRMHapticsSService" );
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CHWRMHapticsService* CHWRMHapticsService::NewL(
+ CHWRMHapticsPluginManager* aPluginHandler,
+ CHWRMHapticsReservationHandler* aReservationHandler,
+ CHWRMHapticsCommonData& aHapticsCommonData,
+ const RMessage2& aMessage )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::NewL()" ) ) );
+
+ CHWRMHapticsService* self =
+ new ( ELeave ) CHWRMHapticsService( aHapticsCommonData, aMessage );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aPluginHandler, aReservationHandler );
+ CleanupStack::Pop( self );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::NewL - return 0x%x" ), self ) );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsService::~CHWRMHapticsService()
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService()" ) ) );
+
+ // Cleanup haptics just in case regular cleanup failed
+ CleanupHaptics();
+
+ if ( iPacketizer )
+ {
+ delete iPacketizer;
+ iPacketizer = NULL;
+ }
+
+ // Complete any pending requests
+ while ( iTransactionList->FirstItem() )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Deleting request %d" ), iTransactionList->FirstItem()->TransactionId() ) );
+ CHWRMHapticsPluginRequestData* data =
+ static_cast<CHWRMHapticsPluginRequestData*>(
+ iTransactionList->RemoveFirstItem() );
+
+ if ( data->RequestMessage().Handle() )
+ {
+ // Check that this request is not first one of a split request
+ if ( !data->CommandSplit() ||
+ !CheckForMessage(data->RequestMessage().Handle()) )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Canceling pending message" ) ) );
+ data->RequestMessage().Complete( KErrCancel );
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Split request, not canceling message yet" ) ) );
+ }
+ }
+
+ TRAPD ( err, iPluginManager->CancelCommandL( data->TransactionId() ) );
+
+ if ( err != KErrNone )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Cancelling Command (transid: %d) failed: %d" ), data->TransactionId(), err ) );
+ }
+
+ delete data;
+ }
+
+ // Destroy transaction list
+ delete iTransactionList;
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Handles Haptics requests.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CHWRMHapticsService::ExecuteMessageL(
+ const RMessage2& aMessage )
+ {
+ COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_EXECUTEMESSAGEL 1" ) ) );
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL(0x%x)" ), aMessage.Function() ) );
+ __ASSERT_ALWAYS( iPluginManager,
+ User::Panic( KPanicCategory, EPanicBadHandle ) );
+ __ASSERT_ALWAYS( iReservationHandler,
+ User::Panic( KPanicCategory, EPanicBadHandle ) );
+
+ if ( aMessage.IsNull() )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - NULL message!" ) ) );
+ User::Leave( KErrBadHandle );
+ }
+
+ TBool completeMessage( EFalse );
+
+ switch( aMessage.Function() )
+ {
+ case RMessage2::EDisConnect:
+ {
+ // send command to close actuator, if actuator has
+ // been opened (i.e. packetizer exists)
+ if ( iPacketizer )
+ {
+ SendMsgToPluginManagerL( aMessage );
+ }
+
+ CleanupHaptics();
+ break;
+ }
+ case EHWRMHaptics:
+ case EHWRMHapticsBridgeCommand: // flow through
+ {
+ // send haptics message
+ SendMsgToPluginManagerL( aMessage );
+ break;
+ }
+ case EHWRMHapticsPlayEffect:
+ {
+ // check if suspended
+ if ( iSuspended )
+ {
+ // no effect playing, just complete the message
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - Haptics suspended; Play not executed." ) ) );
+ aMessage.Complete( KErrNone );
+ }
+ else if ( iReservationHandler->IsReserved( this ) &&
+ iReservationHandler->ReservedPriorityHigher( iSid ) )
+ {
+ // haptics has not been reserved for some other client with
+ // higher (or equal) priority, notify caller with an error code
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - Haptics Reserved!" ) ) );
+ User::Leave( KErrInUse );
+ }
+ else
+ {
+ // send play effect -command forwards to plugin manager
+ SendMsgToPluginManagerL( aMessage );
+ }
+
+ break;
+ }
+ case EHWRMHapticsOpenActuator:
+ {
+ // get actuator type
+ THWRMLogicalActuators actuator =
+ static_cast<THWRMLogicalActuators>( aMessage.Int2() );
+
+ // open the plugin to send the message to appropriate actuator;
+ TBool created = iPluginManager->OpenPluginToActuatorL( actuator );
+
+ // reset packetizer instance
+ if ( iPacketizer )
+ {
+ delete iPacketizer;
+ iPacketizer = NULL;
+ }
+
+ iPacketizer = CHWRMHapticsPacketizer::NewL( actuator );
+
+ // if plugin was not created, it already exists. Inform client
+ // about the last status of the plugin.
+ if ( !created )
+ {
+ iHapticsCommonData.NotifyActuatorEvent( actuator, iSession );
+ }
+
+ // send the open device message;
+ SendMsgToPluginManagerL( aMessage );
+
+ break;
+ }
+ case EHWRMHapticsCleanup:
+ {
+ CleanupHaptics();
+
+ // complete as there is no ProcessResponse for this
+ aMessage.Complete( KErrNone );
+ break;
+ }
+ case EHWRMHapticsReserve:
+ {
+ COMPONENT_TRACE( ( _L("CHWRMHapticsService::ExecuteMessageL - EHWRMReserveHaptics") ) );
+
+ ReserveHapticsL( aMessage );
+
+ // Since using dummy messages for freeze state restores, need complete always.
+ completeMessage = ETrue;
+
+ break;
+ }
+ case EHWRMHapticsRelease:
+ {
+ COMPONENT_TRACE( ( _L("CHWRMHapticsService::ExecuteMessageL - EHWRMReleaseHaptics") ) );
+
+ ReleaseHaptics();
+
+ // Since using dummy messages for default state restores, need complete always.
+ completeMessage = ETrue;
+
+ break;
+ }
+ case EHWRMHapticsSuppActuators:
+ {
+ // get the supported logical actuator types from
+ // the plugin manager
+ TUint32 types = iPluginManager->GetSupportedActuatorInfo();
+
+ // write the supported types to aMessage
+ TPckg<TUint32> actuatorInfoRetPckg( types );
+ TInt err = aMessage.Write( 0, actuatorInfoRetPckg, 0 );
+
+ // complete the message
+ aMessage.Complete( err );
+ break;
+ }
+
+ case EHWRMHapticsSetLicenseProp:
+ {
+ // The license key is set automatically if it is given as empty
+ // string and if LicenseAutoSettingAllowed check succeeds.
+ // The actual license key setting occures in lower layer,
+ // here it is enough to create new command message.
+
+ // check license key length
+ if ( aMessage.Int1() == 0 )
+ {
+ // check if automatic license key setting is allowed
+ // for the calling client
+ if ( iPluginManager->LicenseAutoSettingAllowed( aMessage ) &&
+ iPacketizer )
+ {
+ // create buffer for new request data
+ HWRMHapticsCommand::RHWRMHapticsReqData reqData;
+
+ // client is allowed to get automatic license key setting,
+ // create new command package
+ TInt err = iPacketizer->EncSetPlatformLicenseKeyReq(
+ iPacketizer->DeviceHandle(),
+ reqData );
+
+ // write new request data to request message, if creating
+ // it succeeded
+ if ( err == KErrNone )
+ {
+ aMessage.Write( 0, reqData, 0 );
+ }
+
+ reqData.Close();
+ }
+ }
+
+ // send message to plugin manager
+ SendMsgToPluginManagerL( aMessage );
+ break;
+ }
+ case EHWRMHapticsStatusNotification:
+ {
+ // store the message. It will be completed only
+ // when the haptics/actuator status for this client changes
+ // (thus the command should always be asynchronous on the
+ // client side)
+ iHapticsCommonData.AddStatusObserver( aMessage );
+
+ break;
+ }
+ case EHWRMHapticsGetStatus:
+ {
+ // get the current status value for this client
+ MHWRMHapticsObserver::THWRMHapticsStatus status =
+ iHapticsCommonData.CurrentStatus( aMessage.Session() );
+
+ // write the status to message
+ TPckg<MHWRMHapticsObserver::THWRMHapticsStatus> statusPckg( status );
+ TInt err = aMessage.Write( 0, statusPckg, 0 );
+
+ // complete message
+ aMessage.Complete( err );
+
+ break;
+ }
+ default:
+ {
+ // Cannot identify the message, panic the client
+ aMessage.Panic( KPanicCategory, EPanicIllegalFunction );
+ break;
+ }
+
+ }//switch
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - return 0x%x" ), completeMessage ) );
+ COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_EXECUTEMESSAGEL 0" ) ) );
+
+ return completeMessage;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles Haptics requests responses.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ProcessResponseL( TInt aCommandId,
+ TUint8 aTransId,
+ const TDesC8& aData )
+ {
+ COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_PROCESSRESPONSEL 1" ) ) );
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL(0x%x, 0x%x, <data>)" ), aCommandId, aTransId ) );
+
+ if( aCommandId == HWRMHapticsCommand::EHapticsCmdId )
+ {
+ TInt contextErr = CompleteRequestL( aTransId, aData );
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL - CompleteRequestL ret = %d" ), contextErr ) );
+
+ // Leave if there is error in context
+ User::LeaveIfError( contextErr );
+ }
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL - return" ) ) );
+ COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_PROCESSRESPONSEL 0" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Suspends haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::SuspendResource()
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SuspendSubResource()" ) ) );
+
+ iSuspended = ETrue;
+
+ // notify client that haptics for it has been suspended
+ iHapticsCommonData.NotifyStatus(
+ MHWRMHapticsObserver::EHWRMHapticsStatusSuspended, iSession );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SuspendSubResource - return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Resumes haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ResumeResource()
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ResumeSubResource()" ) ) );
+
+ iSuspended = EFalse;
+
+ // notify client that haptics for it is now available
+ iHapticsCommonData.NotifyStatus(
+ MHWRMHapticsObserver::EHWRMHapticsStatusAvailable, iSession );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ResumeSubResource - return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels outstanding request by completing the RMessage2 and removing data
+// from transaction list.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::CancelRequest( TUint8 aTransId )
+ {
+ CHWRMHapticsPluginRequestData* data =
+ static_cast<CHWRMHapticsPluginRequestData*>(
+ iTransactionList->FindTransaction( aTransId, ETrue ) );
+
+ if ( data && data->RequestMessage().Handle() )
+ {
+ data->RequestMessage().Complete( KErrTimedOut );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsService::CHWRMHapticsService(
+ CHWRMHapticsCommonData& aHapticsCommonData,
+ const RMessage2& aMessage )
+ : iHapticsCommonData( aHapticsCommonData ), iSid( aMessage.SecureId() ),
+ iSession( aMessage.Session() )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CHWRMHapticsService()" ) ) );
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CHWRMHapticsService - return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ConstructL(
+ CHWRMHapticsPluginManager* aPluginManager,
+ CHWRMHapticsReservationHandler* aReservationHandler )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ConstructL(0x%x)" ), aPluginManager ) );
+
+ if ( !aPluginManager )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ iPluginManager = aPluginManager;
+ iReservationHandler = aReservationHandler;
+
+ iTransactionList = new( ELeave ) CHWRMHapticsPluginTransactionList();
+
+ // set this session to the common data for storing the client
+ // specific status information
+ iHapticsCommonData.AddSessionL( iSession );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ConstructL - return " ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Completes request. Subclass calls this from ProcessResponseL
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsService::CompleteRequestL( TUint8 aTransId,
+ const TDesC8& aData )
+ {
+ // return value
+ TInt contextErr( KErrNone );
+
+ // find transaction data
+ CHWRMHapticsPluginRequestData* data =
+ static_cast<CHWRMHapticsPluginRequestData*>(
+ iTransactionList->FindTransaction( aTransId, ETrue ) );
+
+ CleanupStack::PushL( data );
+
+ if ( data && data->RequestMessage().Handle() )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - iRequestMessage.Handle() ok." ) ) );
+
+ // data storage for the protocol version and error code
+ CHWRMHapticsRespData* respData =
+ CHWRMHapticsRespData::NewLC( KErrNone, KNullDesC8 );
+
+ // internalize data using stream reader
+ RDesReadStream reader( aData );
+ CleanupClosePushL( reader );
+ reader >> *respData;
+ CleanupStack::PopAndDestroy( &reader );
+
+ // status filled in message decoding
+ TInt vibeStatus = KErrNone;
+
+ // decode data, if no error
+ if ( respData->ErrorCode() == KErrNone )
+ {
+ if ( data->RequestMessage().Function() == EHWRMHapticsBridgeCommand )
+ {
+ // bridge command handling
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequest - inside EHWRMHapticsBridgeCommand case:" ) ) );
+ DATADUMP_TRACE( _L("CHWRMHapticsService::CompleteRequest - (EHWRMHapticsBridgeCommand case) - data dump "), respData->Data() );
+
+ // write error code and response data
+ TPckg<TInt> vibeDummyCodePckg( KErrNone );
+ data->RequestMessage().Write( 1, vibeDummyCodePckg, 0 );
+ data->RequestMessage().Write( 2, respData->Data(), 0 );
+ }
+ else
+ {
+ // decode the message and send it to the callback service
+ CDesC8ArraySeg* decodeArray = NULL;
+ TRAPD( err, decodeArray = iPacketizer->DecodeMessageL(
+ respData->Data(), vibeStatus ) );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - Return msg decoding, err = %d" ), err ) );
+
+ for ( TInt i = 0; err == KErrNone &&
+ i < decodeArray->MdcaCount(); ++i )
+ {
+ // write data back to client
+ err = data->RequestMessage().Write(
+ KHapticsMessageResponseArgsOffset + i,
+ decodeArray->MdcaPoint( i ), 0 );
+ }
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - Data writing err = %d" ), err ) );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( respData );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - calling iRequestMessage.Complete()") ) ) ;
+ data->RequestMessage().Complete( vibeStatus );
+ }
+ else
+ {
+ // transaction data not found
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequest - No transaction data found!" ) ) );
+ contextErr = KErrBadHandle;
+ }
+
+ // cleanup data
+ CleanupStack::PopAndDestroy( data );
+
+ return contextErr;
+ }
+
+// ---------------------------------------------------------------------------
+// Checks transaction list if specified message is in any transaction.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsService::CheckForMessage( TInt aHandle )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CheckForMessage - Checking for message: 0x%x" ), aHandle ) );
+
+ CHWRMHapticsPluginRequestData* data =
+ static_cast<CHWRMHapticsPluginRequestData*>(
+ iTransactionList->FirstItem() );
+
+ TBool retval( EFalse );
+
+ while ( !retval && data )
+ {
+ if ( data->RequestMessage().Handle() == aHandle )
+ {
+ retval = ETrue;
+ }
+
+ data = static_cast<CHWRMHapticsPluginRequestData*>( data->NextItem() );
+ }
+
+ return retval;
+ }
+
+// ---------------------------------------------------------------------------
+// Cleans up haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::CleanupHaptics()
+ {
+ if ( !iCleanupDone )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CleanupHaptics()" ) ) );
+
+ // release haptics in case this client has made the reservation
+ ReleaseHaptics();
+
+ iSuspended = EFalse;
+
+ // remove priority of the client from reservation handler
+ iReservationHandler->RemovePriority( iSid );
+
+ // remove this session from the common data
+ iHapticsCommonData.RemoveSession( iSession );
+
+ iCleanupDone = ETrue;
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CleanupHaptics - return" ) ) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Handles Haptics requests.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::SendMsgToPluginManagerL( const RMessage2& aMessage )
+ {
+ // Create new data (TransId is updated later, commandId is not important)
+ CHWRMHapticsPluginRequestData* data( NULL );
+ if ( aMessage.Function() == RMessage2::EDisConnect )
+ {
+ data = new ( ELeave )
+ CHWRMHapticsPluginRequestData( RMessage2(), 0, 0, EFalse );
+ }
+ else
+ {
+ data = new ( ELeave )
+ CHWRMHapticsPluginRequestData( aMessage, 0, 0, EFalse );
+ }
+
+ CleanupStack::PushL( data );
+
+ if ( aMessage.Function() == RMessage2::EDisConnect )
+ {
+ // form from Disconnect message actuator closing request
+ RBuf8 closeBuf;
+ CleanupClosePushL( closeBuf );
+
+ User::LeaveIfError( iPacketizer->EncCloseDeviceReq(
+ iPacketizer->DeviceHandle(), closeBuf ) );
+
+ HBufC8* reqData = closeBuf.AllocL();
+
+ CleanupStack::PopAndDestroy( &closeBuf );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SendMsgToPluginManagerL - Disconnect actuator") ) );
+
+ // created buffer is deleted in the request data object
+ data->SetRequestData( reqData );
+
+ // command to plugin manager
+ TUint8 transId = iPluginManager->ProcessCommandL(
+ HWRMHapticsCommand::EHapticsCmdId,
+ *reqData, this );
+ data->SetTransactionId( transId );
+ }
+ else
+ {
+ // read message data into a heap buffer
+ HBufC8* reqData = HBufC8::NewL( aMessage.GetDesLength( 0 ) );
+ TPtr8 dataPtr = reqData->Des();
+ TInt err = aMessage.Read( 0, dataPtr, 0 );
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SendMsgToPluginManagerL - aMessageRead err = %d"), err ) );
+
+ // created buffer is deleted in the request data object
+ data->SetRequestData( reqData );
+
+ // command to plugin manager
+ TUint8 transId = iPluginManager->ProcessCommandL(
+ HWRMHapticsCommand::EHapticsCmdId,
+ *reqData, this);
+ data->SetTransactionId( transId );
+ }
+
+ // data still needed, do not destroy, just pop
+ CleanupStack::Pop( data );
+
+ // Add data to list
+ iTransactionList->AddTransaction( data );
+ }
+
+// ---------------------------------------------------------------------------
+// Reserves haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ReserveHapticsL( const RMessage2& aMessage )
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReserveHapticsL()" ) ) );
+
+ // Reserve the haptics
+ TBool noCoeEnv = aMessage.Int0();
+ TBool suspended = iReservationHandler->ReserveL( iSid, noCoeEnv, this );
+
+ // if reservation became the affective reservation, inform all other
+ // clients that haptics is reserved
+ if ( !suspended )
+ {
+ iHapticsCommonData.BroadcastStatus(
+ MHWRMHapticsObserver::EHWRMHapticsStatusReserved, iSession );
+ }
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReserveHapticsL() return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Releases haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ReleaseHaptics()
+ {
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReleaseHaptics()" ) ) );
+
+ // get info is haptics currently reserved for this client
+ TBool activeReservation = iReservationHandler->ActiveReservation( this );
+
+ // release reservation (removes, if this has a reservation)
+ TBool reserved = iReservationHandler->Release( this );
+
+ // if haptics is still reserved for another client, notify client
+ if ( reserved )
+ {
+ iHapticsCommonData.NotifyStatus(
+ MHWRMHapticsObserver::EHWRMHapticsStatusReserved, iSession );
+ }
+ else if ( activeReservation )
+ {
+ // haptics was reserved for this client, but there are no more
+ // reservations --> inform all clients, which have been blocked
+ iHapticsCommonData.BroadcastStatus(
+ MHWRMHapticsObserver::EHWRMHapticsStatusAvailable, iSession );
+ }
+
+ COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReleaseHaptics() return" ) ) );
+ }
+
+
+// End of File