hwrmhaptics/hapticspluginmanager/src/hwrmhapticspluginmanager.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hwrmhaptics/hapticspluginmanager/src/hwrmhapticspluginmanager.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,583 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Haptics server plugin handler implementation.
+*
+*/
+
+
+#include <ecom/ecom.h>
+#include <hwrmhapticscommands.h>
+#include <hwrmlogicalactuators.h>
+#include <centralrepository.h>
+
+#include "hwrmhapticspluginmanager.h"
+#include "hwrmhapticsclientserver.h"
+#include "hwrmhapticsservice.h"
+#include "hwrmhapticstrace.h"
+#include "hwrmhapticstransactiondata.h"
+#include "hwrmhapticsinternalcrkeys.h"
+#include "hwrmhapticsuid.h"
+
+_LIT( KPanicCategory, "HWRMHapticsPluginManager" );
+
+// HWRMHaptics uid file
+_LIT( KHapticsUidFilename, "hwrmhapticsuid.ini" );
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CHWRMHapticsPluginManager* CHWRMHapticsPluginManager::NewL(
+                                CHWRMHapticsCommonData& aHapticsCommonData, 
+                                TInt aRequestTimeout )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::NewL()" ) ) );
+    
+    CHWRMHapticsPluginManager* self = 
+        new ( ELeave ) CHWRMHapticsPluginManager( aHapticsCommonData, 
+                                                  aRequestTimeout );
+    CleanupStack::PushL( self );
+    
+    self->ConstructL();
+    
+    CleanupStack::Pop( self );
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::NewL - return 0x%x" ), self ) );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsPluginManager::~CHWRMHapticsPluginManager()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::~CHWRMHapticsPluginManager()" ) ) );
+    
+    if ( iPlugin )
+        {
+        // Cancel any ongoing requests
+        while ( iTransactionList->FirstItem() )
+            {
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::~CHWRMHapticsPluginManager - Canceling transaction %d" ), iTransactionList->FirstItem()->TransactionId() ) );
+            TRAPD( err, CancelCommandL(
+                        iTransactionList->FirstItem()->TransactionId() ) );
+
+            if ( err != KErrNone )
+                {
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::~CHWRMHapticsPluginManager - Canceling transaction %d failed" ), iTransactionList->FirstItem()->TransactionId() ) );
+                }
+            }
+
+        delete iPlugin;
+        iPlugin = NULL;
+        }
+        
+    delete iPluginTimer;
+    // delete transaction list
+    delete iTransactionList;
+
+    delete iHapticsUid;
+
+    delete iRepository; 
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::~CHWRMHapticsPluginManager - return " )) );
+    }
+
+// ---------------------------------------------------------------------------
+// Handles plugin requests from sessions. Only one concurrent request 
+// is supported.
+// ---------------------------------------------------------------------------
+//
+TUint8 CHWRMHapticsPluginManager::ProcessCommandL( 
+                                TInt aCommandId,
+                                TDesC8& aData,
+                                CHWRMHapticsService* aCompletionCallback  )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessCommandL(0x%x, <aData>, 0x%x)" ), aCommandId, aCompletionCallback ) );
+
+    if ( !iPlugin )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessCommandL - No actuator!" ) ) );
+        User::Leave( KErrBadHandle );
+        }
+
+    // Generate new transaction ID.
+    iTransIdCounter++; 
+    if ( iTransIdCounter == 0 )
+        {
+        // Counter will overflow back to zero when it hits max.
+        // However, zero indicates completed transaction as return value, so 
+        // increase counter again.
+        iTransIdCounter++; 
+        }
+    
+    // If we run out of transIds, return server is busy.
+    if ( iTransactionList->FindTransaction( iTransIdCounter, EFalse ) )
+        {
+        User::Leave( KErrServerBusy );
+        }
+
+    // Create transaction data before call in case it leaves
+    TTime obsoletionTime;
+    obsoletionTime.UniversalTime();
+    obsoletionTime += iRequestTimeout;
+    CHWRMHapticsTransactionData* data = 
+        new (ELeave) CHWRMHapticsTransactionData( aCompletionCallback, 
+                                                  iTransIdCounter, 
+                                                  aCommandId, 
+                                                  obsoletionTime );
+
+    // Push transaction data to cleanup stack so that it will clean 
+    // out if ProcessCommandL leaves.
+    CleanupStack::PushL( data );
+    
+    iPlugin->ProcessCommandL( aCommandId, data->TransactionId(), aData );
+    
+    TUint8 retval( 0 );
+
+    // data still needed, do not destroy, just pop
+    CleanupStack::Pop( data );
+    
+    // Add data to list
+    iTransactionList->AddTransaction( data );
+
+    retval = data->TransactionId();
+
+    // Start  timer if it is not already started
+    if ( !iPluginTimer->IsActive() )
+        {
+        iPluginTimer->Set( iRequestTimeout );
+        }
+        
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessCommandL - return 0x%x" ), retval ) );         
+    
+    return retval;
+        
+    }
+    
+// ---------------------------------------------------------------------------
+// Cancels the currently executing request
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::CancelCommandL( TUint8 aTransId )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::CancelCommandL()" )) );
+
+    if ( !iPlugin )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::CancelCommandL - No actuator!" ) ) );
+        User::Leave( KErrBadHandle );
+        }
+    
+    // Find correct transaction data and remove it from list
+    CHWRMHapticsTransactionData* data = 
+        static_cast<CHWRMHapticsTransactionData*>(
+            iTransactionList->FindTransaction( aTransId, ETrue ) );
+   
+    // cancel request timer if no more transactions open
+    if ( iTransactionList->Count() == 0 )
+        {
+        iPluginTimer->Cancel();
+        }
+
+    // If transaction is not open, do nothing
+    // Do not cancel if request has no callback (i.e. final destructor 
+    // state restorings)
+    // (these are canceled by timeout if they do not complete successfully)
+    if ( data && data->CompletionCallback() )
+        {            
+        CleanupStack::PushL( data );
+        
+        iPlugin->CancelCommandL( data->TransactionId(), data->CommandId() );
+        
+        // Destroy the transaction data, since transaction is over.
+        CleanupStack::PopAndDestroy( data );
+        }
+    else
+        {
+        if ( data )
+            {
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::CancelCommandL - Not canceled because no callback" ) ) );
+            
+            // Push data back to list
+            iTransactionList->AddTransaction( data );
+            }
+        else
+            {
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::CancelCommandL - Not canceled because no transaction found" ) ) );
+            }
+        }
+        
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::CancelCommandL - return" ) ) );
+    }
+    
+// ---------------------------------------------------------------------------
+// Called by the plugin to inform its state. Sends notification of the state
+// to all listening clients.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::PluginEnabled( 
+                                    THWRMLogicalActuators aActuator,
+                                    TBool aEnabled )
+    {
+    MHWRMHapticsActuatorObserver::THWRMActuatorEvents event = 
+        MHWRMHapticsActuatorObserver::EHWRMActuatorDisabled;
+    
+    if ( aEnabled )
+        {
+        event = MHWRMHapticsActuatorObserver::EHWRMActuatorEnabled;
+        }
+    
+    iHapticsCommonData.BroadcastActuatorEvent( event, aActuator );
+    }
+
+// ---------------------------------------------------------------------------
+// Routes response from plugin to correct service instance
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::ProcessResponseL( TInt aCommandId,
+                                                  TUint8 aTransId,
+                                                  const TDesC8& aData  )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessResponseL(0x%x, 0x%x, <aData> )" ), aCommandId, aTransId ) );
+
+    // Find and remove correct transaction data and remove it from queue
+    CHWRMHapticsTransactionData* data = 
+        static_cast<CHWRMHapticsTransactionData*>(
+            iTransactionList->FindTransaction( aTransId, ETrue ) );
+    
+    // cancel request timer if no more transactions open
+    if ( iTransactionList->Count() == 0 )
+        {
+        iPluginTimer->Cancel();
+        }
+
+    // If transaction is not open, response not expected.
+    if ( data )
+        {
+        CleanupStack::PushL( data );
+
+        // Check that command ID is the expected one        
+        if ( data->CommandId() != aCommandId )
+            {
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessResponseL - Command ID mismatch, expected: 0x%x, got 0x%x" ), data->CommandId(), aCommandId ) );
+            User::Leave( KErrBadHandle );
+            }
+
+        // Route data to callback service if one is needed
+        if ( data->CompletionCallback() )
+            {
+            data->CompletionCallback()->ProcessResponseL( aCommandId, 
+                                                         aTransId, 
+                                                         aData );
+            }
+        
+        CleanupStack::PopAndDestroy( data );
+        data = NULL;
+        }
+    else
+        {
+        // There is problem in adaptation, as unexpected transaction was completed.
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessResponseL - No transaction data found!" ) ) );
+        User::Leave( KErrBadHandle );
+        }
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ProcessResponseL - return" ) ) );
+    }
+    
+// ---------------------------------------------------------------------------
+// Cancels all obsolete transactions. TimerId is irrelevant as only one timer.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::GenericTimerFired( TInt /*aTimerId*/, 
+                                                   TBool /*aCutOff*/ )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::GenericTimerFired()" ) ) );
+
+    __ASSERT_ALWAYS( iPlugin, User::Panic( KPanicCategory, 
+                                           EPanicBadHandle ) );
+
+    // Since requests are added to end of list always, they are in order 
+    // of obsolescense.
+    // Cancel requests that are obsolete and notify callback service
+    TInt err( KErrNone );
+    TTime now;
+    now.UniversalTime();
+
+    CHWRMHapticsTransactionData* data = 
+        static_cast<CHWRMHapticsTransactionData*>( 
+            iTransactionList->FirstItem() );
+    
+    while ( data && ( data->TransactionObsoletionTime() < now ) )   
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::GenericTimerFired - Canceling obsolete transaction 0x%x" ), data->TransactionId() ) );
+
+        // Cancel transaction. 
+        TUint8 trId( data->TransactionId() );
+        TRAP(err, iPlugin->CancelCommandL( trId, data->CommandId() ) );
+
+        if ( err != KErrNone )
+            {
+            // Ignore errors as we cannot do anything about it 
+            // anyway. Just trace.
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::GenericTimerFired - Canceling obsolete transaction FAILED (%d)!" ), err ) );
+            }
+
+        if ( data->CompletionCallback() )
+            {
+            data->CompletionCallback()->CancelRequest( trId );
+            }
+
+        // Destroy the transaction data, since transaction is over.
+        iTransactionList->RemoveFirstItem();
+        delete data;
+        
+        // get next data to check
+        data = static_cast<CHWRMHapticsTransactionData*>(
+                                    iTransactionList->FirstItem() );
+        }
+
+    // Restart timer if there is more transactions in list
+    if ( data )
+        {
+        iPluginTimer->Set( iRequestTimeout );
+        }
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::GenericTimerFired - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// It retrieves the supported actuator information from plugins.
+// ---------------------------------------------------------------------------
+//
+TUint32 CHWRMHapticsPluginManager::GetSupportedActuatorInfo()
+    {
+    return iSupActuators;
+    }
+
+// ---------------------------------------------------------------------------
+// Opens the plugin appropriate for the actuator to be opened.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsPluginManager::OpenPluginToActuatorL( 
+                                            THWRMLogicalActuators aActuator )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::OpenPluginToActuator - Actuator = %d " ), aActuator) );
+    
+    TBool created = EFalse;
+
+    // check if actuator type is supported
+    if ( !( aActuator & iSupActuators ) )
+        {
+        // not supported
+        User::Leave( KErrNotSupported );
+        }
+
+    if ( !iPlugin )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::OpenPluginToActuator - Creating plugin instance." ) ) );
+
+        // map actuator type to type cenrep id
+        TInt adaptationCenrepId(0);
+        switch( aActuator )
+            {
+            case EHWRMLogicalActuatorAny:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginAnyAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorDevice:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginDeviceAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorPrimaryDisplay:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginPrimaryDisplayAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorSecondaryDisplay:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginSecondaryDisplayAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorGame:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginGameAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorGameLeft:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginGameLeftAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorGameRight:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginGameRightAdaptation;
+                break;
+                }
+            case EHWRMLogicalActuatorExternalVibra:
+                {
+                adaptationCenrepId = KHWRMHapticsPluginExternalVibraAdaptation;
+                break;
+                }
+            default:
+                adaptationCenrepId = KHWRMHapticsPluginAnyAdaptation;
+                break;
+           }
+
+        TInt adaptationPluginUid( 0 );
+        User::LeaveIfError( iRepository->Get( adaptationCenrepId, 
+                                              adaptationPluginUid ) );
+
+        // create plugin instance with the given uid
+        TRAPD( err, iPlugin = CHWRMHapticsPluginService::NewL( 
+                                  TUid::Uid( adaptationPluginUid ), this ) );
+
+        // if the plugin with given uid was not found, the 
+        // actuator type is not supported
+        if ( err == KErrNotFound )
+            {
+            err = KErrNotSupported;
+            }
+        
+        User::LeaveIfError( err );
+        
+        created = ETrue;
+        }
+    
+    return created;
+    }
+
+// ---------------------------------------------------------------------------
+// Checks if automatic license setting is allowed. The actual check is done
+// in CHWRMHapticsUid helper class.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsPluginManager::LicenseAutoSettingAllowed( 
+    const RMessage2& aMessage )
+    {
+    return iHapticsUid->LicenseAutoSetAllowed( aMessage );
+    }
+
+// ---------------------------------------------------------------------------
+// C++ constructor
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsPluginManager::CHWRMHapticsPluginManager( 
+                                CHWRMHapticsCommonData& aHapticsCommonData, 
+                                TInt aRequestTimeout )
+    : iHapticsCommonData( aHapticsCommonData ), 
+      iTransIdCounter( 0 ),
+      iRequestTimeout( aRequestTimeout )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// 2nd phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::ConstructL()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ConstructL(<aMatch>)" )) );
+
+    // create transaction list and timer
+    iTransactionList = new( ELeave ) CHWRMHapticsPluginTransactionList();
+    iPluginTimer = CHWRMHapticsGenericTimer::NewL( this, iRequestTimeout, 0 );
+
+    iRepository = CRepository::NewL( KCRUidHWRMHapticsPlugins ); 
+
+    // get all supported actuator information
+    iSupActuators = FindSupportedActuatorInfoL();
+    
+    // create UID file parser
+    iHapticsUid = CHWRMHapticsUid::NewL( KHapticsUidFilename );
+    
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsPluginManager::ConstructL - return" )) );
+    }
+
+// ---------------------------------------------------------------------------
+// Finds the supported actuator information from plugins.
+// ---------------------------------------------------------------------------
+//
+TUint32 CHWRMHapticsPluginManager::FindSupportedActuatorInfoL()
+    {
+    TUint32 supportedActuators( 0 );
+    
+    // Any
+    AddInfoIfSupportedL( KHWRMHapticsPluginAnyAdaptation, 
+                         EHWRMLogicalActuatorAny, 
+                         supportedActuators );
+
+    // Device
+    AddInfoIfSupportedL( KHWRMHapticsPluginDeviceAdaptation, 
+                         EHWRMLogicalActuatorDevice, 
+                         supportedActuators );
+
+    // Primary Display
+    AddInfoIfSupportedL( KHWRMHapticsPluginPrimaryDisplayAdaptation, 
+                         EHWRMLogicalActuatorPrimaryDisplay, 
+                         supportedActuators );
+
+    // Secondary Display
+    AddInfoIfSupportedL( KHWRMHapticsPluginSecondaryDisplayAdaptation, 
+                         EHWRMLogicalActuatorSecondaryDisplay, 
+                         supportedActuators );
+
+    // Game
+    AddInfoIfSupportedL( KHWRMHapticsPluginGameAdaptation, 
+                         EHWRMLogicalActuatorGame, 
+                         supportedActuators );
+
+    // Game Left
+    AddInfoIfSupportedL( KHWRMHapticsPluginGameLeftAdaptation, 
+                         EHWRMLogicalActuatorGameLeft, 
+                         supportedActuators );
+
+    // Game Right
+    AddInfoIfSupportedL( KHWRMHapticsPluginGameRightAdaptation, 
+                         EHWRMLogicalActuatorGameRight, 
+                         supportedActuators );
+
+    // External Vibra
+    AddInfoIfSupportedL( KHWRMHapticsPluginExternalVibraAdaptation, 
+                         EHWRMLogicalActuatorExternalVibra, 
+                         supportedActuators );
+
+    return supportedActuators;
+    }
+
+// ---------------------------------------------------------------------------
+// If given actuator type is found, adds it to the actuator mask integer.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsPluginManager::AddInfoIfSupportedL( TInt aMatch,
+                                                THWRMLogicalActuators aMask,
+                                                TUint32& aActuators )
+    {
+    TInt pluginUid( 0 );
+    User::LeaveIfError( iRepository->Get( aMatch, pluginUid ) );
+
+    // if the adaptation plugin UID is not zero, implementation is found,
+    // i.e. actuator is supported
+    if( pluginUid != 0 ) 
+        {
+        // add actuator to the mask
+        aActuators = aActuators | aMask;
+        }    
+    }
+
+//  End of File