--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/resourcemgmt/hwresourcesmgr/server/src/HWRMVibraService.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1288 @@
+// Copyright (c) 2006-2009 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:
+//
+
+
+
+
+// INCLUDE FILES
+#include "HWRMServer.h"
+#include "HWRMVibraClientServer.h"
+#include "HWRMService.h"
+#include "HWRMVibraService.h"
+#include "HWRMVibraCommands.h"
+#include "HWRMPluginHandler.h"
+#include "HWRMtrace.h"
+#include "HWRMVibraCommonData.h"
+#include "HWRMVibra.h"
+#include "HWRMReservationHandler.h"
+#include "HWRMPrivateCRKeys.h"
+#include "HWRMDomainPSKeys.h"
+#include "HWRMPrivatePSKeys.h"
+#include "HWRMVibraCommonService.h"
+
+
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+// None
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+_LIT( KPanicCategory, "HWRMVibraService" );
+
+const TInt KHWRMVibraMaxDurationInMicroseconds = KHWRMVibraMaxDuration * 1000;
+
+const TInt KHWRMVibraTimerID = KMaxTInt;
+const TInt KHWRMVibraNoTimer = KMinTInt;
+
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::CHWRMVibraService
+// C++ constructor
+// -----------------------------------------------------------------------------
+//
+CHWRMVibraService::CHWRMVibraService(CHWRMVibraCommonService& aCommonService,
+ CHWRMVibraCommonData& aVibraCommonData,
+ TBool aPrivilegedClient)
+ : iVibraCommonData(aVibraCommonData),
+ iPrivilegedClient(aPrivilegedClient),
+ iStateSetAfterReservation(EFalse),
+ iCommonService(aCommonService),
+ iSid(0),
+ iActiveTimerId(KHWRMVibraTimerID)
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CHWRMVibraService()" ) );
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CHWRMVibraService - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ConstructL(CHWRMPluginHandler* aPluginHandler,
+ CHWRMReservationHandler* aReservationHandler)
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ConstructL(0x%x)" ), aPluginHandler );
+
+ BaseConstructL(aPluginHandler, aReservationHandler);
+
+ // Create vibra timer with special identifier.
+ iVibraTimer = CHWRMGenericTimer::NewL(*this, iVibraCommonData.MaximumOnTime(), KHWRMVibraTimerID);
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ConstructL - return " ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CHWRMVibraService* CHWRMVibraService::NewL(CHWRMPluginHandler* aPluginHandler,
+ CHWRMReservationHandler* aReservationHandler,
+ CHWRMVibraCommonService& aCommonService,
+ CHWRMVibraCommonData& aVibraCommonData,
+ TBool aPrivilegedClient)
+ {
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::NewL(0x%x, aPrivilegedClient: 0x%x)" ), aPluginHandler, aPrivilegedClient );
+
+ CHWRMVibraService* self = new( ELeave ) CHWRMVibraService(aCommonService, aVibraCommonData, aPrivilegedClient);
+
+ CleanupStack::PushL( self );
+ self->ConstructL(aPluginHandler, aReservationHandler);
+ CleanupStack::Pop();
+
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::NewL - return 0x%x" ), self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------
+//
+CHWRMVibraService::~CHWRMVibraService()
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::~CHWRMVibraService()" ) );
+
+ // Cleanup vibra just in case regular cleanup failed
+ CleanupVibra();
+
+ // Delete timer
+ if (iVibraTimer)
+ {
+ iVibraTimer->Cancel();
+ delete iVibraTimer;
+ }
+
+ ReleasePulseData();
+
+ // Base class cleanup
+ BaseDestruct();
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::~CHWRMVibraService - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ReleasePulseData
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ReleasePulseData()
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ReleasePulseData(), count %d" ), iPulseData.Count() );
+
+ iPulseData.ResetAndDestroy();
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ReleasePulseData - return" ) );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::CleanupVibra
+// Cleans up vibra.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::CleanupVibra()
+ {
+ if ( !iCleanupDone )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra()" ) );
+ TInt unreserved(0x0);
+
+ // If still reserved, release
+ if ( iReserved )
+ {
+ unreserved = iReservationHandler->Release(this, KHWRMAllSubResources);
+ iReserved = EFalse;
+ iSuspended = EFalse;
+ }
+ else
+ {
+ unreserved = iReservationHandler->GetUnreservedTargets();
+ }
+
+ COMPONENT_TRACE3(_L("HWRM Server - CHWRMVibraService::CleanupVibra - Vibra status: %d, reservation status: %d"), iLastStatus, unreserved );
+
+ // If this session has set vibra to vibrate and vibra is unreserved, stop it.
+ if ( unreserved && iLastStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing cleanup
+ TRAPD(err, StopVibraL(dummy, EFalse, ETrue));
+ if ( err != KErrNone )
+ {
+ COMPONENT_TRACE2(_L("HWRM Server - CHWRMVibraService::CleanupVibra - Stopping vibra failed: %d"), err );
+ }
+ else
+ {
+ // Since there will be no ProcessResponse for this one, publish the status now
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusStopped, iPrivilegedClient);
+ }
+ }
+
+ // Make sure client requests get cleared if not via StopVibraL
+ if( iCommonService.HasData( this ) )
+ {
+ iCommonService.ResetClientData( this );
+ }
+
+ iCleanupDone = ETrue;
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra - return" ) );
+ }
+ else
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra - Already cleaned up" ) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ForceVibraStop
+// Stops vibra.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ForceVibraStop()
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ForceVibraStop()" ) );
+
+ RMessage2 dummy;
+ TRAP_IGNORE(StopVibraL(dummy, ETrue));
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ForceVibraStop - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ExecuteMessageL
+// Handles Vibra requests.
+// -----------------------------------------------------------------------------
+//
+TBool CHWRMVibraService::ExecuteMessageL( const RMessage2& aMessage )
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ExecuteMessageL(0x%x)" ), aMessage.Function() );
+
+ __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
+ __ASSERT_ALWAYS(iReservationHandler, User::Panic(KPanicCategory, EPanicBadHandle));
+
+ if ( aMessage.IsNull() )
+ {
+ User::Leave(KErrBadHandle);
+ }
+
+ // All messages are by default asynchronous because of the nature of the plugin API
+ TBool completeMessage(EFalse);
+ TInt function( aMessage.Function() );
+
+ // Retrieve client sid
+ iSid = aMessage.SecureId();
+
+ switch ( function )
+ {
+ case EHWRMStartVibraDefaultIntensity:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStartVibraDefaultIntensity") );
+
+ StartVibraL( aMessage.Int0() * 1000, KUseDefaultIntensity, aMessage);
+
+ break;
+ }
+ case EHWRMStartVibra:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStartVibra") );
+
+ StartVibraL(aMessage.Int0() * 1000, aMessage.Int1(), aMessage);
+
+ break;
+ }
+ case EHWRMPulseVibraDefault:
+ case EHWRMPulseVibraDefaultIntensity:
+ case EHWRMPulseVibra:
+ {
+ // First of all check whether pulse request allowed by this client.
+ if ( !iCommonService.VibraPulseAllowed( aMessage.SecureId() ) )
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+ TInt duration( iVibraCommonData.FeedbackDefaultDuration() * 1000 );
+ TInt intensity( iVibraCommonData.FeedbackDefaultIntensity() );
+
+ if( function == EHWRMPulseVibraDefault )
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibraDefault") );
+ }
+ else if( function == EHWRMPulseVibraDefaultIntensity )
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibraDefaultIntensity") );
+ duration = aMessage.Int0() * 1000;
+ }
+ else
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibra") );
+ duration = aMessage.Int0() * 1000;
+ intensity = aMessage.Int1();
+ }
+
+ COMPONENT_TRACE2(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - pulse supported %d"),
+ iVibraCommonData.FeedbackPulseSupported() );
+
+ // If there is active reservation and vibration ongoing by a higher priority client,
+ // pulse request is not allowed. In all other circumstances either pulse or start
+ // command is sent to plugin.
+ if ( iReservationHandler->IsReserved(this, KHWRMAllSubResources) &&
+ iCommonService.ExecutingPriorityHigher( aMessage.SecureId() ) )
+ {
+ User::Leave(KErrInUse);
+ }
+
+ if( iVibraCommonData.FeedbackPulseSupported() )
+ {
+ // It is plugin or underlying software responsibility to generate pulse start/stop
+ // and continue ongoing vibration if such exists.
+ PulseVibraL( duration, intensity, aMessage);
+ }
+ else
+ {
+ // Request another vibration by lefting current timer if such exist intact
+ // and creating new timer for this pulse request.
+ StartVibraL( duration, intensity, aMessage, EFalse, ETrue);
+ }
+
+ break;
+ }
+ case EHWRMStopVibra:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStopVibra") );
+
+ StopVibraL(aMessage);
+ break;
+ }
+ case EHWRMReserveVibra:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMReserveVibra") );
+
+ // Reserve whole vibra. If returned mask is non-zero, reservation was done in suspended mode.
+ iSuspended = (iReservationHandler->ReserveL(aMessage, aMessage.Int1(), this, KHWRMAllSubResources));
+
+ iReserved = ETrue;
+
+ iStateSetAfterReservation = EFalse;
+
+ // Restore previously stored state if restore was specified.
+ // Errors are trapped as reservation itself was successful.
+ if ( aMessage.Int0() )
+ {
+ TInt err(KErrNone);
+ RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing reservation.
+
+ if ( iFrozenStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ TRAP(err, StartVibraL(iFrozenTime, iFrozenIntensity, dummy));
+ }
+ else
+ {
+ TRAP(err, StopVibraL(dummy));
+ }
+ }
+
+ completeMessage = ETrue; // Complete needed, as dummy used.
+ break;
+ }
+ case EHWRMReleaseVibra:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMReleaseVibra") );
+
+ // If a "Leave" is introduced, consideration must be given to the corresponding
+ // client side side code which requested this action. In particular, ensure that
+ // the client-side caller doesn't set its "iReserved" flag to false without
+ // checking the result of the Release command.
+
+ // Release whole vibra.
+ TInt unreserved = iReservationHandler->Release(this, KHWRMAllSubResources);
+
+ iReserved = EFalse;
+
+ // Clear suspended flag
+ iSuspended = EFalse;
+
+ // Freeze state
+ iFrozenTime = iVibraTimer->Freeze();
+ iFrozenStatus = iLastStatus;
+ iFrozenIntensity = iLastIntensity;
+
+ // Restore base state if no more reservations for vibra.
+ // Errors are trapped as release itself was successful.
+ if ( unreserved )
+ {
+ RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing release.
+ TRAP_IGNORE(StopVibraL(dummy));
+ }
+
+ completeMessage = ETrue; // Complete needed, as dummy used.
+ break;
+ }
+ case EHWRMCleanupVibra:
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMCleanupVibra") );
+
+ CleanupVibra();
+
+ completeMessage = ETrue; // Complete needed, as dummy used in CleanupVibra.
+ break;
+ }
+ // Cannot identify the message, panic the client
+ default:
+ {
+ CHWRMServer::PanicClient(aMessage, EPanicIllegalFunction);
+ break;
+ }
+ }
+
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ExecuteMessageL - return 0x%x" ), completeMessage );
+
+ return completeMessage;
+
+ }
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::StartVibraL
+// Starts vibra for duration with specified intensity.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::StartVibraL(const TTimeIntervalMicroSeconds32& aDuration,
+ TInt aIntensity,
+ const RMessage2& aMessage,
+ TBool aSetTimer,
+ TBool aPulse)
+ {
+
+ COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::StartVibraL(%d, %d, %d, %d)" ),
+ aDuration.Int(), aIntensity, aSetTimer, aPulse );
+
+
+ __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
+
+ // Duration must not be negative.
+ if ( aDuration.Int() < 0 || aDuration.Int() > KHWRMVibraMaxDurationInMicroseconds )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // Check vibra/feedback profile settings if not privileged client.
+ // If not pulse request, vibra must be on. If pulse request, feedback must be on.
+ if ( !iPrivilegedClient &&
+ ( ( !aPulse && (iVibraCommonData.VibraState() != CHWRMVibra::EVibraModeON ) ) ||
+ ( aPulse && (iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON) ) ) )
+ {
+ // Stop vibra if it needs shutdown.
+ if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ StopVibraL(aMessage);
+ }
+ User::Leave(KErrAccessDenied);
+ }
+
+ // Check if vibra is cooling off or feedback should be prevented
+ if ( iVibraCommonData.VibraLocked() || (aPulse && VibraPulseBlocked()) )
+ {
+ User::Leave(KErrLocked);
+ }
+
+ // Check if vibra is blocked (aPulse means no feedback request)
+ if ( !aPulse &&
+ iVibraCommonData.VibraBlocked() &&
+ iVibraCommonData.VibraBlocked( KHWRMInternalSettingsChargerBlockVibra ) )
+ {
+ User::Leave(KErrLocked);
+ }
+
+
+ // Check intensity validity
+ if ( aIntensity != KUseDefaultIntensity && (aIntensity < KHWRMVibraMinIntensity || aIntensity > KHWRMVibraMaxIntensity) )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // Check intensity validity for pulse requests
+ if ( aPulse && (aIntensity < KHWRMVibraMinPulseIntensity || aIntensity > KHWRMVibraMaxIntensity) )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // Call plugins
+ if ( aIntensity == 0 )
+ {
+ // Stop vibra, if intensity is zero
+ StopVibraL(aMessage);
+ }
+ else
+ {
+ // Start timers, if so specified
+ // This is because when restoring last state, existing timer should be left intact.
+ // Vibra timer is left intact also if pulse requested because new timer is setup.
+ if ( aSetTimer && !aPulse )
+ {
+ iVibraTimer->Set(aDuration);
+ iActiveTimerId = KHWRMVibraTimerID;
+ }
+
+ if ( aPulse )
+ {
+ // Create new timer with ascending identifier.
+ TInt count( iPulseData.Count() );
+ CHWRMGenericTimer* timer =
+ CHWRMGenericTimer::NewL(*this, iVibraCommonData.MaximumOnTime(), count );
+ iActiveTimerId = count;
+ CPulseData* pulseData = CPulseData::NewL(*timer, iLastIntensity, aIntensity, iActiveTimerId );
+ CleanupStack::PushL( pulseData );
+ iPulseData.AppendL( pulseData );
+ CleanupStack::Pop( pulseData );
+ iPulseData[count]->Timer().Set(aDuration);
+ }
+
+ // complete message if suspended, as there will not be ProcessResponseL
+ if ( iSuspended && aMessage.Handle() )
+ {
+ aMessage.Complete(KErrNone);
+ }
+
+ // Call plugin if not suspended
+ if ( !iSuspended )
+ {
+ // Check reservation if not pulse request (pulse is blocked earlier if priority
+ // of this client is lower than reserving client).
+ if ( !aPulse && iReservationHandler->IsReserved(this, KHWRMAllSubResources) )
+ {
+ User::Leave(KErrInUse);
+ }
+
+ // Create new data (TransId is updated later, commandId is not important)
+ THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse);
+ CleanupStack::PushL( data );
+
+ if ( aIntensity == KUseDefaultIntensity )
+ {
+ // No data, pass empty descriptor
+ TBuf8<1> emptyDes;
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId, emptyDes, this);
+ }
+ else
+ {
+ HWRMVibraCommand::TStartVibraCmdDataPackage dataPckg(aIntensity);
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraCmdId, dataPckg, this);
+ }
+
+ // data still needed, do not destroy, just pop
+ CleanupStack::Pop( data );
+
+ // Add data to list
+ iTransactionList->AddTransaction( data );
+
+ // Assign request data for common vibra service
+ TVibraClientData clientData( this, iSid, aIntensity );
+ // Control of overlapping pulses/normal vibration requests is in hands of HWRM,
+ // when pulse length is configured to be handled by HWRM. That is why
+ // client data must be set to common vibra service.
+ iCommonService.SetClientData( clientData );
+
+
+ iStateSetAfterReservation = ETrue;
+ }
+ }
+ // Store the latest status in case vibra gets suspended before next plugin call.
+ iLastStatus = CHWRMVibra::EVibraStatusOn;
+ iLastIntensity = aIntensity;
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StartVibraL - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::VibraPulseBlocked
+// Checks whether vibra pulse should be blocked.
+// -----------------------------------------------------------------------------
+//
+TBool CHWRMVibraService::VibraPulseBlocked()
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked" ) );
+ TBool blocked( EFalse );
+
+ // Check whether vibra cooling off should prevent feedback
+ if ( iVibraCommonData.VibraLocked() &&
+ iVibraCommonData.VibraBlocked( KHWRMInternalSettingsCoolOffBlockFeedback ) )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by cool-off" ));
+ blocked = ETrue;
+ }
+
+ // Check if vibra is blocked and whether it should prevent feedback
+ if ( (iVibraCommonData.VibraBlocked() & KHWRMAccessoryVibraBlocked) &&
+ iVibraCommonData.VibraBlocked( KHWRMInternalSettingsAccessoryBlockFeedback ) )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by accessory" ) );
+ blocked = ETrue;
+ }
+ if ( (iVibraCommonData.VibraBlocked() & KHWRMInternalVibraBlocked) &&
+ iVibraCommonData.VibraBlocked( KHWRMInternalSettingsChargerBlockFeedback ) )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by charger" ) );
+ blocked = ETrue;
+ }
+
+ return blocked;
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::PulseVibraL
+// Requests vibra pulse with specified intensity and duration.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::PulseVibraL(const TTimeIntervalMicroSeconds32& aDuration,
+ TInt aIntensity,
+ const RMessage2& aMessage,
+ TBool /* aSetTimer */)
+ {
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::PulseVibraL(%d, %d)" ), aDuration.Int(), aIntensity );
+
+ __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
+
+ // Duration must not be negative.
+ if ( aDuration.Int() < 0 || aDuration.Int() > KHWRMVibraMaxDurationInMicroseconds )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // Check intensity validity
+ if ( aIntensity < KHWRMVibraMinPulseIntensity || aIntensity > KHWRMVibraMaxIntensity )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if( VibraPulseBlocked() )
+ {
+ User::Leave(KErrLocked);
+ }
+
+ // Check vibra profile setting if not privileged client
+ if ( !iPrivilegedClient && iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON )
+ {
+ // Stop vibra if it needs shutdown.
+ if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ StopVibraL(aMessage);
+ }
+ User::Leave(KErrAccessDenied);
+ }
+
+ // Finally before sending pulse-command to plugin check that this client
+ // has higher priority than last client requested vibration.
+
+ // Call plugins
+ if ( aIntensity == 0 )
+ {
+ // Stop vibra, if intensity is zero
+ StopVibraL(aMessage);
+ }
+ else
+ {
+ // There is no timer for real pulse requests, because low level
+ // implementation must stop the vibra after specified duration.
+ // This will however result in vibra status not being updated.
+ iActiveTimerId = KHWRMVibraNoTimer;
+
+ // Complete message if suspended, as there will not be ProcessResponseL
+ if ( iSuspended && aMessage.Handle() )
+ {
+ aMessage.Complete(KErrNone);
+ }
+
+ // Call plugin if not suspended
+ if ( !iSuspended )
+ {
+ // Create new data (TransId is updated later, commandId is not important)
+ THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse);
+ CleanupStack::PushL( data );
+ HWRMVibraCommand::TVibraData vibraData;
+ vibraData.iIntensity = aIntensity;
+ vibraData.iDuration = aDuration.Int() / 1000;
+ HWRMVibraCommand::TPulseVibraCmdDataPackage dataPckg(vibraData);
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EPulseVibraCmdId, dataPckg, this);
+
+ // data still needed, do not destroy, just pop
+ CleanupStack::Pop( data );
+
+ // Add data to list
+ iTransactionList->AddTransaction( data );
+
+ // Control of overlapping pulses/normal vibration requests is not in hands of HWRM,
+ // when pulse length is configured to be handled by vibra driver. That is why
+ // client data may not be set to common vibra service.
+
+ iStateSetAfterReservation = ETrue;
+ }
+
+ // Store the latest status in case vibra gets suspended before next plugin call.
+ iLastStatus = CHWRMVibra::EVibraStatusOn;
+ iLastIntensity = aIntensity;
+ }
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::PulseVibraL - return" ) );
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::StopVibraL
+// Stops vibra. No harm calling this just in case
+// even if vibra is already stopped.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::StopVibraL(const RMessage2& aMessage,
+ TBool aForceStop,
+ TBool aFinalStop)
+ {
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::StopVibraL(%d,%d)" ), aForceStop, aFinalStop );
+
+ __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
+
+ TBool forceStop(aForceStop);
+
+ // Stop any ongoing timers
+ iVibraTimer->Cancel();
+
+ ReleasePulseData();
+ // Reset this service's client data.
+ // This way any other (if any) service's interrupted vibration is restarted.
+ iCommonService.ResetClientData( this );
+
+
+
+ // Check from active reserver if it is ok for them that we stop vibra.
+ // This is necessary if active reserver is just reserving vibra but hasn't set vibra state explicitly
+ // after reservation. Otherwise it is possible that vibra will be left on forever.
+ // Note: This will sometimes result in unnecessary stop calls from suspended sessions when active session has not
+ // explicitly set vibra on/off, but this is the only way to ensure that the necessary stop calls go through.
+ CHWRMService* activeReserver = iReservationHandler->GetActiveReserver(KHWRMAllSubResources);
+ if ( activeReserver )
+ {
+ if ( (static_cast<CHWRMVibraService*>(activeReserver)) == this )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - This session is active reserver, no need to force stop.") );
+ }
+ else if ( (static_cast<CHWRMVibraService*>(activeReserver))->OkToStopVibra() )
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - Active reserver has not used vibra since reservation - Force stop vibra.") );
+ forceStop = ETrue;
+ }
+ else
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - Active reserver has been using vibra after reservation, no need to force stop.") );
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - No active reserver found, no need to force stop.") );
+ }
+
+ if ( forceStop || !iSuspended )
+ {
+ // Check reservation.
+ if ( !forceStop && iReservationHandler->IsReserved(this, KHWRMAllSubResources) )
+ {
+ User::Leave(KErrInUse);
+ }
+
+ // create new data (TransId is updated later)
+ THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse); // commandId is not important
+ CleanupStack::PushL( data );
+
+ // No data, pass empty descriptor
+ TBuf8<1> emptyDes;
+
+ // Do not require callback on final stopping of vibra
+ CHWRMService* callback = NULL;
+ if ( !aFinalStop )
+ {
+ callback = this;
+ }
+
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStopVibraCmdId, emptyDes, callback);
+
+ // data still needed, do not destroy, just pop
+ CleanupStack::Pop( data );
+
+ // Add data to list
+ iTransactionList->AddTransaction( data );
+
+ iStateSetAfterReservation = ETrue;
+ }
+ else
+ {
+ // complete message if suspended, as there will not be ProcessResponseL
+ if ( aMessage.Handle() )
+ {
+ aMessage.Complete(KErrNone);
+ }
+ }
+
+ // Store the latest status in case vibra gets suspended before next plugin call.
+ iLastStatus = CHWRMVibra::EVibraStatusStopped;
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - return" ) );
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ProcessResponseL
+// Handles Vibra requests responses.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ProcessResponseL( TInt aCommandId, TUint8 aTransId, TDesC8& aData, TBool aTimeout)
+ {
+ COMPONENT_TRACE4(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL(0x%x, 0x%x, <data>, 0x%x)" ), aCommandId, aTransId, aTimeout );
+
+ TInt pluginErr(KErrNone); // Error came from plugin as data (or timeout). Used to complete RMessage.
+ TInt contextErr(KErrNone); // Error in context, i.e. bad handle or descriptor. Used to leave.
+
+ // Unpack the package. All vibra messages contain only possible error code
+ // in return package.
+ if ( !aTimeout && aData.Size() != sizeof(TInt) )
+ {
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - Data size mismatch, expected: 0x%x, got 0x%x" ), sizeof(TInt), aData.Size() );
+ contextErr = KErrBadDescriptor;
+ pluginErr = KErrBadDescriptor;
+ }
+ else
+ {
+ // If response was caused by timeout, set that as the error.
+ // Timeout handled this way instead of just returning KErrTimeout in aData because
+ // aData format is not known in plugin handler and in theoretically some new commands
+ // may also return different response than just error code in future.
+ if ( aTimeout )
+ {
+ pluginErr = KErrTimedOut;
+ }
+ else
+ {
+ HWRMVibraCommand::TErrorCodeResponsePackage errPckg;
+ errPckg.Copy(aData);
+ pluginErr = errPckg();
+ }
+
+ if ( pluginErr != KErrNone )
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - Error: %d" ), pluginErr );
+ }
+
+ // Update vibra status PS state value
+ if ( !iPrivilegedClient &&
+ ( ( (iActiveTimerId == KHWRMVibraTimerID) && (iVibraCommonData.VibraState() != CHWRMVibra::EVibraModeON ) ) ||
+ ( (iActiveTimerId != KHWRMVibraTimerID) && (iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON) ) ) )
+ {
+ // This can presumably happen if there was ongoing plugin call when
+ // vibra was turned off.
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusNotAllowed, iPrivilegedClient);
+
+ // Set vibra timer for immediate shutdown if commandid was not stop
+ if ( aCommandId != HWRMVibraCommand::EStopVibraCmdId )
+ {
+ iVibraTimer->Set(1);
+ ReleasePulseData();
+ }
+ }
+ else
+ {
+ if ( pluginErr != KErrNone )
+ {
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusUnknown, iPrivilegedClient);
+ }
+ else
+ {
+ switch ( aCommandId )
+ {
+ case HWRMVibraCommand::EStartVibraCmdId:
+ {
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);
+ break;
+ }
+ case HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId:
+ {
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);
+ break;
+ }
+ case HWRMVibraCommand::EPulseVibraCmdId:
+ {
+ // It may cause quite a lot of overhead to publish vibra status for short pulses.
+ // iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);
+ break;
+ }
+
+ case HWRMVibraCommand::EStopVibraCmdId:
+ {
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusStopped, iPrivilegedClient);
+ break;
+ }
+ default:
+ {
+ iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusUnknown, iPrivilegedClient);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Complete request and remove delete transaction
+ contextErr = CompleteRequest(aTransId, pluginErr);
+
+ // Leave if there is error in context
+ User::LeaveIfError(contextErr);
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - return" ) );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::GenericTimerFired
+// Handles vibra cutoff timer firing. Adjust vibra intensity and stops vibra.
+// There is only one regular vibra timer active at a time. It is used for vibra start calls.
+// If vibra pulse is requested, new timer is setup. If pulse timer expires and vibra or any other
+// pulse timer is still active, vibration intensity must be adjusted accordingly. If all pulse
+// timers and vibra timer have expired, stop vibra.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::GenericTimerFired(TInt aTimerId, TBool aCutOff)
+ {
+ COMPONENT_TRACE5( _L( "HWRM Server - CHWRMVibraService::GenericTimerFired, iLastIntensity %d, iActiveTimerId %d, aTimerId %d, aCutOff %d" ),
+ iLastIntensity, iActiveTimerId, aTimerId, aCutOff );
+
+ // if cutoff because maximum ontime set the lock period
+ if ( aCutOff )
+ {
+ iVibraCommonData.LockVibra();
+ }
+
+ RMessage2 dummy;
+ TInt err(KErrNone);
+ TInt count( iPulseData.Count() );
+ TBool changeIntensity( EFalse );
+ TBool pulseTimersActive( EFalse );
+ TBool succeedingFound( EFalse );
+
+ if( aTimerId < count )
+ {
+ // Update last intensity from expired pulse timer to ACTIVE timer succeeding it,
+ // because otherwise it has old information about intensity, which must
+ // be set when it expires. This works, because timer objects only need to
+ // remember last intensity. If timer expires, but it is not "active" one, then
+ // intensity is not changed and intensity if just passed to next one in queue.
+ for( TInt i = aTimerId+1; i < count; i++ )
+ {
+ if( iPulseData[i]->Timer().IsActive() )
+ {
+ COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgrading last intensity from %d (%d) to %d (%d) "),
+ aTimerId, iPulseData[aTimerId]->LastIntensity(), i, iPulseData[i]->LastIntensity() );
+ COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgrading timer id from %d (%d) to %d (%d) " ),
+ aTimerId, iPulseData[aTimerId]->LastTimerId(), i, iPulseData[i]->LastTimerId() );
+ iPulseData[i]->SetLastIntensity( iPulseData[aTimerId]->LastIntensity() );
+ iPulseData[i]->SetLastTimerId( iPulseData[aTimerId]->LastTimerId() );
+ succeedingFound = ETrue;
+ break;
+ }
+ }
+ }
+
+ // Check if any pulse timers active
+ for( TInt i = 0; i < count; i++ )
+ {
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - pulse timer %d status: %d" ), i, iPulseData[i]->Timer().IsActive() );
+ if( iPulseData[i]->Timer().IsActive() )
+ {
+ pulseTimersActive = ETrue;
+ }
+ }
+
+ COMPONENT_TRACE2( _L( "HWRM Server - CHWRMVibraService::GenericTimerFired - vibra timer status: %d" ), iVibraTimer->IsActive() );
+
+ // If timer expired is not last active timer, we must not change intensity,
+ // because intensity has been changed when new timer setup and intensity
+ // gets updated only if it expires or new pulse request arrives.
+ if( aTimerId == iActiveTimerId )
+ {
+ changeIntensity = ETrue;
+
+ if( (aTimerId == KHWRMVibraTimerID || !succeedingFound) && pulseTimersActive )
+ {
+ // If active timer expired was vibra timer or succeeding (=active) pulse timer was not found
+ // and there are still active pulse timers, update timer id and intensity accordingly.
+ // First pulse timer from end is new active.
+ for( TInt i = count-1; i >= 0; i-- )
+ {
+ if( iPulseData[i]->Timer().IsActive() )
+ {
+ iActiveTimerId = i;
+ iLastIntensity = iPulseData[i]->Intensity();
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgraded active timer id to %d and intensity to %d" ),
+ iActiveTimerId, iLastIntensity );
+ break;
+ }
+ }
+ }
+ else if( aTimerId != KHWRMVibraTimerID && iVibraTimer->IsActive() && !pulseTimersActive )
+ {
+ // If active timer expired was not vibra timer and it still active and no more pulse
+ // timers, update timer id and intensity accordingly
+ iActiveTimerId = KHWRMVibraTimerID;
+ if( aTimerId < count )
+ {
+ iLastIntensity = iPulseData[aTimerId]->LastIntensity();
+ }
+ COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgraded active timer id to %d and intensity to %d" ),
+ iActiveTimerId, iLastIntensity );
+ }
+ else
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - active timer id and intensity not updated" ) );
+ }
+ }
+
+ if( !pulseTimersActive )
+ {
+ // Remove expired pulse timers
+ ReleasePulseData();
+ }
+
+ // If cutoff or there are no active timers left, stop vibra
+ if( aCutOff || (!pulseTimersActive && !iVibraTimer->IsActive()) )
+ {
+ TRAP(err, StopVibraL(dummy));
+
+ if ( err != KErrNone )
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - Error Stopping vibra: %d" ), err );
+ }
+ }
+ else if( changeIntensity )
+ {
+ TRAP(err, ChangeVibraIntensityL());
+
+ if ( err != KErrNone )
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - Error changing intensity: %d" ), err );
+ }
+ }
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - return" ) );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ChangeVibraIntensityL
+// Changes the device vibration intensity to previous active intensity.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ChangeVibraIntensityL()
+ {
+ COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ChangeVibraIntensityL() - new intensity %d" ), iLastIntensity );
+
+ // Ignore Coverity false positive as uninitialized variable.
+ // Since no response is sent back to the client, only a empty message is created here.
+ // Message handle of this will be initialized to NULL in the default constructor.
+ // coverity[var_decl]
+ RMessage2 dummy;
+
+ // Create new data (TransId is updated later, commandId is not important)
+ THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(dummy, 0, 0, EFalse);
+ CleanupStack::PushL( data );
+
+ if ( iLastIntensity == KUseDefaultIntensity )
+ {
+ // No data, pass empty descriptor
+ TBuf8<1> emptyDes;
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId, emptyDes, this);
+ }
+ else
+ {
+ HWRMVibraCommand::TStartVibraCmdDataPackage dataPckg(iLastIntensity);
+ data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraCmdId, dataPckg, this);
+ }
+
+ // data still needed, do not destroy, just pop
+ CleanupStack::Pop( data );
+
+ // Add data to list
+ iTransactionList->AddTransaction( data );
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::SuspendSubResource
+// Suspends vibra. Since vibra has no subresources, whole vibra is affected.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::SuspendSubResource(TInt /*aSubResource*/)
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::SuspendSubResource()" ) );
+
+ if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ // Resume base state, i.e. stop vibra
+ RMessage2 dummy;
+ TRAP_IGNORE(StopVibraL(dummy));
+
+ // Restore iLastStatus
+ iLastStatus = CHWRMVibra::EVibraStatusOn;
+ }
+
+ iSuspended = ETrue;
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::SuspendSubResource - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ResumeSubResource
+// Resumes vibra. Since vibra has no subresources, whole vibra is affected.
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ResumeSubResource(TInt /*aSubResource*/)
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ResumeSubResource()" ) );
+
+ iSuspended = EFalse;
+
+ RMessage2 dummy;
+
+ // Restore last state
+ TInt err(KErrNone);
+ if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
+ {
+ TRAP(err, StartVibraL(0, iLastIntensity, dummy, EFalse));
+ }
+ else
+ {
+ TRAP(err, StopVibraL(dummy));
+ }
+
+ COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ResumeSubResource - return" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::ActivateSubResource
+// Vibra doesn't support activation/deactivation based on device state
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::ActivateSubResource(TInt /*aSubResource*/, TBool /*aActivate*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CHWRMVibraService::OkToStopVibra
+// Checks if it is ok to stop vibra from another session.
+// -----------------------------------------------------------------------------
+//
+TBool CHWRMVibraService::OkToStopVibra()
+ {
+ return !iStateSetAfterReservation;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPulseData::CPulseData
+// -----------------------------------------------------------------------------
+//
+
+
+CHWRMVibraService::CPulseData::CPulseData( CHWRMGenericTimer& aVibraTimer,
+ const TInt aLastIntensity,
+ const TInt aIntensity,
+ const TInt aLastTimerId )
+ :iVibraTimer(aVibraTimer),
+ iLastIntensity(aLastIntensity),
+ iIntensity(aIntensity),
+ iLastTimerId(aLastTimerId)
+ {
+ COMPONENT_TRACE1(_L( "HWRM Server - CPulseData::CPulseData()" ) );
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPulseData::NewL
+// -----------------------------------------------------------------------------
+//
+CHWRMVibraService::CPulseData*
+CHWRMVibraService::CPulseData::NewL( CHWRMGenericTimer& aVibraTimer,
+ const TInt aLastIntensity,
+ const TInt aIntensity,
+ const TInt aLastTimerId )
+ {
+ COMPONENT_TRACE4(_L( "HWRM Server - CPulseData::NewL(0x%x, %d, %d)" ), &aVibraTimer, aLastIntensity, aIntensity);
+
+ CPulseData* self = new( ELeave )
+ CPulseData(aVibraTimer, aLastIntensity, aIntensity, aLastTimerId);
+
+ COMPONENT_TRACE2(_L( "HWRM Server - CPulseData::NewL - return 0x%x" ), self);
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::~CPulseData
+// -----------------------------------------------------------------------------
+//
+CHWRMVibraService::CPulseData::~CPulseData()
+ {
+ COMPONENT_TRACE1(_L("HWRM Server - CPulseData::~CPulseData()"));
+
+ iVibraTimer.Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::Timer
+// -----------------------------------------------------------------------------
+//
+CHWRMGenericTimer& CHWRMVibraService::CPulseData::Timer() const
+ {
+ return iVibraTimer;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPulseData::LastIntensity
+// -----------------------------------------------------------------------------
+//
+TInt CHWRMVibraService::CPulseData::LastIntensity() const
+ {
+ return iLastIntensity;
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::Intensity
+// -----------------------------------------------------------------------------
+//
+TInt CHWRMVibraService::CPulseData::Intensity() const
+ {
+ return iIntensity;
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::SetLastIntensity
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::CPulseData::SetLastIntensity(TInt aIntensity)
+ {
+ iLastIntensity = aIntensity;
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::LastTimerId
+// -----------------------------------------------------------------------------
+//
+TInt CHWRMVibraService::CPulseData::LastTimerId() const
+ {
+ return iLastTimerId;
+ }
+
+// -----------------------------------------------------------------------------
+// CPulseData::SetLastTimerId
+// -----------------------------------------------------------------------------
+//
+void CHWRMVibraService::CPulseData::SetLastTimerId(TInt aTimerId)
+ {
+ iLastTimerId = aTimerId;
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// End of File