resourcemgmt/hwresourcesmgr/server/src/HWRMVibraService.cpp
changeset 0 4e1aa6a622a0
child 76 cb32bcc88bad
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "HWRMServer.h"
       
    21 #include "HWRMVibraClientServer.h"
       
    22 #include "HWRMService.h"
       
    23 #include "HWRMVibraService.h"
       
    24 #include "HWRMVibraCommands.h"
       
    25 #include "HWRMPluginHandler.h"
       
    26 #include "HWRMtrace.h"
       
    27 #include "HWRMVibraCommonData.h"
       
    28 #include "HWRMVibra.h"
       
    29 #include "HWRMReservationHandler.h"
       
    30 #include "HWRMPrivateCRKeys.h"
       
    31 #include "HWRMDomainPSKeys.h"
       
    32 #include "HWRMPrivatePSKeys.h"
       
    33 #include "HWRMVibraCommonService.h"
       
    34 
       
    35 
       
    36 
       
    37 // EXTERNAL DATA STRUCTURES
       
    38 // None
       
    39 
       
    40 // EXTERNAL FUNCTION PROTOTYPES  
       
    41 // None
       
    42 
       
    43 // CONSTANTS
       
    44 // None
       
    45 
       
    46 // MACROS
       
    47 // None
       
    48 
       
    49 // LOCAL CONSTANTS AND MACROS
       
    50 _LIT( KPanicCategory, "HWRMVibraService" );
       
    51 
       
    52 const TInt KHWRMVibraMaxDurationInMicroseconds = KHWRMVibraMaxDuration * 1000;
       
    53 
       
    54 const TInt KHWRMVibraTimerID = KMaxTInt;
       
    55 const TInt KHWRMVibraNoTimer = KMinTInt;
       
    56 
       
    57 
       
    58 // MODULE DATA STRUCTURES
       
    59 // None
       
    60 
       
    61 // LOCAL FUNCTION PROTOTYPES
       
    62 // None
       
    63 
       
    64 // FORWARD DECLARATIONS
       
    65 // None
       
    66 
       
    67 // ============================= LOCAL FUNCTIONS ===============================
       
    68 
       
    69 // ============================ MEMBER FUNCTIONS ===============================
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CHWRMVibraService::CHWRMVibraService
       
    73 // C++ constructor
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 CHWRMVibraService::CHWRMVibraService(CHWRMVibraCommonService& aCommonService,
       
    77                                      CHWRMVibraCommonData& aVibraCommonData,
       
    78                                      TBool aPrivilegedClient)
       
    79     : iVibraCommonData(aVibraCommonData),
       
    80       iPrivilegedClient(aPrivilegedClient),
       
    81       iStateSetAfterReservation(EFalse),
       
    82       iCommonService(aCommonService),
       
    83       iSid(0),
       
    84       iActiveTimerId(KHWRMVibraTimerID)
       
    85     {
       
    86     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CHWRMVibraService()" ) );
       
    87     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CHWRMVibraService - return" ) );
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CHWRMVibraService::ConstructL
       
    92 // Symbian 2nd phase constructor can leave.
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 void CHWRMVibraService::ConstructL(CHWRMPluginHandler* aPluginHandler,
       
    96                                    CHWRMReservationHandler* aReservationHandler)
       
    97     {    
       
    98     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ConstructL(0x%x)" ), aPluginHandler );
       
    99 
       
   100     BaseConstructL(aPluginHandler, aReservationHandler);
       
   101     
       
   102     // Create vibra timer with special identifier.
       
   103     iVibraTimer = CHWRMGenericTimer::NewL(*this, iVibraCommonData.MaximumOnTime(), KHWRMVibraTimerID);
       
   104     
       
   105     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ConstructL - return " ) );
       
   106     }
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CHWRMVibraService::NewL
       
   110 // Two-phased constructor.
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 CHWRMVibraService* CHWRMVibraService::NewL(CHWRMPluginHandler* aPluginHandler,
       
   114                                            CHWRMReservationHandler* aReservationHandler,
       
   115                                            CHWRMVibraCommonService& aCommonService,
       
   116                                            CHWRMVibraCommonData& aVibraCommonData,
       
   117                                            TBool aPrivilegedClient)
       
   118     {
       
   119     COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::NewL(0x%x, aPrivilegedClient: 0x%x)" ), aPluginHandler, aPrivilegedClient );
       
   120     
       
   121     CHWRMVibraService* self = new( ELeave ) CHWRMVibraService(aCommonService, aVibraCommonData, aPrivilegedClient);
       
   122   
       
   123     CleanupStack::PushL( self );
       
   124     self->ConstructL(aPluginHandler, aReservationHandler);
       
   125     CleanupStack::Pop();
       
   126 
       
   127     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::NewL - return 0x%x" ), self );
       
   128     
       
   129     return self;
       
   130     }
       
   131    
       
   132 // ---------------------------------------------------------
       
   133 // Destructor
       
   134 // ---------------------------------------------------------
       
   135 //
       
   136 CHWRMVibraService::~CHWRMVibraService()
       
   137     {
       
   138     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::~CHWRMVibraService()" ) );
       
   139 
       
   140     // Cleanup vibra just in case regular cleanup failed
       
   141     CleanupVibra();    
       
   142 
       
   143     // Delete timer
       
   144     if (iVibraTimer)
       
   145         {
       
   146         iVibraTimer->Cancel();
       
   147         delete iVibraTimer;
       
   148         }
       
   149 
       
   150     ReleasePulseData();
       
   151 
       
   152     // Base class cleanup
       
   153     BaseDestruct();
       
   154 
       
   155     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::~CHWRMVibraService - return" ) );
       
   156     }
       
   157 
       
   158 // -----------------------------------------------------------------------------
       
   159 // CHWRMVibraService::ReleasePulseData
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 void CHWRMVibraService::ReleasePulseData()
       
   163     {
       
   164     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ReleasePulseData(), count %d" ), iPulseData.Count() );
       
   165 
       
   166     iPulseData.ResetAndDestroy();
       
   167     
       
   168     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ReleasePulseData - return" ) );
       
   169     }
       
   170 
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CHWRMVibraService::CleanupVibra
       
   174 // Cleans up vibra. 
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 void CHWRMVibraService::CleanupVibra()
       
   178     {    
       
   179     if ( !iCleanupDone )
       
   180         {        
       
   181         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra()" ) );
       
   182         TInt unreserved(0x0);
       
   183         
       
   184         // If still reserved, release
       
   185         if ( iReserved )
       
   186             {
       
   187             unreserved = iReservationHandler->Release(this, KHWRMAllSubResources);	
       
   188             iReserved = EFalse;
       
   189             iSuspended = EFalse;
       
   190             }
       
   191         else
       
   192             {
       
   193             unreserved = iReservationHandler->GetUnreservedTargets();
       
   194             }
       
   195 
       
   196         COMPONENT_TRACE3(_L("HWRM Server - CHWRMVibraService::CleanupVibra - Vibra status: %d, reservation status: %d"), iLastStatus, unreserved );
       
   197 
       
   198         // If this session has set vibra to vibrate and vibra is unreserved, stop it.
       
   199         if ( unreserved && iLastStatus == CHWRMVibra::EVibraStatusOn )
       
   200             {
       
   201             RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing cleanup            
       
   202             TRAPD(err, StopVibraL(dummy, EFalse, ETrue));
       
   203             if ( err != KErrNone )
       
   204                 {
       
   205                 COMPONENT_TRACE2(_L("HWRM Server - CHWRMVibraService::CleanupVibra - Stopping vibra failed: %d"), err );
       
   206                 }
       
   207             else 
       
   208                 {
       
   209                 // Since there will be no ProcessResponse for this one, publish the status now
       
   210                 iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusStopped, iPrivilegedClient);	    
       
   211                 }
       
   212             }
       
   213             
       
   214         // Make sure client requests get cleared if not via StopVibraL
       
   215         if( iCommonService.HasData( this ) )
       
   216             {
       
   217             iCommonService.ResetClientData( this );
       
   218             }
       
   219 
       
   220         iCleanupDone = ETrue;
       
   221         
       
   222         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra - return" ) );    
       
   223         }
       
   224     else
       
   225         {
       
   226         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::CleanupVibra - Already cleaned up" ) );    
       
   227         }
       
   228     }
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CHWRMVibraService::ForceVibraStop
       
   232 // Stops vibra. 
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 void CHWRMVibraService::ForceVibraStop()
       
   236     {
       
   237     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ForceVibraStop()" ) );
       
   238     
       
   239     RMessage2 dummy;
       
   240     TRAP_IGNORE(StopVibraL(dummy, ETrue));
       
   241     
       
   242     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ForceVibraStop - return" ) );
       
   243     }
       
   244     
       
   245 // -----------------------------------------------------------------------------
       
   246 // CHWRMVibraService::ExecuteMessageL
       
   247 // Handles Vibra requests. 
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 TBool CHWRMVibraService::ExecuteMessageL( const RMessage2& aMessage )
       
   251     {
       
   252     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ExecuteMessageL(0x%x)" ), aMessage.Function() );
       
   253     
       
   254     __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
       
   255     __ASSERT_ALWAYS(iReservationHandler, User::Panic(KPanicCategory, EPanicBadHandle));
       
   256     
       
   257     if ( aMessage.IsNull() )
       
   258         {
       
   259         User::Leave(KErrBadHandle);
       
   260         }
       
   261 
       
   262     // All messages are by default asynchronous because of the nature of the plugin API
       
   263     TBool completeMessage(EFalse);
       
   264     TInt function( aMessage.Function() );
       
   265 
       
   266 	// Retrieve client sid
       
   267     iSid = aMessage.SecureId();
       
   268 
       
   269     switch ( function )
       
   270         {
       
   271     	case EHWRMStartVibraDefaultIntensity:
       
   272     	    {
       
   273             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStartVibraDefaultIntensity") );
       
   274 
       
   275             StartVibraL( aMessage.Int0() * 1000, KUseDefaultIntensity, aMessage);   
       
   276 
       
   277     		break;
       
   278     	    }
       
   279     	case EHWRMStartVibra:
       
   280     	    {
       
   281             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStartVibra") );
       
   282 
       
   283             StartVibraL(aMessage.Int0() * 1000, aMessage.Int1(), aMessage);            
       
   284 
       
   285     		break;
       
   286     	    }
       
   287     	case EHWRMPulseVibraDefault:
       
   288     	case EHWRMPulseVibraDefaultIntensity:
       
   289     	case EHWRMPulseVibra:
       
   290     	    {
       
   291             // First of all check whether pulse request allowed by this client.
       
   292             if ( !iCommonService.VibraPulseAllowed( aMessage.SecureId() ) )
       
   293                 {
       
   294                 User::Leave(KErrAccessDenied);
       
   295                 }
       
   296 
       
   297             TInt duration( iVibraCommonData.FeedbackDefaultDuration() * 1000 );
       
   298             TInt intensity( iVibraCommonData.FeedbackDefaultIntensity() );
       
   299 
       
   300             if( function == EHWRMPulseVibraDefault )
       
   301                 {
       
   302                 COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibraDefault") );
       
   303                 }
       
   304             else if( function == EHWRMPulseVibraDefaultIntensity )
       
   305                 {
       
   306                 COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibraDefaultIntensity") );
       
   307                 duration = aMessage.Int0() * 1000;
       
   308                 }
       
   309             else
       
   310                 {
       
   311                 COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMPulseVibra") );
       
   312                 duration = aMessage.Int0() * 1000;
       
   313                 intensity = aMessage.Int1();
       
   314                 }
       
   315             
       
   316             COMPONENT_TRACE2(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - pulse supported %d"), 
       
   317                 iVibraCommonData.FeedbackPulseSupported() );
       
   318 
       
   319             // If there is active reservation and vibration ongoing by a higher priority client, 
       
   320             // pulse request is not allowed. In all other circumstances either pulse or start 
       
   321             // command is sent to plugin.
       
   322             if ( iReservationHandler->IsReserved(this, KHWRMAllSubResources) &&
       
   323                  iCommonService.ExecutingPriorityHigher( aMessage.SecureId() ) )
       
   324                 {
       
   325                 User::Leave(KErrInUse);
       
   326                 }
       
   327 
       
   328             if( iVibraCommonData.FeedbackPulseSupported() )
       
   329                 {
       
   330                 // It is plugin or underlying software responsibility to generate pulse start/stop
       
   331                 // and continue ongoing vibration if such exists.
       
   332                 PulseVibraL( duration, intensity, aMessage);
       
   333                 }
       
   334             else
       
   335                 {
       
   336                 // Request another vibration by lefting current timer if such exist intact
       
   337                 // and creating new timer for this pulse request.
       
   338                 StartVibraL( duration, intensity, aMessage, EFalse, ETrue);
       
   339                 }
       
   340                 
       
   341             break;    
       
   342     	    }
       
   343     	case EHWRMStopVibra:
       
   344     	    {
       
   345             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMStopVibra") );
       
   346 
       
   347             StopVibraL(aMessage);            
       
   348     		break;
       
   349     	    }
       
   350     	case EHWRMReserveVibra:
       
   351     	    {
       
   352             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMReserveVibra") );
       
   353             
       
   354             // Reserve whole vibra. If returned mask is non-zero, reservation was done in suspended mode.
       
   355             iSuspended = (iReservationHandler->ReserveL(aMessage, aMessage.Int1(), this, KHWRMAllSubResources));	
       
   356                            
       
   357             iReserved = ETrue;           
       
   358             
       
   359             iStateSetAfterReservation = EFalse;    
       
   360                            
       
   361             // Restore previously stored state if restore was specified.
       
   362             // Errors are trapped as reservation itself was successful.
       
   363             if ( aMessage.Int0() )
       
   364                 {
       
   365                 TInt err(KErrNone);
       
   366                 RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing reservation.
       
   367                 
       
   368                 if ( iFrozenStatus == CHWRMVibra::EVibraStatusOn )
       
   369                     {
       
   370                     TRAP(err, StartVibraL(iFrozenTime, iFrozenIntensity, dummy));
       
   371                     }
       
   372                 else
       
   373                     {
       
   374                     TRAP(err, StopVibraL(dummy));
       
   375                     }
       
   376                 }
       
   377 
       
   378             completeMessage = ETrue; // Complete needed, as dummy used.
       
   379     		break;
       
   380     	    }
       
   381     	case EHWRMReleaseVibra:
       
   382     	    {
       
   383             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMReleaseVibra") );
       
   384 
       
   385 			// If a "Leave" is introduced, consideration must be given to the corresponding
       
   386 			// client side side code which requested this action. In particular, ensure that
       
   387 			// the client-side caller doesn't set its "iReserved" flag to false without 
       
   388 			// checking the result of the Release command.
       
   389         
       
   390             // Release whole vibra. 
       
   391             TInt unreserved = iReservationHandler->Release(this, KHWRMAllSubResources);	
       
   392             
       
   393             iReserved = EFalse;
       
   394             
       
   395             // Clear suspended flag
       
   396             iSuspended = EFalse;
       
   397             
       
   398             // Freeze state
       
   399             iFrozenTime = iVibraTimer->Freeze(); 
       
   400             iFrozenStatus = iLastStatus;
       
   401             iFrozenIntensity = iLastIntensity;
       
   402             
       
   403             // Restore base state if no more reservations for vibra.
       
   404             // Errors are trapped as release itself was successful.
       
   405             if ( unreserved )
       
   406                 {
       
   407                 RMessage2 dummy; // Use dummy to avoid adaptation returned error messages failing release.
       
   408                 TRAP_IGNORE(StopVibraL(dummy));
       
   409                 }
       
   410                 
       
   411             completeMessage = ETrue; // Complete needed, as dummy used.
       
   412     		break;
       
   413     	    }
       
   414         case EHWRMCleanupVibra:
       
   415             {
       
   416             COMPONENT_TRACE1(_L("HWRM Server - CHWRMVibraService::ExecuteMessageL - EHWRMCleanupVibra") );
       
   417 
       
   418             CleanupVibra();
       
   419                 
       
   420             completeMessage = ETrue; // Complete needed, as dummy used in CleanupVibra.
       
   421     		break;
       
   422     	    }
       
   423         // Cannot identify the message, panic the client
       
   424         default:
       
   425             {
       
   426             CHWRMServer::PanicClient(aMessage, EPanicIllegalFunction);
       
   427             break;
       
   428             }
       
   429         }
       
   430 
       
   431     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ExecuteMessageL - return 0x%x" ), completeMessage );
       
   432 
       
   433     return completeMessage;
       
   434     
       
   435    }
       
   436 // -----------------------------------------------------------------------------
       
   437 // CHWRMVibraService::StartVibraL
       
   438 // Starts vibra for duration with specified intensity.
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 void CHWRMVibraService::StartVibraL(const TTimeIntervalMicroSeconds32& aDuration, 
       
   442                                     TInt aIntensity, 
       
   443                                     const RMessage2& aMessage,
       
   444 	                                TBool aSetTimer,
       
   445                                     TBool aPulse)
       
   446 	{
       
   447     
       
   448     COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::StartVibraL(%d, %d, %d, %d)" ),
       
   449     aDuration.Int(), aIntensity, aSetTimer, aPulse );
       
   450 
       
   451 
       
   452     __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
       
   453 
       
   454     // Duration must not be negative.
       
   455     if ( aDuration.Int() < 0 || aDuration.Int() > KHWRMVibraMaxDurationInMicroseconds )
       
   456         {
       
   457         User::Leave(KErrArgument);
       
   458         }
       
   459         
       
   460     // Check vibra/feedback profile settings if not privileged client.
       
   461     // If not pulse request, vibra must be on. If pulse request, feedback must be on.
       
   462     if ( !iPrivilegedClient && 
       
   463         ( ( !aPulse && (iVibraCommonData.VibraState() != CHWRMVibra::EVibraModeON ) ) ||
       
   464           ( aPulse && (iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON) ) ) )        
       
   465     	{
       
   466         // Stop vibra if it needs shutdown.
       
   467         if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
       
   468             {
       
   469             StopVibraL(aMessage);
       
   470             }
       
   471         User::Leave(KErrAccessDenied);
       
   472         }
       
   473     
       
   474     // Check if vibra is cooling off or feedback should be prevented
       
   475     if ( iVibraCommonData.VibraLocked() || (aPulse && VibraPulseBlocked()) )
       
   476         {
       
   477         User::Leave(KErrLocked);
       
   478         }
       
   479            
       
   480 	// Check if vibra is blocked (aPulse means no feedback request)
       
   481     if ( !aPulse &&
       
   482          iVibraCommonData.VibraBlocked() && 
       
   483          iVibraCommonData.VibraBlocked( KHWRMInternalSettingsChargerBlockVibra ) )
       
   484         {
       
   485         User::Leave(KErrLocked);
       
   486         }
       
   487         
       
   488 
       
   489     // Check intensity validity
       
   490     if ( aIntensity != KUseDefaultIntensity && (aIntensity < KHWRMVibraMinIntensity || aIntensity > KHWRMVibraMaxIntensity) )
       
   491         {
       
   492         User::Leave(KErrArgument);
       
   493         }
       
   494         
       
   495     // Check intensity validity for pulse requests
       
   496     if ( aPulse && (aIntensity < KHWRMVibraMinPulseIntensity || aIntensity > KHWRMVibraMaxIntensity) )
       
   497         {
       
   498         User::Leave(KErrArgument);
       
   499         }
       
   500 
       
   501     // Call plugins
       
   502     if ( aIntensity == 0 )
       
   503         {
       
   504         // Stop vibra, if intensity is zero
       
   505         StopVibraL(aMessage);
       
   506         }
       
   507     else
       
   508         {
       
   509         // Start timers, if so specified
       
   510         // This is because when restoring last state, existing timer should be left intact.
       
   511         // Vibra timer is left intact also if pulse requested because new timer is setup.
       
   512         if ( aSetTimer && !aPulse )
       
   513             {
       
   514             iVibraTimer->Set(aDuration);
       
   515             iActiveTimerId = KHWRMVibraTimerID;
       
   516             }
       
   517 
       
   518         if ( aPulse )
       
   519             {
       
   520             // Create new timer with ascending identifier.
       
   521             TInt count( iPulseData.Count() );
       
   522             CHWRMGenericTimer* timer = 
       
   523                 CHWRMGenericTimer::NewL(*this, iVibraCommonData.MaximumOnTime(), count );                                
       
   524             iActiveTimerId = count;
       
   525             CPulseData* pulseData = CPulseData::NewL(*timer, iLastIntensity, aIntensity, iActiveTimerId );
       
   526             CleanupStack::PushL( pulseData );
       
   527             iPulseData.AppendL( pulseData );
       
   528             CleanupStack::Pop( pulseData );
       
   529             iPulseData[count]->Timer().Set(aDuration);
       
   530             }
       
   531 
       
   532 		// complete message if suspended, as there will not be ProcessResponseL
       
   533         if ( iSuspended && aMessage.Handle() )
       
   534             {
       
   535             aMessage.Complete(KErrNone);
       
   536             }
       
   537 
       
   538         // Call plugin if not suspended
       
   539         if ( !iSuspended )
       
   540             {
       
   541             // Check reservation if not pulse request (pulse is blocked earlier if priority
       
   542             // of this client is lower than reserving client).
       
   543             if ( !aPulse && iReservationHandler->IsReserved(this, KHWRMAllSubResources) )
       
   544                 {
       
   545                 User::Leave(KErrInUse);
       
   546                 }
       
   547 
       
   548             // Create new data (TransId is updated later, commandId is not important)
       
   549             THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse); 
       
   550             CleanupStack::PushL( data );
       
   551 
       
   552             if ( aIntensity == KUseDefaultIntensity )
       
   553                 {
       
   554                 // No data, pass empty descriptor
       
   555                 TBuf8<1> emptyDes;
       
   556                 data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId, emptyDes, this);
       
   557                 }
       
   558             else 
       
   559                 {
       
   560                 HWRMVibraCommand::TStartVibraCmdDataPackage dataPckg(aIntensity);    
       
   561                 data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraCmdId, dataPckg, this);    
       
   562                 }
       
   563 
       
   564             // data still needed, do not destroy, just pop
       
   565             CleanupStack::Pop( data );
       
   566             
       
   567             // Add data to list
       
   568             iTransactionList->AddTransaction( data );
       
   569             
       
   570             // Assign request data for common vibra service
       
   571             TVibraClientData clientData( this, iSid, aIntensity );
       
   572             // Control of overlapping pulses/normal vibration requests is in hands of HWRM,
       
   573             // when pulse length is configured to be handled by HWRM. That is why
       
   574             // client data must be set to common vibra service.
       
   575             iCommonService.SetClientData( clientData );
       
   576             
       
   577 
       
   578             iStateSetAfterReservation = ETrue;
       
   579             }
       
   580         }
       
   581         // Store the latest status in case vibra gets suspended before next plugin call.
       
   582         iLastStatus = CHWRMVibra::EVibraStatusOn;
       
   583         iLastIntensity = aIntensity;        
       
   584         
       
   585     	COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StartVibraL - return" ) );    
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // CHWRMVibraService::VibraPulseBlocked
       
   590 // Checks whether vibra pulse should be blocked.
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 TBool CHWRMVibraService::VibraPulseBlocked()
       
   594     {
       
   595     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked" ) );
       
   596     TBool blocked( EFalse );
       
   597     
       
   598     // Check whether vibra cooling off should prevent feedback 
       
   599     if ( iVibraCommonData.VibraLocked() && 
       
   600          iVibraCommonData.VibraBlocked( KHWRMInternalSettingsCoolOffBlockFeedback ) )
       
   601         {
       
   602         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by cool-off" ));
       
   603         blocked = ETrue;
       
   604         }
       
   605 
       
   606     // Check if vibra is blocked and whether it should prevent feedback
       
   607     if ( (iVibraCommonData.VibraBlocked() & KHWRMAccessoryVibraBlocked) && 
       
   608          iVibraCommonData.VibraBlocked( KHWRMInternalSettingsAccessoryBlockFeedback ) )
       
   609         {
       
   610         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by accessory" ) );
       
   611         blocked = ETrue;
       
   612         }
       
   613     if ( (iVibraCommonData.VibraBlocked() & KHWRMInternalVibraBlocked) && 
       
   614          iVibraCommonData.VibraBlocked( KHWRMInternalSettingsChargerBlockFeedback ) )
       
   615         {
       
   616         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::VibraPulseBlocked - blocked by charger" ) );
       
   617         blocked = ETrue;
       
   618         }
       
   619     
       
   620     return blocked;
       
   621     }
       
   622 
       
   623 // -----------------------------------------------------------------------------
       
   624 // CHWRMVibraService::PulseVibraL
       
   625 // Requests vibra pulse with specified intensity and duration.
       
   626 // -----------------------------------------------------------------------------
       
   627 //
       
   628 void CHWRMVibraService::PulseVibraL(const TTimeIntervalMicroSeconds32& aDuration, 
       
   629                                     TInt aIntensity, 
       
   630                                     const RMessage2& aMessage,
       
   631 	                                TBool /* aSetTimer */)
       
   632     {
       
   633     COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::PulseVibraL(%d, %d)" ), aDuration.Int(), aIntensity );
       
   634 
       
   635     __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
       
   636 
       
   637     // Duration must not be negative.
       
   638     if ( aDuration.Int() < 0 || aDuration.Int() > KHWRMVibraMaxDurationInMicroseconds )
       
   639         {
       
   640         User::Leave(KErrArgument);
       
   641         }
       
   642         
       
   643     // Check intensity validity
       
   644     if ( aIntensity < KHWRMVibraMinPulseIntensity || aIntensity > KHWRMVibraMaxIntensity )
       
   645         {
       
   646         User::Leave(KErrArgument);
       
   647         }
       
   648 
       
   649     if( VibraPulseBlocked() )
       
   650         {
       
   651         User::Leave(KErrLocked);
       
   652         }
       
   653     
       
   654     // Check vibra profile setting if not privileged client
       
   655     if ( !iPrivilegedClient && iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON )
       
   656         {
       
   657         // Stop vibra if it needs shutdown.
       
   658         if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
       
   659             {
       
   660             StopVibraL(aMessage);
       
   661             }
       
   662         User::Leave(KErrAccessDenied);
       
   663         }
       
   664 
       
   665     // Finally before sending pulse-command to plugin check that this client
       
   666     // has higher priority than last client requested vibration.
       
   667 
       
   668     // Call plugins
       
   669     if ( aIntensity == 0 )
       
   670         {
       
   671         // Stop vibra, if intensity is zero
       
   672         StopVibraL(aMessage);
       
   673         }
       
   674     else
       
   675         {
       
   676         // There is no timer for real pulse requests, because low level 
       
   677         // implementation must stop the vibra after specified duration.
       
   678         // This will however result in vibra status not being updated.
       
   679         iActiveTimerId = KHWRMVibraNoTimer;
       
   680         
       
   681         // Complete message if suspended, as there will not be ProcessResponseL
       
   682         if ( iSuspended && aMessage.Handle() )
       
   683             {
       
   684             aMessage.Complete(KErrNone);
       
   685             }
       
   686 
       
   687         // Call plugin if not suspended
       
   688         if ( !iSuspended )
       
   689             {
       
   690             // Create new data (TransId is updated later, commandId is not important)
       
   691             THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse); 
       
   692             CleanupStack::PushL( data );
       
   693             HWRMVibraCommand::TVibraData vibraData;
       
   694             vibraData.iIntensity = aIntensity;
       
   695             vibraData.iDuration = aDuration.Int() / 1000;
       
   696             HWRMVibraCommand::TPulseVibraCmdDataPackage dataPckg(vibraData);
       
   697             data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EPulseVibraCmdId, dataPckg, this);
       
   698 
       
   699             // data still needed, do not destroy, just pop
       
   700             CleanupStack::Pop( data );
       
   701             
       
   702             // Add data to list
       
   703             iTransactionList->AddTransaction( data );
       
   704             
       
   705             // Control of overlapping pulses/normal vibration requests is not in hands of HWRM,
       
   706             // when pulse length is configured to be handled by vibra driver. That is why
       
   707             // client data may not be set to common vibra service.
       
   708             
       
   709             iStateSetAfterReservation = ETrue;
       
   710             }
       
   711             
       
   712         // Store the latest status in case vibra gets suspended before next plugin call.
       
   713         iLastStatus = CHWRMVibra::EVibraStatusOn;
       
   714         iLastIntensity = aIntensity;
       
   715         }
       
   716         
       
   717     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::PulseVibraL - return" ) );
       
   718     
       
   719     }
       
   720 
       
   721 
       
   722 // -----------------------------------------------------------------------------
       
   723 // CHWRMVibraService::StopVibraL
       
   724 // Stops vibra. No harm calling this just in case 
       
   725 // even if vibra is already stopped.
       
   726 // -----------------------------------------------------------------------------
       
   727 //
       
   728 void CHWRMVibraService::StopVibraL(const RMessage2& aMessage, 
       
   729                                    TBool aForceStop,
       
   730                                    TBool aFinalStop)
       
   731     {
       
   732     COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::StopVibraL(%d,%d)" ), aForceStop, aFinalStop );
       
   733 
       
   734     __ASSERT_ALWAYS(iPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle));
       
   735 
       
   736     TBool forceStop(aForceStop);
       
   737 
       
   738     // Stop any ongoing timers
       
   739     iVibraTimer->Cancel();   
       
   740     
       
   741      ReleasePulseData();
       
   742     // Reset this service's client data.
       
   743     // This way any other (if any) service's interrupted vibration is restarted.
       
   744     iCommonService.ResetClientData( this );
       
   745 
       
   746        
       
   747 
       
   748     // Check from active reserver if it is ok for them that we stop vibra. 
       
   749     // This is necessary if active reserver is just reserving vibra but hasn't set vibra state explicitly
       
   750     // after reservation. Otherwise it is possible that vibra will be left on forever.
       
   751     // Note: This will sometimes result in unnecessary stop calls from suspended sessions when active session has not
       
   752     //       explicitly set vibra on/off, but this is the only way to ensure that the necessary stop calls go through.
       
   753     CHWRMService* activeReserver = iReservationHandler->GetActiveReserver(KHWRMAllSubResources);
       
   754     if ( activeReserver )
       
   755         {
       
   756         if ( (static_cast<CHWRMVibraService*>(activeReserver)) == this )
       
   757             {
       
   758             COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - This session is active reserver, no need to force stop.") );
       
   759             }
       
   760         else if ( (static_cast<CHWRMVibraService*>(activeReserver))->OkToStopVibra() )
       
   761             {
       
   762             COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - Active reserver has not used vibra since reservation - Force stop vibra.") );
       
   763             forceStop = ETrue;
       
   764             }
       
   765         else
       
   766             {
       
   767             COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - Active reserver has been using vibra after reservation, no need to force stop.") );
       
   768             }
       
   769         }
       
   770     else
       
   771         {
       
   772         COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - No active reserver found, no need to force stop.") );
       
   773         }
       
   774 
       
   775     if ( forceStop || !iSuspended )
       
   776         {
       
   777         // Check reservation.
       
   778         if ( !forceStop && iReservationHandler->IsReserved(this, KHWRMAllSubResources) )
       
   779             {
       
   780             User::Leave(KErrInUse);
       
   781             }
       
   782 
       
   783         // create new data (TransId is updated later)
       
   784         THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(aMessage, 0, 0, EFalse); // commandId is not important
       
   785         CleanupStack::PushL( data );
       
   786 
       
   787         // No data, pass empty descriptor
       
   788         TBuf8<1> emptyDes;
       
   789 
       
   790         // Do not require callback on final stopping of vibra    
       
   791         CHWRMService* callback = NULL;
       
   792         if ( !aFinalStop )
       
   793             {
       
   794             callback = this;
       
   795             }
       
   796 
       
   797         data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStopVibraCmdId, emptyDes, callback);
       
   798     	
       
   799         // data still needed, do not destroy, just pop
       
   800         CleanupStack::Pop( data );
       
   801         
       
   802         // Add data to list
       
   803         iTransactionList->AddTransaction( data );
       
   804         
       
   805         iStateSetAfterReservation = ETrue;
       
   806         }
       
   807     else
       
   808         {
       
   809         // complete message if suspended, as there will not be ProcessResponseL
       
   810         if ( aMessage.Handle() )
       
   811             {
       
   812             aMessage.Complete(KErrNone);
       
   813             }        
       
   814         }
       
   815         
       
   816     // Store the latest status in case vibra gets suspended before next plugin call.
       
   817     iLastStatus = CHWRMVibra::EVibraStatusStopped;
       
   818         
       
   819     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::StopVibraL - return" ) );
       
   820     
       
   821     }
       
   822     
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CHWRMVibraService::ProcessResponseL
       
   826 // Handles Vibra requests responses.
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 void CHWRMVibraService::ProcessResponseL( TInt aCommandId,  TUint8 aTransId, TDesC8& aData, TBool aTimeout)
       
   830     {
       
   831     COMPONENT_TRACE4(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL(0x%x, 0x%x, <data>, 0x%x)" ), aCommandId, aTransId, aTimeout );
       
   832 
       
   833     TInt pluginErr(KErrNone);  // Error came from plugin as data (or timeout). Used to complete RMessage.
       
   834     TInt contextErr(KErrNone);  // Error in context, i.e. bad handle or descriptor. Used to leave.
       
   835 
       
   836     // Unpack the package. All vibra messages contain only possible error code
       
   837     // in return package.
       
   838     if ( !aTimeout && aData.Size() != sizeof(TInt) )
       
   839         {
       
   840         COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - Data size mismatch, expected: 0x%x, got 0x%x" ), sizeof(TInt), aData.Size() );
       
   841         contextErr = KErrBadDescriptor;
       
   842         pluginErr = KErrBadDescriptor;
       
   843         }      
       
   844     else
       
   845         {        
       
   846         // If response was caused by timeout, set that as the error.
       
   847         // Timeout handled this way instead of just returning KErrTimeout in aData because
       
   848         // aData format is not known in plugin handler and in theoretically some new commands
       
   849         // may also return different response than just error code in future.
       
   850         if ( aTimeout )
       
   851             {
       
   852             pluginErr = KErrTimedOut;            
       
   853             }
       
   854         else
       
   855             {
       
   856             HWRMVibraCommand::TErrorCodeResponsePackage errPckg;
       
   857             errPckg.Copy(aData);
       
   858             pluginErr = errPckg();
       
   859             }
       
   860 
       
   861         if ( pluginErr != KErrNone )
       
   862             {
       
   863             COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - Error: %d" ), pluginErr );        
       
   864             }
       
   865 
       
   866         // Update vibra status PS state value 
       
   867         if ( !iPrivilegedClient  && 
       
   868             ( ( (iActiveTimerId == KHWRMVibraTimerID) && (iVibraCommonData.VibraState() != CHWRMVibra::EVibraModeON ) ) ||
       
   869               ( (iActiveTimerId != KHWRMVibraTimerID) && (iVibraCommonData.VibraFeedbackState() != CHWRMVibra::EVibraFeedbackModeON) ) ) )
       
   870         	{
       
   871             // This can presumably happen if there was ongoing plugin call when 
       
   872             // vibra was turned off.
       
   873             iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusNotAllowed, iPrivilegedClient);	
       
   874             
       
   875             // Set vibra timer for immediate shutdown if commandid was not stop
       
   876             if ( aCommandId != HWRMVibraCommand::EStopVibraCmdId )
       
   877                 {
       
   878                 iVibraTimer->Set(1);
       
   879                 ReleasePulseData();
       
   880                 }
       
   881             }
       
   882         else
       
   883             {       
       
   884             if ( pluginErr != KErrNone )
       
   885                 {
       
   886                 iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusUnknown, iPrivilegedClient);	
       
   887                 }
       
   888             else
       
   889                 {
       
   890                 switch ( aCommandId )
       
   891                     {
       
   892                     case HWRMVibraCommand::EStartVibraCmdId:
       
   893                         {
       
   894                         iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);	    
       
   895                         break;
       
   896                         }
       
   897                     case HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId:
       
   898                         {
       
   899                         iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);	    
       
   900                         break;
       
   901                         }
       
   902 						case HWRMVibraCommand::EPulseVibraCmdId:
       
   903                         {
       
   904                         // It may cause quite a lot of overhead to publish vibra status for short pulses.
       
   905                         // iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusOn, iPrivilegedClient);	    
       
   906                         break;
       
   907                         }
       
   908 
       
   909                     case HWRMVibraCommand::EStopVibraCmdId:
       
   910                         {
       
   911                         iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusStopped, iPrivilegedClient);	    
       
   912                         break;
       
   913                         }
       
   914                     default:
       
   915                         {
       
   916                         iVibraCommonData.PublishVibraStatus(CHWRMVibra::EVibraStatusUnknown, iPrivilegedClient);	    
       
   917                         break;
       
   918                         }
       
   919                     }
       
   920                 }
       
   921             }
       
   922         }
       
   923         
       
   924     // Complete request and remove delete transaction
       
   925     contextErr = CompleteRequest(aTransId, pluginErr);    
       
   926 
       
   927     // Leave if there is error in context    
       
   928     User::LeaveIfError(contextErr);
       
   929 
       
   930     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ProcessResponseL - return" ) );
       
   931     }
       
   932 
       
   933     
       
   934 // -----------------------------------------------------------------------------
       
   935 // CHWRMVibraService::GenericTimerFired
       
   936 // Handles vibra cutoff timer firing. Adjust vibra intensity and stops vibra.
       
   937 // There is only one regular vibra timer active at a time. It is used for vibra start calls.
       
   938 // If vibra pulse is requested, new timer is setup. If pulse timer expires and vibra or any other 
       
   939 // pulse timer is still active, vibration intensity must be adjusted accordingly. If all pulse 
       
   940 // timers and vibra timer have expired, stop vibra.
       
   941 // -----------------------------------------------------------------------------
       
   942 //
       
   943 void CHWRMVibraService::GenericTimerFired(TInt aTimerId, TBool aCutOff)
       
   944     {
       
   945     COMPONENT_TRACE5( _L( "HWRM Server - CHWRMVibraService::GenericTimerFired, iLastIntensity %d, iActiveTimerId %d, aTimerId %d, aCutOff %d" ),
       
   946         iLastIntensity, iActiveTimerId, aTimerId, aCutOff );
       
   947 
       
   948     // if cutoff because maximum ontime set the lock period
       
   949     if ( aCutOff )
       
   950         {
       
   951         iVibraCommonData.LockVibra();
       
   952         }
       
   953         
       
   954 	RMessage2 dummy;
       
   955     TInt err(KErrNone);
       
   956     TInt count( iPulseData.Count() );
       
   957     TBool changeIntensity( EFalse );
       
   958     TBool pulseTimersActive( EFalse );
       
   959     TBool succeedingFound( EFalse );
       
   960     
       
   961     if( aTimerId < count )
       
   962         {
       
   963         // Update last intensity from expired pulse timer to ACTIVE timer succeeding it,
       
   964         // because otherwise it has old information about intensity, which must
       
   965         // be set when it expires. This works, because timer objects only need to 
       
   966         // remember last intensity. If timer expires, but it is not "active" one, then
       
   967         // intensity is not changed and intensity if just passed to next one in queue.
       
   968         for( TInt i = aTimerId+1; i < count; i++ )
       
   969             {
       
   970             if( iPulseData[i]->Timer().IsActive() )
       
   971                 {
       
   972                 COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgrading last intensity from %d (%d) to %d (%d) "),
       
   973                     aTimerId, iPulseData[aTimerId]->LastIntensity(), i, iPulseData[i]->LastIntensity() );
       
   974                 COMPONENT_TRACE5(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgrading timer id from %d (%d) to %d (%d) " ), 
       
   975                     aTimerId, iPulseData[aTimerId]->LastTimerId(), i, iPulseData[i]->LastTimerId() );
       
   976                 iPulseData[i]->SetLastIntensity( iPulseData[aTimerId]->LastIntensity() );
       
   977                 iPulseData[i]->SetLastTimerId( iPulseData[aTimerId]->LastTimerId() );
       
   978                 succeedingFound = ETrue;
       
   979                 break;
       
   980                 }
       
   981             }
       
   982         }
       
   983 
       
   984     // Check if any pulse timers active
       
   985     for( TInt i = 0; i < count; i++ )
       
   986         {
       
   987         COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - pulse timer %d status: %d" ), i, iPulseData[i]->Timer().IsActive() );
       
   988         if( iPulseData[i]->Timer().IsActive() )
       
   989             {
       
   990             pulseTimersActive = ETrue;
       
   991             }
       
   992         }
       
   993 
       
   994     COMPONENT_TRACE2( _L( "HWRM Server - CHWRMVibraService::GenericTimerFired - vibra timer status: %d" ), iVibraTimer->IsActive() );
       
   995 
       
   996     // If timer expired is not last active timer, we must not change intensity,
       
   997     // because intensity has been changed when new timer setup and intensity
       
   998     // gets updated only if it expires or new pulse request arrives.
       
   999     if( aTimerId == iActiveTimerId )
       
  1000         {
       
  1001         changeIntensity = ETrue;
       
  1002         
       
  1003         if( (aTimerId == KHWRMVibraTimerID || !succeedingFound) && pulseTimersActive )
       
  1004             {
       
  1005             // If active timer expired was vibra timer or succeeding (=active) pulse timer was not found
       
  1006             // and there are still active pulse timers, update timer id and intensity accordingly.
       
  1007             // First pulse timer from end is new active.
       
  1008             for( TInt i = count-1; i >= 0; i-- )
       
  1009                 {
       
  1010                 if( iPulseData[i]->Timer().IsActive() )
       
  1011                     {
       
  1012                     iActiveTimerId = i;
       
  1013                     iLastIntensity = iPulseData[i]->Intensity();
       
  1014                     COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgraded active timer id to %d and intensity to %d" ),
       
  1015                         iActiveTimerId, iLastIntensity );
       
  1016                     break;
       
  1017                     }
       
  1018                 }
       
  1019             }
       
  1020         else if( aTimerId != KHWRMVibraTimerID && iVibraTimer->IsActive() && !pulseTimersActive )
       
  1021             {
       
  1022             // If active timer expired was not vibra timer and it still active and no more pulse 
       
  1023             // timers, update timer id and intensity accordingly
       
  1024             iActiveTimerId = KHWRMVibraTimerID;
       
  1025             if( aTimerId < count )
       
  1026                 {
       
  1027                 iLastIntensity = iPulseData[aTimerId]->LastIntensity();
       
  1028                 }
       
  1029             COMPONENT_TRACE3(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - upgraded active timer id to %d and intensity to %d" ), 
       
  1030                 iActiveTimerId, iLastIntensity );
       
  1031             }
       
  1032         else
       
  1033             {
       
  1034             COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - active timer id and intensity not updated" ) ); 
       
  1035             }
       
  1036         }
       
  1037 
       
  1038     if( !pulseTimersActive )
       
  1039         {
       
  1040         // Remove expired pulse timers
       
  1041         ReleasePulseData();
       
  1042         }
       
  1043     
       
  1044     // If cutoff or there are no active timers left, stop vibra
       
  1045     if( aCutOff || (!pulseTimersActive && !iVibraTimer->IsActive()) )
       
  1046         {
       
  1047         TRAP(err, StopVibraL(dummy));
       
  1048     
       
  1049         if ( err != KErrNone )
       
  1050             {
       
  1051             COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - Error Stopping vibra: %d" ), err );
       
  1052             }
       
  1053         }
       
  1054     else if( changeIntensity )
       
  1055         {
       
  1056         TRAP(err, ChangeVibraIntensityL());
       
  1057     
       
  1058         if ( err != KErrNone )
       
  1059             {
       
  1060             COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - Error changing intensity: %d" ), err );
       
  1061             }
       
  1062         }
       
  1063 
       
  1064     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::GenericTimerFired - return" ) );
       
  1065     
       
  1066     }
       
  1067     
       
  1068 // -----------------------------------------------------------------------------
       
  1069 // CHWRMVibraService::ChangeVibraIntensityL
       
  1070 // Changes the device vibration intensity to previous active intensity.
       
  1071 // -----------------------------------------------------------------------------
       
  1072 //
       
  1073 void CHWRMVibraService::ChangeVibraIntensityL()
       
  1074     {
       
  1075     COMPONENT_TRACE2(_L( "HWRM Server - CHWRMVibraService::ChangeVibraIntensityL() - new intensity %d" ), iLastIntensity );
       
  1076 
       
  1077 	// Ignore Coverity false positive as uninitialized variable.
       
  1078 	// Since no response is sent back to the client, only a empty message is created here. 
       
  1079 	// Message handle of this will be initialized to NULL in the default constructor.
       
  1080 	// coverity[var_decl]
       
  1081 	RMessage2 dummy;
       
  1082     
       
  1083     // Create new data (TransId is updated later, commandId is not important)
       
  1084     THWRMPluginRequestData* data = new (ELeave) THWRMPluginRequestData(dummy, 0, 0, EFalse); 
       
  1085     CleanupStack::PushL( data );
       
  1086 
       
  1087     if ( iLastIntensity == KUseDefaultIntensity )
       
  1088         {
       
  1089         // No data, pass empty descriptor
       
  1090         TBuf8<1> emptyDes;
       
  1091         data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraWithDefaultSettingsCmdId, emptyDes, this);
       
  1092         }
       
  1093     else 
       
  1094         {
       
  1095         HWRMVibraCommand::TStartVibraCmdDataPackage dataPckg(iLastIntensity);    
       
  1096         data->iTransId = iPluginHandler->ProcessCommandL(HWRMVibraCommand::EStartVibraCmdId, dataPckg, this);    
       
  1097         }
       
  1098 
       
  1099     // data still needed, do not destroy, just pop
       
  1100     CleanupStack::Pop( data );
       
  1101 
       
  1102     // Add data to list
       
  1103     iTransactionList->AddTransaction( data );
       
  1104     }
       
  1105     
       
  1106 
       
  1107     
       
  1108 // -----------------------------------------------------------------------------
       
  1109 // CHWRMVibraService::SuspendSubResource
       
  1110 // Suspends vibra. Since vibra has no subresources, whole vibra is affected.
       
  1111 // -----------------------------------------------------------------------------
       
  1112 //
       
  1113 void CHWRMVibraService::SuspendSubResource(TInt /*aSubResource*/)
       
  1114     {
       
  1115     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::SuspendSubResource()" ) );
       
  1116     
       
  1117     if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
       
  1118         {
       
  1119         // Resume base state, i.e. stop vibra
       
  1120         RMessage2 dummy;
       
  1121         TRAP_IGNORE(StopVibraL(dummy));
       
  1122             
       
  1123         // Restore iLastStatus
       
  1124         iLastStatus = CHWRMVibra::EVibraStatusOn;
       
  1125         }
       
  1126     
       
  1127     iSuspended = ETrue;
       
  1128     
       
  1129     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::SuspendSubResource - return" ) );
       
  1130     }
       
  1131     
       
  1132 // -----------------------------------------------------------------------------
       
  1133 // CHWRMVibraService::ResumeSubResource
       
  1134 // Resumes vibra. Since vibra has no subresources, whole vibra is affected.
       
  1135 // -----------------------------------------------------------------------------
       
  1136 //
       
  1137 void CHWRMVibraService::ResumeSubResource(TInt /*aSubResource*/)
       
  1138     {
       
  1139     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ResumeSubResource()" ) );
       
  1140     
       
  1141     iSuspended = EFalse;
       
  1142     
       
  1143     RMessage2 dummy;
       
  1144     
       
  1145     // Restore last state
       
  1146     TInt err(KErrNone);
       
  1147     if ( iLastStatus == CHWRMVibra::EVibraStatusOn )
       
  1148         {
       
  1149         TRAP(err, StartVibraL(0, iLastIntensity, dummy, EFalse));
       
  1150         }
       
  1151     else
       
  1152         {
       
  1153         TRAP(err, StopVibraL(dummy));
       
  1154         }
       
  1155 
       
  1156     COMPONENT_TRACE1(_L( "HWRM Server - CHWRMVibraService::ResumeSubResource - return" ) );
       
  1157     }
       
  1158 
       
  1159 // -----------------------------------------------------------------------------
       
  1160 // CHWRMVibraService::ActivateSubResource
       
  1161 // Vibra doesn't support activation/deactivation based on device state
       
  1162 // -----------------------------------------------------------------------------
       
  1163 //
       
  1164 void CHWRMVibraService::ActivateSubResource(TInt /*aSubResource*/, TBool /*aActivate*/)
       
  1165     {
       
  1166     // Do nothing
       
  1167     }
       
  1168 
       
  1169 // -----------------------------------------------------------------------------
       
  1170 // CHWRMVibraService::OkToStopVibra
       
  1171 // Checks if it is ok to stop vibra from another session.
       
  1172 // -----------------------------------------------------------------------------
       
  1173 //
       
  1174 TBool CHWRMVibraService::OkToStopVibra()
       
  1175     {
       
  1176     return !iStateSetAfterReservation;
       
  1177     }
       
  1178 
       
  1179 
       
  1180 // -----------------------------------------------------------------------------
       
  1181 // CPulseData::CPulseData
       
  1182 // -----------------------------------------------------------------------------
       
  1183 //
       
  1184 
       
  1185 
       
  1186 CHWRMVibraService::CPulseData::CPulseData( CHWRMGenericTimer& aVibraTimer,
       
  1187                                            const TInt aLastIntensity, 
       
  1188                                            const TInt aIntensity,
       
  1189                                            const TInt aLastTimerId )
       
  1190     :iVibraTimer(aVibraTimer),
       
  1191     iLastIntensity(aLastIntensity),
       
  1192     iIntensity(aIntensity),
       
  1193     iLastTimerId(aLastTimerId)
       
  1194     {
       
  1195     COMPONENT_TRACE1(_L( "HWRM Server - CPulseData::CPulseData()" ) );
       
  1196     }
       
  1197 
       
  1198 
       
  1199 
       
  1200 // -----------------------------------------------------------------------------
       
  1201 // CPulseData::NewL
       
  1202 // -----------------------------------------------------------------------------
       
  1203 //
       
  1204 CHWRMVibraService::CPulseData* 
       
  1205 CHWRMVibraService::CPulseData::NewL( CHWRMGenericTimer& aVibraTimer,
       
  1206                               const TInt aLastIntensity, 
       
  1207                               const TInt aIntensity,
       
  1208                               const TInt aLastTimerId )
       
  1209     {
       
  1210     COMPONENT_TRACE4(_L( "HWRM Server - CPulseData::NewL(0x%x, %d, %d)" ), &aVibraTimer, aLastIntensity, aIntensity);
       
  1211 
       
  1212     CPulseData* self = new( ELeave ) 
       
  1213         CPulseData(aVibraTimer, aLastIntensity, aIntensity, aLastTimerId);
       
  1214     
       
  1215     COMPONENT_TRACE2(_L( "HWRM Server - CPulseData::NewL - return 0x%x" ), self);
       
  1216     
       
  1217     return self;
       
  1218     }
       
  1219 
       
  1220 // -----------------------------------------------------------------------------
       
  1221 // CPulseData::~CPulseData
       
  1222 // -----------------------------------------------------------------------------
       
  1223 //
       
  1224 CHWRMVibraService::CPulseData::~CPulseData()
       
  1225     {
       
  1226     COMPONENT_TRACE1(_L("HWRM Server - CPulseData::~CPulseData()"));
       
  1227 
       
  1228     iVibraTimer.Cancel();
       
  1229     }
       
  1230         
       
  1231 // -----------------------------------------------------------------------------
       
  1232 // CPulseData::Timer
       
  1233 // -----------------------------------------------------------------------------
       
  1234 //
       
  1235 CHWRMGenericTimer& CHWRMVibraService::CPulseData::Timer() const
       
  1236     {
       
  1237     return iVibraTimer;
       
  1238     }
       
  1239             
       
  1240 
       
  1241 // -----------------------------------------------------------------------------
       
  1242 // CPulseData::LastIntensity
       
  1243 // -----------------------------------------------------------------------------
       
  1244 //
       
  1245 TInt CHWRMVibraService::CPulseData::LastIntensity() const
       
  1246     {
       
  1247     return iLastIntensity;
       
  1248     }
       
  1249             
       
  1250 // -----------------------------------------------------------------------------
       
  1251 // CPulseData::Intensity
       
  1252 // -----------------------------------------------------------------------------
       
  1253 //
       
  1254 TInt CHWRMVibraService::CPulseData::Intensity() const
       
  1255     {
       
  1256     return iIntensity;
       
  1257     }
       
  1258 
       
  1259 // -----------------------------------------------------------------------------
       
  1260 // CPulseData::SetLastIntensity
       
  1261 // -----------------------------------------------------------------------------
       
  1262 //
       
  1263 void CHWRMVibraService::CPulseData::SetLastIntensity(TInt aIntensity)
       
  1264     {
       
  1265     iLastIntensity = aIntensity;
       
  1266     }
       
  1267 
       
  1268 // -----------------------------------------------------------------------------
       
  1269 // CPulseData::LastTimerId
       
  1270 // -----------------------------------------------------------------------------
       
  1271 //
       
  1272 TInt CHWRMVibraService::CPulseData::LastTimerId() const
       
  1273     {
       
  1274     return iLastTimerId;
       
  1275     }
       
  1276 
       
  1277 // -----------------------------------------------------------------------------
       
  1278 // CPulseData::SetLastTimerId
       
  1279 // -----------------------------------------------------------------------------
       
  1280 //
       
  1281 void CHWRMVibraService::CPulseData::SetLastTimerId(TInt aTimerId)
       
  1282     {
       
  1283     iLastTimerId = aTimerId;
       
  1284     }
       
  1285     
       
  1286 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1287 
       
  1288 //  End of File