systemswstubs/hwrmhapticsstubplugin/src/hwrmhapticsstubplugin.cpp
changeset 5 6ac4a04c9b06
child 16 cee235f8aa57
equal deleted inserted replaced
4:ac37d08cf88d 5:6ac4a04c9b06
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Haptics test (adaptation) plugin implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <s32mem.h>
       
    20 #include <hwrmhapticscommands.h>
       
    21 #include "hwrmhapticsstubplugin.h"
       
    22 
       
    23 // ---------------------------------------------------------------------------
       
    24 // Static instantiation method.
       
    25 // ---------------------------------------------------------------------------
       
    26 //
       
    27 CHWRMHapticsStubPlugin* CHWRMHapticsStubPlugin::NewL( 
       
    28                                     MHWRMHapticsPluginCallback* aCallback )
       
    29     {
       
    30     CHWRMHapticsStubPlugin* self = 
       
    31         new ( ELeave ) CHWRMHapticsStubPlugin( aCallback );
       
    32     CleanupStack::PushL( self );
       
    33     self->ConstructL();
       
    34     CleanupStack::Pop( self );
       
    35     return self;
       
    36     }
       
    37 
       
    38 // ---------------------------------------------------------------------------
       
    39 // Destructor
       
    40 // ---------------------------------------------------------------------------
       
    41 //
       
    42 CHWRMHapticsStubPlugin::~CHWRMHapticsStubPlugin()
       
    43     {
       
    44     iResponders.ResetAndDestroy();
       
    45 
       
    46     if ( iIdle )
       
    47         {
       
    48         iIdle->Cancel();
       
    49         delete iIdle;
       
    50         }
       
    51     }
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // Implementation of ProcessCommandL. Creates an idle responder and appends it
       
    55 // to the array of idle responders. (Later then, when the responder gets 
       
    56 // runtime, it will initiate the response generation).
       
    57 // ---------------------------------------------------------------------------
       
    58 //
       
    59 void CHWRMHapticsStubPlugin::ProcessCommandL( TInt aCommandId,
       
    60                                               TUint8 aTransId,
       
    61                                               TDesC8& aData )
       
    62     {
       
    63     if ( aCommandId != HWRMHapticsCommand::EHapticsCmdId ||
       
    64          aData.Size() < 2 ) // minimum length check
       
    65         {
       
    66         User::Leave( KErrBadDescriptor );
       
    67         }
       
    68         
       
    69     TUint8* dataPtr = const_cast<TUint8*>( aData.Ptr() );
       
    70     
       
    71     if ( !dataPtr )
       
    72         {
       
    73         User::Leave( KErrBadDescriptor );
       
    74         }
       
    75     
       
    76     CHWRMHapticsStubPluginIdleResponder* responder = 
       
    77         CHWRMHapticsStubPluginIdleResponder::NewL( this, aTransId, dataPtr );
       
    78     CleanupStack::PushL( responder );
       
    79     iResponders.AppendL( responder );
       
    80     CleanupStack::Pop ( responder );
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // Implementation of CancelCommandL. Just removes the corresponding idle 
       
    85 // responder.
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 void CHWRMHapticsStubPlugin::CancelCommandL( TUint8 aTransId, 
       
    89                                              TInt /* aCommandId */ )
       
    90     {
       
    91     RemoveResponder( aTransId );
       
    92     }
       
    93 
       
    94 
       
    95 // ---------------------------------------------------------------------------
       
    96 // Method that does the actual response generation towards the issuer of 
       
    97 // command i.e., the HapticsPluginManager
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 void CHWRMHapticsStubPlugin::GenerateResponseL( TUint8 aTransId,
       
   101                                                 TUint8* aData )
       
   102     {
       
   103     // Hardcoded responses generated based on the command code (first 2 bytes
       
   104     // of the aData data packet, but since at the moment the 2nd byte is 
       
   105     // always 0x00, we just use the 1st one)
       
   106     TUint8 command = aData[0];
       
   107 
       
   108     TBuf8<KHWRMHapticsRespMaxSize> binRespData;
       
   109     binRespData.SetLength( KHWRMHapticsRespMaxSize );
       
   110     
       
   111     TInt i( 0 );
       
   112     // For each command the response data's first two bytes are copy of
       
   113     // the received command code (first 2 bytes of aData).
       
   114     
       
   115     binRespData[i++] = aData[0]; // command code bits 0..7
       
   116     binRespData[i++] = aData[1]; // command code bits 8..15
       
   117     
       
   118     switch ( command )
       
   119         {
       
   120         case 0x00: // API version query
       
   121             {
       
   122             // Response to API version query contains:
       
   123             //      1 byte major version number
       
   124             //      1 byte minor version number
       
   125             //      2 bytes for build version
       
   126             binRespData[i++] = 0x02; // major version
       
   127             binRespData[i++] = 0x00; // minor version
       
   128             binRespData[i++] = 0x53; // build version bits 0..7
       
   129             binRespData[i++] = 0x04; // build version bits 8..15
       
   130             break;    
       
   131             }
       
   132 
       
   133         case 0x01: // Initialize
       
   134         case 0x02: // Terminate
       
   135         case 0x06: // Modify basis effect
       
   136         case 0x07: // Stop effect
       
   137         case 0x08: // Stop all effects
       
   138         case 0x0B: // Reset debug buffer
       
   139         case 0x0C: // Stop designed bridge
       
   140         case 0x13: // Close device
       
   141         case 0x14: // Start designed bridge
       
   142         case 0x16: // Play streaming sample
       
   143         case 0x18: // Destroy streaming effect
       
   144         case 0x19: // Pause playing effect
       
   145         case 0x1A: // Resume playing effect
       
   146         case 0x1E: // Modify magsweep effect
       
   147         case 0x1F: // Modify periodic effect
       
   148             {
       
   149             // For these commands the response only contains status byte 
       
   150             // (set to 0x00 ("Success") in this stub).
       
   151             binRespData[i++] = 0x00; // status
       
   152             break;
       
   153             }
       
   154  
       
   155         case 0x03: // Play basis effect
       
   156         case 0x04: // Play IVT effect (with IVT data)
       
   157         case 0x05: // Play IVT effect (without IVT data)
       
   158         case 0x17: // Create streaming effect
       
   159         case 0x1C: // Play magsweep effect
       
   160         case 0x1D: // Play periodic effect
       
   161             {
       
   162             // The response consists of status byte (0x00) and 4-byte long
       
   163             // effectHandle (here hardcoded as 0x01000000)
       
   164             binRespData[i++] = 0x00; // status
       
   165             binRespData[i++] = 0x01; // effectHandle bits 0..7
       
   166             binRespData[i++] = 0x00; // effectHandle bits 8..15
       
   167             binRespData[i++] = 0x00; // effectHandle bits 16..23
       
   168             binRespData[i++] = 0x00; // effectHandle bits 24..31
       
   169             break;    
       
   170             }
       
   171             
       
   172         case 0x09: // Get device capabilities
       
   173             {
       
   174             // The response consists of status byte (0x00), 4-byte long
       
   175             // capability type (copied from the received command (bytes 
       
   176             // 7..10)), 1-byte capability  value type (copied from the 
       
   177             // received command (byte 2), 1-byte size byte and "size" bytes
       
   178             // long value
       
   179             binRespData[i++] = 0x00;      // status
       
   180             binRespData[i++] = aData[7];  // capability type bits 0..7
       
   181             binRespData[i++] = aData[8];  // capability type bits 8..15
       
   182             binRespData[i++] = aData[9];  // capability type bits 16..23
       
   183             binRespData[i++] = aData[10]; // capability type bits 24..31
       
   184             binRespData[i++] = aData[2];  // capability value type
       
   185             // The size and value depend on what exactly is being queried
       
   186             // Note: Currently only the lowest (0..7) bytes of capability
       
   187             //       type have meaning, thus the switch case below is 
       
   188             //       simplified..
       
   189             // Note: Since all values, except device name, are actually 32-bit
       
   190             //       integers, their size is always 4.
       
   191             TUint8 capabilityType = aData[7];
       
   192             switch ( capabilityType )
       
   193                 {
       
   194                 case 0: // device category
       
   195                     {
       
   196                     binRespData[i++] = 0x04; // size
       
   197                     binRespData[i++] = 0x02;
       
   198                     binRespData[i++] = 0x00;
       
   199                     binRespData[i++] = 0x00;
       
   200                     binRespData[i++] = 0x00; // value - virtual device
       
   201                     break;    
       
   202                     }
       
   203                 case 1: // max nested repeats
       
   204                 case 2: // num of actuators
       
   205                 case 4: // num of effect slots
       
   206                 case 6: // min period
       
   207                     {
       
   208                     binRespData[i++] = 0x04; // size
       
   209                     binRespData[i++] = 0x01;
       
   210                     binRespData[i++] = 0x00;
       
   211                     binRespData[i++] = 0x00;
       
   212                     binRespData[i++] = 0x00; // value - 0x1
       
   213                     break;  
       
   214                     }
       
   215                 case 3: // actuator type
       
   216                     {
       
   217                     binRespData[i++] = 0x04; // size
       
   218                     binRespData[i++] = 0x00;
       
   219                     binRespData[i++] = 0x00;
       
   220                     binRespData[i++] = 0x00;
       
   221                     binRespData[i++] = 0x00; // value - ERM actuator
       
   222                     break;    
       
   223                     }
       
   224                 case 5: // supported styles
       
   225                     {
       
   226                     binRespData[i++] = 0x04; // size
       
   227                     binRespData[i++] = 0x07;
       
   228                     binRespData[i++] = 0x00;
       
   229                     binRespData[i++] = 0x00;
       
   230                     binRespData[i++] = 0x00; // value - all styles   
       
   231                     break;
       
   232                     }
       
   233                 case 7:  // max period 
       
   234                 case 8:  // max effect duration
       
   235                 case 11: // max envelope time
       
   236                 case 13: // max IVT file size (tethered)
       
   237                 case 14: // max IVT file size
       
   238                     {
       
   239                     binRespData[i++] = 0x04; // size
       
   240                     binRespData[i++] = 0xFF;
       
   241                     binRespData[i++] = 0xFF;
       
   242                     binRespData[i++] = 0x00; // 
       
   243                     binRespData[i++] = 0x00; // value => 0xFFFF.
       
   244                     break;    
       
   245                     }
       
   246                 case 9: // supported effects
       
   247                     {
       
   248                     binRespData[i++] = 0x04; // size
       
   249                     binRespData[i++] = 0x07;
       
   250                     binRespData[i++] = 0x00;
       
   251                     binRespData[i++] = 0x00;
       
   252                     binRespData[i++] = 0x00; // value - mag|per|timeline   
       
   253                     break;
       
   254                     }
       
   255                 case 10: // device name
       
   256                     {
       
   257                     binRespData[i++] = 0x04;  // size
       
   258                     binRespData[i++] = 0x52;  // value - byte 1, ascii "S"
       
   259                     binRespData[i++] = 0x53;  // value - byte 2, ascii "T"
       
   260                     binRespData[i++] = 0x54;  // value - byte 3, ascii "U"
       
   261                     binRespData[i++] = 0x42;  // value - byte 4, ascoo "B"
       
   262                     break;   
       
   263                     }
       
   264                 case 12: // API version number
       
   265                     {
       
   266                     binRespData[i++] = 0x04; // size
       
   267                     binRespData[i++] = 0x02;
       
   268                     binRespData[i++] = 0x00;
       
   269                     binRespData[i++] = 0x00;
       
   270                     binRespData[i++] = 0x00; // value - API version 
       
   271                                              // Note: same as major version in
       
   272                                              // specific API version query
       
   273                                              // 0x2
       
   274                     break;
       
   275                     }
       
   276                 default:
       
   277                     {
       
   278                     // Here status byte changed to -6 (0xFA)
       
   279                     // ("incompatible capability type")
       
   280                     binRespData[2]   = 0xFA; // status (re-assigned)
       
   281                     binRespData[i++] = 0x00; // value size set to zero
       
   282                     break;
       
   283                     }
       
   284                 } // inner switch ends
       
   285             break;    
       
   286             }
       
   287 
       
   288         case 0x0A: // Get debug buffer
       
   289             {
       
   290             // The response consists of status byte (0x00) and 2 bytes
       
   291             // indicating the buffer size followed by the buffer itself.
       
   292             // Here buffer size zero is used => thus this only consists of
       
   293             // 3 bytes
       
   294             // FFS: This may have to be changed if the zero-length is not ok.
       
   295             binRespData[i++] = 0x00; // status
       
   296             binRespData[i++] = 0x00; // buffer size bits 0..7
       
   297             binRespData[i++] = 0x00; // buffer size bits 8..15
       
   298             break;    
       
   299             }
       
   300 
       
   301         case 0x0D: // Get device state
       
   302             {
       
   303             // The response consists of status byte (0x00) and 4 bytes that
       
   304             // indicate the device state (the bytes used here mean 
       
   305             // "device attached to the system")
       
   306             binRespData[i++] = 0x00; // status
       
   307             binRespData[i++] = 0x01; // device state bits 0..7
       
   308             binRespData[i++] = 0x00; // device state bits 8..15
       
   309             binRespData[i++] = 0x00; // device state bits 16..23
       
   310             binRespData[i++] = 0x00; // device state bits 24..31
       
   311             break;    
       
   312             }
       
   313 
       
   314         case 0x0E: // Set kernel param
       
   315             {
       
   316             // The response consists of status byte (0x00) and 2 bytes that
       
   317             // are the kernel param Id's copied from the received command 
       
   318             // (bytes 6 and 7)
       
   319             binRespData[i++] = 0x00;     // status
       
   320             binRespData[i++] = aData[6]; // kernel param Id bits 0..7
       
   321             binRespData[i++] = aData[7]; // kernel param Id bits 8..15
       
   322             break;    
       
   323             }
       
   324 
       
   325         case 0x0F: // Get kernel param
       
   326             {
       
   327             // The response consists of status byte (0x00), 2 bytes that are
       
   328             // the kernel param Id's copied from the received command 
       
   329             // (bytes 6&7) and two bytes for (here dummy 0x00) values
       
   330             binRespData[i++] = 0x00;     // status
       
   331             binRespData[i++] = aData[6]; // kernel param Id bits 0..7
       
   332             binRespData[i++] = aData[7]; // kernel param Id bits 8..15
       
   333             binRespData[i++] = 0x00;     // kernel param value bits 0..7
       
   334             binRespData[i++] = 0x00;     // kernel param value bits 8..15
       
   335             break;    
       
   336             }
       
   337 
       
   338         case 0x10: // Set device property
       
   339             {
       
   340             // The response consists of status byte (0x00), 4 bytes indicating
       
   341             // the property type (copied from the received command's bytes 
       
   342             // 6..9) and 1 byte indicating the property value type (copied
       
   343             // from the received command's byte 10).
       
   344             binRespData[i++] = 0x00;      // status
       
   345             binRespData[i++] = aData[6];  // property type bits 0..7
       
   346             binRespData[i++] = aData[7];  // property type bits 8..15
       
   347             binRespData[i++] = aData[8];  // property type bits 16..23
       
   348             binRespData[i++] = aData[9];  // property type bits 24..31
       
   349             binRespData[i++] = aData[10]; // property value type
       
   350             break;    
       
   351             }
       
   352 
       
   353         case 0x11: // Get device property
       
   354             {
       
   355             // The response consists of 1-byte status (0x00), 4-byte long
       
   356             // property type (copied from the received command bytes 7..10),
       
   357             // 1-byte property value type (copied from the received command
       
   358             // byte 2), 1-byte size byte and "size" bytes long value part
       
   359             binRespData[i++] = 0x00;      // status
       
   360             binRespData[i++] = aData[7];  // property type bits 0..7
       
   361             binRespData[i++] = aData[8];  // property type bits 8..15
       
   362             binRespData[i++] = aData[9];  // property type bits 16..23
       
   363             binRespData[i++] = aData[10]; // property type bits 24..31
       
   364             binRespData[i++] = aData[2];  // property value type
       
   365             // The size and value depend on what exactly is being queried
       
   366             // Note: Currently only the lowest (0..7) bytes of capability type
       
   367             //       have meaning, thus the switch case below is simplified
       
   368             TUint8 propertyType = aData[7];
       
   369             switch ( propertyType )
       
   370                 {
       
   371                 case 0: 
       
   372                     // license key.. not feasible as GET device property type
       
   373                     {
       
   374                     // re-assign the status
       
   375                     binRespData[2]   = 0xF9; // status - incompatible property
       
   376                                              //          type
       
   377                     binRespData[i++] = 0x00; // value size == 0 (=> no value)                    
       
   378                     break;
       
   379                     }
       
   380                 case 1: // priority
       
   381                     {
       
   382                     binRespData[i++] = 0x04; // size (32-bit integer takes 4
       
   383                                              // bytes)
       
   384                     binRespData[i++] = 0x00;
       
   385                     binRespData[i++] = 0x00;
       
   386                     binRespData[i++] = 0x00;
       
   387                     binRespData[i++] = 0x00; // value - 0x0 is lowest priority
       
   388                     break;
       
   389                     }
       
   390                 case 2: // disable effects
       
   391                     {
       
   392                     binRespData[i++] = 0x04; // size 
       
   393                     binRespData[i++] = 0x00;
       
   394                     binRespData[i++] = 0x00;
       
   395                     binRespData[i++] = 0x00;
       
   396                     binRespData[i++] = 0x00; // value - 0x0 means not disabled
       
   397                     break;
       
   398                     }
       
   399                 case 3: // strength
       
   400                 case 4: // master strength
       
   401                     {
       
   402                     binRespData[i++] = 0x04; // size 
       
   403                     binRespData[i++] = 0xFF;
       
   404                     binRespData[i++] = 0xFF;
       
   405                     binRespData[i++] = 0x00;
       
   406                     binRespData[i++] = 0x00; // => value 0xFFFF
       
   407                     break;
       
   408                     }
       
   409                 default:
       
   410                     {
       
   411                     // Pehaps it's best to change the status byte to -7 (0xF9)
       
   412                     // ("incompatible property type")
       
   413                     binRespData[2]   = 0xF9; // status (re-assigned)
       
   414                     binRespData[i++] = 0x00; // value size, set to zero
       
   415                     break;    
       
   416                     }
       
   417                 } // inner switch ends
       
   418             break;    
       
   419             }
       
   420 
       
   421         case 0x12: // Open device
       
   422             {
       
   423             // The response consists of status byte (0x00) and 4-byte long
       
   424             // deviceHandle (here hardcoded as 0x01000000)
       
   425             binRespData[i++] = 0x00; // status
       
   426             binRespData[i++] = 0x01; // deviceHandle bits 0..7
       
   427             binRespData[i++] = 0x00; // deviceHandle bits 8..15
       
   428             binRespData[i++] = 0x00; // deviceHandle bits 16..23
       
   429             binRespData[i++] = 0x00; // deviceHandle bits 24..31
       
   430             break;    
       
   431             }
       
   432 
       
   433         case 0x15: // Device count
       
   434             {
       
   435             // The response only contains the device count (here value == 1)
       
   436             binRespData[i++] = 0x01;
       
   437             break;    
       
   438             }
       
   439 
       
   440         case 0x1B: // Get effect state
       
   441             {
       
   442             // The response consists of status byte (0x00) and one byte effect
       
   443             // state (0x00 used here meaning "Not playing")
       
   444             binRespData[i++] = 0x00; // status
       
   445             binRespData[i++] = 0x00; // effect state 
       
   446             break;
       
   447             }
       
   448             
       
   449         case 0x20: // Load IVT data
       
   450             {
       
   451             // The response consists of status byte (0x00) and 4-byte long
       
   452             // fileHandle (here hardcoded as 0x01000000)
       
   453             binRespData[i++] = 0x00; // status
       
   454             binRespData[i++] = 0x01; // fileHandle bits 0..7
       
   455             binRespData[i++] = 0x00; // fileHandle bits 8..15
       
   456             binRespData[i++] = 0x00; // fileHandle bits 16..23
       
   457             binRespData[i++] = 0x00; // fileHandle bits 24..31
       
   458             break;    
       
   459             }
       
   460 
       
   461         case 0x30: // Get license key
       
   462             {
       
   463             binRespData[i++] = 0x00; // status
       
   464             binRespData[i++] = 0x20; // size
       
   465             for( TInt n=0; n<0x20; )
       
   466                 {
       
   467                 binRespData[i++] = 0x53; // S
       
   468                 n++;
       
   469                 binRespData[i++] = 0x54; // T
       
   470                 n++;
       
   471                 binRespData[i++] = 0x55; // U
       
   472                 n++;
       
   473                 binRespData[i++] = 0x42; // B
       
   474                 n++;
       
   475                 }
       
   476             break;
       
   477             }
       
   478             
       
   479         case 0xFF: // Protocol version query
       
   480             {
       
   481             // Response to Protocol version query contains:
       
   482             //      1 byte minor version number
       
   483             //      1 byte major version number
       
   484             binRespData[i++] = 0x00; // minor version 
       
   485             binRespData[i++] = 0x03; // major version
       
   486             break;    
       
   487             }
       
   488     
       
   489         default:
       
   490             {
       
   491             // Unknown command.. 
       
   492             break;    
       
   493             }
       
   494         } // switch ends 
       
   495         
       
   496     // set the lenght of the raw response data
       
   497     binRespData.SetLength( i );
       
   498 
       
   499     // create Haptics response data. This is done by externalizing 
       
   500     // (with RDesWriteStream whose sink is the Haptics response data)
       
   501     TInt32 respDataErr( KErrNone );
       
   502     CHWRMHapticsRespData* respData = 
       
   503         CHWRMHapticsRespData::NewLC( respDataErr, binRespData );
       
   504     HWRMHapticsCommand::RHWRMHapticsRespData resp;
       
   505     resp.CreateL( KHWRMHapticsRespMaxSize );
       
   506     CleanupClosePushL( resp );
       
   507     RDesWriteStream streamWriter( resp );
       
   508     CleanupClosePushL( streamWriter );
       
   509     streamWriter << *respData;
       
   510     // This commits to stream's sink (i.e., to 'resp')
       
   511     CleanupStack::PopAndDestroy( &streamWriter );
       
   512     
       
   513     // Call the ProcessResponseL of the HapticsPluginManager
       
   514     // object that created this stub plugin instance.
       
   515     iResponseCallback->ProcessResponseL
       
   516         ( HWRMHapticsCommand::EHapticsCmdId, aTransId, resp );    
       
   517     
       
   518     CleanupStack::PopAndDestroy( &resp );
       
   519     CleanupStack::PopAndDestroy( respData );
       
   520     // Order garbage collection of "spent" responder(s), if not already
       
   521     // waiting for scheduling
       
   522     if ( !iIdle->IsActive() )
       
   523         {
       
   524         iIdle->Start( TCallBack ( CollectGarbageIdle, this ) );    
       
   525         }         
       
   526     }
       
   527 
       
   528 // ---------------------------------------------------------------------------
       
   529 // Static method called as CIdle TCallBack in order to remove obsolete 
       
   530 // responder from the array of responder pointers
       
   531 // ---------------------------------------------------------------------------
       
   532 //
       
   533 TInt CHWRMHapticsStubPlugin::CollectGarbageIdle( TAny* aObjectPtr )
       
   534     {
       
   535     CHWRMHapticsStubPlugin* self = 
       
   536         reinterpret_cast<CHWRMHapticsStubPlugin*>( aObjectPtr );
       
   537     if ( self )
       
   538         {
       
   539         self->CollectGarbage();
       
   540         }
       
   541     return KErrNone;
       
   542     }
       
   543 
       
   544 // ---------------------------------------------------------------------------
       
   545 // Removes all responders that have finished their work from iResponders array
       
   546 // ---------------------------------------------------------------------------
       
   547 // 
       
   548 void CHWRMHapticsStubPlugin::CollectGarbage()
       
   549     {
       
   550     for( TInt i( 0 ); i < iResponders.Count(); )
       
   551         {
       
   552         if ( iResponders[i]->Active() )
       
   553             {
       
   554             ++i; // skip this, it's still active.. 
       
   555             }
       
   556         else     
       
   557             {
       
   558             delete iResponders[i];
       
   559             iResponders.Remove( i );
       
   560             // note: array index i is not incremented as in the next round
       
   561             //       it already is the position of next item..
       
   562             //       obviously the iResponders.Count() will be then one less
       
   563             //       than in this round.
       
   564             }
       
   565         }
       
   566     }
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 // Constructor
       
   570 // ---------------------------------------------------------------------------
       
   571 //
       
   572 CHWRMHapticsStubPlugin::CHWRMHapticsStubPlugin( 
       
   573                                 MHWRMHapticsPluginCallback* aCallback )     
       
   574     {
       
   575     // set callback to baseclass' member variable
       
   576     iResponseCallback = aCallback;
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // Two-phase construction ConstructL
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 void CHWRMHapticsStubPlugin::ConstructL()     
       
   584     {
       
   585     iIdle = CIdle::NewL( CActive::EPriorityIdle );
       
   586 
       
   587     // inform haptics of the plugin state
       
   588     iResponseCallback->PluginEnabled( EHWRMLogicalActuatorAny, ETrue );
       
   589     iResponseCallback->PluginEnabled( EHWRMLogicalActuatorDevice, ETrue );
       
   590     }
       
   591 
       
   592 // ---------------------------------------------------------------------------
       
   593 // Removes a specific responder (based on transId) from iResponders array
       
   594 // ---------------------------------------------------------------------------
       
   595 //
       
   596 void CHWRMHapticsStubPlugin::RemoveResponder( TUint8 aTransId )
       
   597     {
       
   598     TInt count( iResponders.Count() );
       
   599     
       
   600     for( TInt i( 0 ); i < count; ++i )
       
   601         {
       
   602         if ( iResponders[i]->TransId() == aTransId )
       
   603             {
       
   604             delete iResponders[i];
       
   605             iResponders.Remove( i );
       
   606             break;
       
   607             }
       
   608         }
       
   609     }
       
   610 
       
   611 // end of file
       
   612