diff -r 000000000000 -r 4e1aa6a622a0 resourcemgmt/hwresourcesmgr/server/src/HWRMLightService.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resourcemgmt/hwresourcesmgr/server/src/HWRMLightService.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,1811 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + + + +// INCLUDE FILES +#include "HWRMServer.h" +#include "HWRMService.h" +#include "HWRMLightService.h" +#include "HWRMPluginHandler.h" +#include "HWRMReservationHandler.h" +#include "HWRMtrace.h" + +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +_LIT( KPanicCategory, "HWRMLightService" ); + +const TUint KHWRMDefaultColor = 0; +// MACROS +// None + +// LOCAL CONSTANTS AND MACROS +// None + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHWRMLightService::CHWRMLightService +// C++ constructor +// ----------------------------------------------------------------------------- +// +CHWRMLightService::CHWRMLightService(CHWRMLightCommonData& aLightCommonData) + : iLightCommonData(aLightCommonData) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::CHWRMLightService()" )); + + // Null the target timers to ensure proper cleanup if ConstructL leaves + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + iTargets[i].iTimer = NULL; + } + + iSupportedTargets = iLightCommonData.SupportedTargets(); + iFullSystemTarget = iLightCommonData.FullSystemTarget(); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::CHWRMLightService - return" )); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ConstructL(CHWRMPluginHandler* aPluginHandler, + CHWRMReservationHandler* aReservationHandler) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::ConstructL(0x%x, 0x%x)" ), aPluginHandler, aReservationHandler); + + __ASSERT_ALWAYS(aPluginHandler, User::Panic(KPanicCategory, EPanicBadHandle)); + __ASSERT_ALWAYS(aReservationHandler, User::Panic(KPanicCategory, EPanicBadHandle)); + + BaseConstructL(aPluginHandler, aReservationHandler); + + // initialize target timers (and the rest of the data, just in case) + TInt currentTarget(KHWRMLightFirstTarget); + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + // only initialize supported target timers + if ( currentTarget & iSupportedTargets ) + { + iTargets[i].iTimer = CHWRMGenericTimer::NewL(*this, KHWRMGenericTimerMaxTime, i); + } + + iTargets[i].iTarget = currentTarget; + iTargets[i].iSuspended = EFalse; + iTargets[i].iReserved = EFalse; + + iTargets[i].iBaseState.iIntensity = KHWRMDefaultIntensity; + iTargets[i].iBaseState.iState = CHWRMLight::ELightStatusUnknown; + iTargets[i].iBaseState.iFade = EFalse; + iTargets[i].iBaseState.iOffCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iBaseState.iOnCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iBaseState.iColor = KHWRMInvalidColorMask; + + + iTargets[i].iLastState.iIntensity = KHWRMDefaultIntensity; + iTargets[i].iLastState.iState = CHWRMLight::ELightStatusUnknown; + iTargets[i].iLastState.iFade = EFalse; + iTargets[i].iLastState.iOffCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iLastState.iOnCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iLastState.iColor = KHWRMInvalidColorMask; + + iTargets[i].iFrozenState.iIntensity = KHWRMDefaultIntensity; + iTargets[i].iFrozenState.iState = CHWRMLight::ELightStatusUnknown; + iTargets[i].iFrozenState.iFade = EFalse; + iTargets[i].iFrozenState.iOffCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iFrozenState.iOnCycleDuration = KHWRMDefaultCycleTime; + iTargets[i].iFrozenState.iColor = KHWRMInvalidColorMask; + + // move to next target + currentTarget <<= 1; + } + + iDefaultState.iIntensity = KHWRMDefaultIntensity; + iDefaultState.iState = CHWRMLight::ELightStatusUnknown; // This is updated based on inactivity time + iDefaultState.iFade = ETrue; + iDefaultState.iOffCycleDuration = KHWRMDefaultCycleTime; + iDefaultState.iOnCycleDuration = KHWRMDefaultCycleTime; + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ConstructL - return " ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHWRMLightService* CHWRMLightService::NewL(CHWRMPluginHandler* aPluginHandler, + CHWRMReservationHandler* aReservationHandler, + CHWRMLightCommonData& aLightCommonData) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::NewL(0x%x)" ), aPluginHandler); + + CHWRMLightService* self = new( ELeave ) CHWRMLightService(aLightCommonData); + + CleanupStack::PushL( self ); + self->ConstructL(aPluginHandler, aReservationHandler); + CleanupStack::Pop(); + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::NewL - return 0x%x" ), self ); + + return self; + } + +// --------------------------------------------------------- +// Destructor +// --------------------------------------------------------- +// +CHWRMLightService::~CHWRMLightService() + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::~CHWRMLightService()" ) ); + + CleanupLights(); + + // Delete timers + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + delete iTargets[i].iTimer; + } + + // Base class cleanup + BaseDestruct(); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::~CHWRMLightService - return" ) ); + } + + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::CleanupLights() +// Handles Light service cleanup +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::CleanupLights() + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::CleanupLights()" ) ); + if (!iCleaningUp) + { + iCleaningUp = ETrue; + + TInt unreserved(0x0); + TInt mask(0x0); // mask of targets + + // If any targets are still reserved, release them + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( iTargets[i].iReserved ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMCleanupLights - Target index %d needs release." ), i ); + mask |= iTargets[i].iTarget; + + // Clear reserved and suspended flags + iTargets[i].iReserved = EFalse; + iTargets[i].iSuspended = EFalse; + } + } + + if ( mask ) + { + unreserved = iReservationHandler->Release(this, mask); + } + else + { + unreserved = iReservationHandler->GetUnreservedTargets(); + } + + mask = 0x0; // reset mask + + // Restore unreserved targets that have been affected by this session to default state. + // Also cancel all timers. + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( iTargets[i].iTimer && iTargets[i].iTimer->IsActive() ) + { + iTargets[i].iTimer->Cancel(); + } + + if ( (unreserved & iTargets[i].iTarget) == iTargets[i].iTarget + && iTargets[i].iLastState.iState != CHWRMLight::ELightStatusUnknown ) + { + mask |= iTargets[i].iTarget; + } + } + + // Restore default states if needed. iTargets[0] is used as dummy. + // The aMessage pointer is required for completion after transaction. + if ( mask ) + { + // Cannot restore both system targets and non-system targets with same command, so do them separately. + TInt subMask(mask & iFullSystemTarget); + + if ( subMask ) + { + RestoreState(iTargets[0], EStateChangeDefaultState, EFalse, subMask); + } + + subMask = mask & ~subMask; // rest of targets + + if ( subMask ) + { + RestoreState(iTargets[0], EStateChangeDefaultState, EFalse, subMask); + } + } + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::CleanupLights - Already cleaned up" ) ); + } + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::CleanupLights - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ExecuteMessageL +// Handles Light requests. +// ----------------------------------------------------------------------------- +// +TBool CHWRMLightService::ExecuteMessageL( const RMessage2& aMessage ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL(0x%x)" ), aMessage.Function()); + + // If cleaning up or dummy message, something has gone wrong, so leave. + if ( aMessage.IsNull() || iCleaningUp ) + { + User::Leave(KErrBadHandle); + } + + // All messages are by default asynchronous because of the nature of the plugin API + TBool completeMessage(EFalse); + + switch ( aMessage.Function() ) + { + case EHWRMLightsOn: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMLightsOn" ) ); + + THWRMLightsOnCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMLightsOnData* commandData = &(pckg()); + + LightsOnL( commandData->iTarget, + commandData->iDuration, + commandData->iIntensity, + commandData->iFadeIn, + aMessage ); + + break; + } + case EHWRMLightsOff: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMLightsOff" ) ); + + THWRMLightsOffCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMLightsOffData* commandData = &(pckg()); + + LightsOffL( commandData->iTarget, + commandData->iDuration, + commandData->iFadeOut, + aMessage ); + + break; + } + case EHWRMLightsBlink: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMLightsBlink" ) ); + + THWRMLightsBlinkCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMLightsBlinkData* commandData = &(pckg()); + + LightsBlinkL( commandData->iTarget, + commandData->iDuration, + commandData->iIntensity, + commandData->iOnCycleDuration, + commandData->iOffCycleDuration, + aMessage ); + + break; + } + case EHWRMReserveLights: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMReserveLights") ); + + ReserveLightsL(aMessage); + + completeMessage = ETrue; // Since using dummy messages for freeze state restores, need complete always. + + break; + } + case EHWRMReleaseLights: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMReleaseLights") ); + + // Release specified targets + TInt targetMask(aMessage.Int0()); + + ReleaseLights(targetMask); + + + completeMessage = ETrue; // Since using dummy messages for default state restores, need complete always. + + break; + } + case EHWRMGetSupportedTargets: + { + // Get the supported targets and return them in parameter 0 + TPtrC8 value( reinterpret_cast(&iSupportedTargets), sizeof( iSupportedTargets ) ); + aMessage.WriteL( 0, value ); + + completeMessage = ETrue; + + break; + } + case EHWRMCleanupLights: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMCleanupLights" ) ); + + CleanupLights(); + + // Complete, as dummy messages are used in cleanup + completeMessage = ETrue; + + break; + } + + case EHWRMSetLightColor: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMSetLightColor" ) ); + + THWRMSetColorCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMSetColorData* commandData = &(pckg()); + + SetColorL( commandData->iTarget, + commandData->iColor, + aMessage ); + + break; + } + + case EHWRMLightsOnWithColor: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMLightsOnWithColor" ) ); + + + THWRMLightsOnCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMLightsOnData* commandData = &(pckg()); + + //Data allocated here will be freed in SetColorL if target is suspended + //else will be freed in CompleteRequest for SetColorL + THWRMLightsOnData* lightOnData = new(ELeave) THWRMLightsOnData; + lightOnData->iTarget = commandData->iTarget; + lightOnData->iFadeIn = commandData->iFadeIn; + lightOnData->iDuration = commandData->iDuration; + lightOnData->iIntensity = commandData->iIntensity; + + CleanupStack::PushL( lightOnData ); + + // coverity[freed_arg] + TBool pluginCommandCalled = SetColorL(commandData->iTarget, commandData->iColor, aMessage, + EFalse, ETrue, HWRMLightCommand::ELightsOnCmdId, lightOnData); + + //SetColor will store the pointer(lightOnData) as splitcommand data. + //This will freed after ProcessResponseL. + CleanupStack::Pop( lightOnData ); + + if(!pluginCommandCalled) + { + //Target is suspended, so call light on. + //Message is completed to client and last state is stored. + LightsOnL( commandData->iTarget, + commandData->iDuration, + commandData->iIntensity, + commandData->iFadeIn, + aMessage ); + } + + + + break; + } + + case EHWRMLightsBlinkWithColor: + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - EHWRMLightsBlinkWithColor" ) ); + + + THWRMLightsBlinkCmdPackage pckg; + aMessage.ReadL( 0, pckg ); + + THWRMLightsBlinkData* commandData = &(pckg()); + + //Data allocated here will be freed in SetColorL if target is suspended + //else will be freed in CompleteRequest for SetColorL + THWRMLightsBlinkData* lightBlinkData = new(ELeave) THWRMLightsBlinkData; + + lightBlinkData->iTarget = commandData->iTarget; + lightBlinkData->iDuration = commandData->iDuration; + lightBlinkData->iIntensity = commandData->iIntensity; + lightBlinkData->iOnCycleDuration = commandData->iOnCycleDuration; + lightBlinkData->iOffCycleDuration = commandData->iOffCycleDuration; + + CleanupStack::PushL( lightBlinkData ); + + // coverity[freed_arg] + TBool pluginCommandCalled = SetColorL(commandData->iTarget, commandData->iColor, aMessage, + EFalse, ETrue, HWRMLightCommand::ELightsBlinkCmdId, lightBlinkData); + + //SetColor will store the pointer(lightBlinkData) as splitcommand data. + //This will freed after ProcessResponseL. + CleanupStack::Pop( lightBlinkData ); + + + if(!pluginCommandCalled) + { + //Target is suspended, so call light Blink. + //Message is completed to client and last state is stored. + LightsBlinkL( commandData->iTarget, + commandData->iDuration, + commandData->iIntensity, + commandData->iOnCycleDuration, + commandData->iOffCycleDuration, + aMessage ); + } + + + break; + } + + // Cannot identify the message, panic the client + default: + { + CHWRMServer::PanicClient(aMessage, EPanicIllegalFunction); + break; + } + } + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ExecuteMessageL - return 0x%x" ), completeMessage ); + + return completeMessage; + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ReleaseLights +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ReleaseLights(TInt aTargetMask) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ReleaseLights(0x%x)" ), aTargetMask ); + + TInt targetMask = aTargetMask; + + // Change mask if releasing system target + if ( targetMask & CHWRMLight::ESystemTarget ) + { + targetMask = iFullSystemTarget; + } + else + { + // Strip unsupported targets from mask since those cannot be reserved anyway. + targetMask &= iSupportedTargets; + } + + TInt restoreMask(0x0); + TInt unreserved(iReservationHandler->Release(this, targetMask)); + + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + // freeze only targets that were actually reserved to this session + if ( ((targetMask & iTargets[i].iTarget) == iTargets[i].iTarget) && iTargets[i].iReserved ) + { + // Clear reserved and suspended flags + iTargets[i].iReserved = EFalse; + iTargets[i].iSuspended = EFalse; + + // Freeze state + iTargets[i].iFrozenTime = (iTargets[i].iTimer->Freeze()).Int(); + iTargets[i].iFrozenState.iIntensity = iTargets[i].iLastState.iIntensity; + iTargets[i].iFrozenState.iState = iTargets[i].iLastState.iState; + iTargets[i].iFrozenState.iFade = iTargets[i].iLastState.iFade; + iTargets[i].iFrozenState.iOffCycleDuration = iTargets[i].iLastState.iOffCycleDuration; + iTargets[i].iFrozenState.iOnCycleDuration = iTargets[i].iLastState.iOnCycleDuration; + iTargets[i].iFrozenState.iColor = iTargets[i].iLastState.iColor; + + // Prepare to restore default state for target light if no more reservations for it exist. + if ( (unreserved & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + restoreMask |= iTargets[i].iTarget; + } + } + } + + // Restore default states if needed. iTargets[0] is used as dummy. + // Note: Cannot restore both system targets and non-system targets with same command, + // because they have possibly different default states, so do them separately. + if ( restoreMask ) + { + TInt subMask(restoreMask & iFullSystemTarget); + + if ( subMask ) + { + RestoreState(iTargets[0], EStateChangeDefaultState, EFalse, subMask ); + } + + subMask = restoreMask & ~subMask; // rest of targets + + if ( subMask ) + { + RestoreState(iTargets[0], EStateChangeDefaultState, EFalse, subMask ); + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ReleaseLights - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ReserveLightsL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ReserveLightsL(const RMessage2& aMessage) + { + // Reserve one or more targets + TInt targetMask = aMessage.Int0(); + + // Change mask if reserving system target + if ( targetMask & CHWRMLight::ESystemTarget ) + { + targetMask = iFullSystemTarget; + } + else + { + // check supplied mask validity + CheckTargetParameterL( targetMask ); + } + + TInt suspendedMask(iReservationHandler->ReserveL(aMessage, aMessage.Int2(), this, targetMask)); + + // Go through targets and update datas + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( (targetMask & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + iTargets[i].iReserved = ETrue; + + if ( (suspendedMask & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + iTargets[i].iSuspended = ETrue; + } + + // Restore previously stored state if restore was specified and + // there is valid frozen state stored. + if ( aMessage.Int1() && iTargets[i].iFrozenState.iState != CHWRMLight::ELightStatusUnknown) + { + RestoreState(iTargets[i], EStateChangeFrozenState, EFalse); + } + else if (aMessage.Int1() && iTargets[i].iFrozenState.iColor != KHWRMInvalidColorMask) + { + RMessage2 message; + TRAP_IGNORE(SetColorL(targetMask, iTargets[i].iFrozenState.iColor, message)); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::UpdateDefaultSensitivityL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::UpdateDefaultSensitivityL(TInt aSensitivity) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::UpdateDefaultSensitivityL(%d)" ), aSensitivity ); + + RMessage2 dummy; + HWRMLightCommand::TLightsSensorSensitivityCmdPackage pckg(aSensitivity); + ExecutePluginCommandL(iSupportedTargets, dummy, HWRMLightCommand::ESetLightsSensorSensitivityCmdId, pckg, EFalse); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::UpdateDefaultSensitivityL - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::UpdateDefaultIntensityL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::UpdateDefaultIntensityL(TInt aTarget, TInt aIntensity) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::UpdateDefaultIntensityL(0x%x, %d)" ), aTarget, aIntensity ); + + RMessage2 dummy; + + HWRMLightCommand::TLightsIntensityData intensityData; + intensityData.iTarget = aTarget; + intensityData.iIntensity = aIntensity; + HWRMLightCommand::TLightsIntensityCmdPackage pckg(intensityData); + + ExecutePluginCommandL(iSupportedTargets, dummy, HWRMLightCommand::ESetLightsIntensityCmdId, pckg, EFalse); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::UpdateDefaultIntensityL - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::LightsOnL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::LightsOnL(TInt aTarget, + TInt aDuration, + TInt aIntensity, + TBool aFadeIn, + const RMessage2& aMessage, + TBool aTimerInitiated, + TBool aActivationInitiated) + { + COMPONENT_TRACE8(_L( "HWRM Server - CHWRMLightService::LightsOnL(0x%x ,%d, %d, 0x%x, 0x%x, %d, %d )" ), aTarget, + aDuration, + aIntensity, + aFadeIn, + aMessage.Handle(), + aTimerInitiated, + aActivationInitiated); + + CheckCommonParametersL( aTarget, aDuration, aIntensity); + + TInt modTarget(aTarget); + + if ( !aActivationInitiated ) + { + modTarget = ModifyTargetMaskL(aTarget, EFalse); + } + + // If there is no target, only complete the message, if any. + if ( modTarget ) + { + // If intensity is KHWRMDefaultIntensity, get default intensity from common data or use sensor with sensitivity + TInt intensensitivity = aIntensity; + TBool useSensor = EFalse; + if ( aIntensity == KHWRMDefaultIntensity ) + { + if ( iLightCommonData.SensorEnabled() ) + { + intensensitivity = iLightCommonData.DefaultSensitivity(); + useSensor = ETrue; + } + else + { + // Adaptation will be responsible for setting the correct intensity, do nothing + } + } + + // Check suspended targets, only call plugin for unsuspended ones + TInt unsuspendedTargets = GetAndCheckUnsuspendedTargetsL(modTarget); + + // Call the plugin if any unsuspended targets + if ( unsuspendedTargets ) + { + TInt sensorTargets(0); + TInt nonSensorTargets(0); + TBool splitCommand(EFalse); + + if ( useSensor ) + { + // If sensor is in use, command may need splitting to sensor and non-sensor commands, + // depending on targets. + sensorTargets = unsuspendedTargets & iLightCommonData.SensorTargets(); + nonSensorTargets = unsuspendedTargets & ~sensorTargets; + + if (sensorTargets && nonSensorTargets ) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsOnL - Splitting command required" ) ); + splitCommand = ETrue; + + // NOTE about split commands: + // The ultimate completion code for messages related to split commands will be whatever + // completion code the split command handled last will have. I.e. if there is an error + // on first command but second command completes properly, whole message completes properly. + // So some errors may go unnoticed by client. However, it should be extremely rare that + // one split command will succeed and one completes with error, if environment is properly + // configured. OOM case is the only possiblity that comes to mind. + } + } + else + { + nonSensorTargets = unsuspendedTargets; + } + + if ( sensorTargets ) + { + // Only sensor targets, no splitting + HWRMLightCommand::TLightsOnSensorData pluginCommand; + pluginCommand.iTarget = sensorTargets; + pluginCommand.iSensitivity = intensensitivity; + pluginCommand.iFadeIn = aFadeIn; + HWRMLightCommand::TLightsOnSensorCmdPackage pckg(pluginCommand); + ExecutePluginCommandL(sensorTargets, aMessage, HWRMLightCommand::ELightsOnSensorCmdId, pckg, splitCommand); + } + + if ( nonSensorTargets ) + { + HWRMLightCommand::TLightsOnData pluginCommand; + pluginCommand.iTarget = nonSensorTargets; + + // If targeting non-sensor targets when sensor use is indicated, use default intensity always. + if ( useSensor ) + { + pluginCommand.iIntensity = KHWRMDefaultIntensity; + } + else + { + pluginCommand.iIntensity = intensensitivity; + } + + pluginCommand.iFadeIn = aFadeIn; + HWRMLightCommand::TLightsOnCmdPackage pckg(pluginCommand); + ExecutePluginCommandL(nonSensorTargets, aMessage, HWRMLightCommand::ELightsOnCmdId, pckg, splitCommand); + } + + // Publish state already here if cleaning up, since no ProcessResponse will come + if ( iCleaningUp ) + { + iLightCommonData.PublishLightStatus(unsuspendedTargets, CHWRMLight::ELightOn); + } + } + else + { + // complete message if suspended, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + // Use unmodified target in state update as virtual state for inactive targets needs to be preserved. + if ( !aActivationInitiated ) + { + UpdateTimersAndStoreStates(aTimerInitiated, aDuration, aTarget, CHWRMLight::ELightOn, aIntensity, aFadeIn, 0, 0); + } + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsOnL - Target empty, only complete message" ) ); + + // complete message if one is pending, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsOnL - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::LightsOffL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::LightsOffL(TInt aTarget, + TInt aDuration, + TBool aFadeOut, + const RMessage2& aMessage, + TBool aTimerInitiated, + TBool aActivationInitiated) + { + COMPONENT_TRACE7(_L( "HWRM Server - CHWRMLightService::LightsOffL(0x%x ,%d, %d, 0x%x, %d, %d)" ), aTarget, + aDuration, + aFadeOut, + aMessage.Handle(), + aTimerInitiated, + aActivationInitiated); + + CheckCommonParametersL( aTarget, aDuration, KHWRMDefaultIntensity); + + TInt modTarget(aTarget); + + if ( !aActivationInitiated ) + { + modTarget = ModifyTargetMaskL(aTarget, ETrue); + } + + // If there is no target, only complete the message, if any. + if ( modTarget ) + { + // Check suspended targets, only call plugin for unsuspended ones + TInt unsuspendedTargets = GetAndCheckUnsuspendedTargetsL(modTarget); + + // Call the plugin if any unsuspended targets + if ( unsuspendedTargets ) + { + HWRMLightCommand::TLightsOffData pluginCommand; + pluginCommand.iTarget = unsuspendedTargets; + pluginCommand.iFadeOut = aFadeOut; + HWRMLightCommand::TLightsOffCmdPackage pckg(pluginCommand); + ExecutePluginCommandL(unsuspendedTargets, aMessage, HWRMLightCommand::ELightsOffCmdId, pckg, EFalse); + + // Publish state already here if cleaning up, since no ProcessResponse will come + if ( iCleaningUp ) + { + iLightCommonData.PublishLightStatus(unsuspendedTargets, CHWRMLight::ELightOff); + } + } + else + { + // complete message if suspended, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + // Use unmodified target in state update as virtual state for inactive targets needs to be preserved. + if ( !aActivationInitiated ) + { + UpdateTimersAndStoreStates(aTimerInitiated, aDuration, aTarget, CHWRMLight::ELightOff, KHWRMDefaultIntensity, aFadeOut, 0, 0); + } + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsOffL - Target empty, only complete message" ) ); + + // complete message if one is pending, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsOffL - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::LightsBlinkL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::LightsBlinkL(TInt aTarget, + TInt aDuration, + TInt aIntensity, + TInt aOnCycleTime, + TInt aOffCycleTime, + const RMessage2& aMessage, + TBool aTimerInitiated, + TBool aActivationInitiated) + { + COMPONENT_TRACE9(_L( "HWRM Server - CHWRMLightService::LightsBlinkL(0x%x ,%d, %d, %d, %d, 0x%x, %d, %d)" ), aTarget, + aDuration, + aIntensity, + aOnCycleTime, + aOffCycleTime, + aMessage.Handle(), + aTimerInitiated, + aActivationInitiated); + + CheckCommonParametersL( aTarget, aDuration, aIntensity); + CheckDurationParameterL( aOnCycleTime ); + CheckDurationParameterL( aOffCycleTime ); + + // If one of the cycle durations is default, both must be + if ( aOnCycleTime == KHWRMDefaultCycleTime || aOffCycleTime == KHWRMDefaultCycleTime ) + { + if ( aOnCycleTime != aOffCycleTime ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::LightsBlinkL - Default cycle duration mismatch (%d,%d)" ), aOnCycleTime, aOffCycleTime); + User::Leave(KErrArgument); + } + } + + TInt modTarget(aTarget); + + if ( !aActivationInitiated ) + { + modTarget = ModifyTargetMaskL(aTarget, EFalse); + } + + // If there is no target, only complete the message, if any. + if ( modTarget ) + { + + // Check suspended targets, only call plugin for unsuspended ones + TInt unsuspendedTargets = GetAndCheckUnsuspendedTargetsL(modTarget); + + // Call the plugin if any unsuspended targets + if ( unsuspendedTargets ) + { + // Call the plugin + HWRMLightCommand::TLightsBlinkData pluginCommand; + pluginCommand.iTarget = unsuspendedTargets; + pluginCommand.iIntensity = aIntensity; + pluginCommand.iOnCycleDuration = aOnCycleTime; + pluginCommand.iOffCycleDuration = aOffCycleTime; + HWRMLightCommand::TLightsBlinkCmdPackage pckg(pluginCommand); + ExecutePluginCommandL(unsuspendedTargets, aMessage, HWRMLightCommand::ELightsBlinkCmdId, pckg, EFalse); + + // Publish state already here if cleaning up, since no ProcessResponse will come + if ( iCleaningUp ) + { + iLightCommonData.PublishLightStatus(unsuspendedTargets, CHWRMLight::ELightBlink); + } + } + else + { + // complete message if suspended, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + // Use unmodified target in state update as virtual state for inactive targets needs to be preserved. + if ( !aActivationInitiated ) + { + UpdateTimersAndStoreStates(aTimerInitiated, aDuration, aTarget, CHWRMLight::ELightBlink, aIntensity, EFalse, aOnCycleTime, aOffCycleTime); + } + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsBlinkL - Target empty, only complete message" ) ); + + // complete message if one is pending, as there will not be ProcessResponseL + if ( aMessage.Handle() ) + { + aMessage.Complete(KErrNone); + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::LightsBlinkL - return" ) ); + + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ProcessResponseL +// Handles Light requests responses. +// CommandId not required as all commands have same response value +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ProcessResponseL( TInt aCommandId, TUint8 aTransId, TDesC8& aData, TBool aTimeout ) + { + COMPONENT_TRACE4(_L( "HWRM Server - CHWRMLightService::ProcessResponseL(0x%x ,0x%x, , 0x%x)" ), aCommandId, aTransId, aTimeout ); + + TInt pluginErr(KErrNone); // Error came from plugin as data (or timeout). Used to complete RMessage. + TInt contextErr(KErrNone); // Error in context, i.e. bad handle or descriptor. Used to leave. + + // Unpack the package. All light messages contain only possible error code + // in return package. + if ( !aTimeout && aData.Size() != sizeof(TInt) ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - Data size mismatch, expected: 0x%x, got 0x%x" ), sizeof(TInt), aData.Size() ); + contextErr = KErrBadDescriptor; + pluginErr = KErrBadDescriptor; + } + else + { + // If response was caused by timeout, set that as the error. + // Timeout handled this way instead of just returning KErrTimeout in aData because + // aData format is not known in plugin handler and in theoretically some new commands + // may also return different response than just error code in future. + if ( aTimeout ) + { + pluginErr = KErrTimedOut; + } + else + { + HWRMLightCommand::TErrorCodeResponsePackage errPckg; + errPckg.Copy(aData); + pluginErr = errPckg(); + } + + if ( pluginErr != KErrNone ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - Error: %d" ), pluginErr ); + } + + // Get target of the request + THWRMLightPluginRequestData* data = static_cast(iTransactionList->FindTransaction(aTransId, EFalse)); + + // Update light status PS state value + if ( data && (pluginErr == KErrNone) ) + { + // Do not publish statuses after cleanup has started, as those would incorrectly override statuses set by cleanup + if ( !iCleaningUp ) + { + switch ( aCommandId ) + { + case HWRMLightCommand::ELightsOnCmdId: + { + iLightCommonData.PublishLightStatus(data->iTarget, CHWRMLight::ELightOn); + break; + } + case HWRMLightCommand::ELightsOnSensorCmdId: + { + iLightCommonData.PublishLightStatus(data->iTarget, CHWRMLight::ELightOn); + break; + } + case HWRMLightCommand::ELightsBlinkCmdId: + { + iLightCommonData.PublishLightStatus(data->iTarget, CHWRMLight::ELightBlink); + break; + } + case HWRMLightCommand::ELightsOffCmdId: + { + iLightCommonData.PublishLightStatus(data->iTarget, CHWRMLight::ELightOff); + break; + } + case HWRMLightCommand::ESetLightsIntensityCmdId: + { + // No need to publish status in this case + break; + } + case HWRMLightCommand::ESetLightsSensorSensitivityCmdId: + { + // No need to publish status in this case + break; + } + + case HWRMLightCommand::ELightsSetColorCmdId: + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - ELightsSetColorCmdId iSplitCommand=0x%x iSplitCommandId=0x%x"), data->iSplitCommand, data->iSplitCommandId); + if(data->iSplitCommand) + { + switch(data->iSplitCommandId) + { + case HWRMLightCommand::ELightsOnCmdId: + { + THWRMLightsOnData *lightsOnData = (THWRMLightsOnData*)data->iSplitCommandData; + if(lightsOnData) + { + LightsOnL( lightsOnData->iTarget, + lightsOnData->iDuration, + lightsOnData->iIntensity, + lightsOnData->iFadeIn, + data->iRequestMessage ); + } + break; + } + case HWRMLightCommand::ELightsBlinkCmdId: + { + THWRMLightsBlinkData *lightsBlinkData = (THWRMLightsBlinkData*)data->iSplitCommandData; + if(lightsBlinkData) + { + LightsBlinkL( lightsBlinkData->iTarget, + lightsBlinkData->iDuration, + lightsBlinkData->iIntensity, + lightsBlinkData->iOnCycleDuration, + lightsBlinkData->iOffCycleDuration, + data->iRequestMessage ); + } + break; + } + default: + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - ELightsSetColorCmdId Invalid iSplitCommandId=0x%x"), data->iSplitCommandId); + break; + } + + } + } + break; + } + default: + { + iLightCommonData.PublishLightStatus(data->iTarget, CHWRMLight::ELightStatusUnknown); + break; + } + } + } + } + else + { + // No data found or error in plugin. + TInt target = KHWRMAllTargets; + + if ( data ) + { + target = data->iTarget; + } + + if(aCommandId != HWRMLightCommand::ELightsSetColorCmdId) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - Set ELightStatusUnknown CommandId=%d"), aCommandId); + iLightCommonData.PublishLightStatus(target, CHWRMLight::ELightStatusUnknown); + } + } + } + + // Complete request and delete transaction + contextErr = CompleteRequest(aTransId, pluginErr); + + // Leave if there is error in context + User::LeaveIfError(contextErr); + + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ProcessResponseL - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::UpdateTimersAndStoreStates +// Stores base states of target data objects as necessary. +// This is called from various lights setting methods as opposed to +// ProcessResponseL so that base state will be correct even if timer fires +// before plugin call completes. If plugin subsequently calls ProcessResponseL +// with error condition, the stored base state can unfortunately be +// inconsistent with real state, but that should be no problem, +// as the stored state is the last state user has requested. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::UpdateTimersAndStoreStates(TBool aTimerInitiated, + TInt aDuration, + TInt aTarget, + CHWRMLight::TLightStatus aState, + TInt aIntensity, + TBool aFade, + TInt aOnCycleTime, + TInt aOffCycleTime) + { + COMPONENT_TRACE9(_L( "HWRM Server - CHWRMLightService::UpdateTimersAndStoreStates(0x%x, %d, 0x%x, 0x%x, %d, 0x%x, %d, %d)" ), aTimerInitiated, aDuration, aTarget, aState, aIntensity, aFade, aOnCycleTime, aOffCycleTime ); + + // For system targets, use full system target + TInt updateTarget(aTarget); + if ( aTarget & CHWRMLight::ESystemTarget) + { + updateTarget = iFullSystemTarget; + } + + + // Start timer or update base state if call is not timer initiated. + if ( !aTimerInitiated ) + { + if ( aDuration != KHWRMInfiniteDuration ) + { + // Start timer(s) + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( (updateTarget & iTargets[i].iTarget) == iTargets[i].iTarget) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::UpdateTimersAndStoreStates - Starting new timer with duration %d for target index %d" ), aDuration, i ); + iTargets[i].iTimer->Set(aDuration*1000); + + if ( iTargets[i].iBaseState.iState == CHWRMLight::ELightStatusUnknown ) + { + // If duration based call and base state unknown, + // set base state to off to avoid endless lighting. + iTargets[i].iBaseState.iState = CHWRMLight::ELightOff; + } + } + } + } + else + { + // Since this is not timer related call, update base data and cancel related timers. + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( (updateTarget & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::UpdateTimersAndStoreStates - Setting base state (0x%x) for target index %d" ), aState, i ); + iTargets[i].iBaseState.iIntensity = aIntensity; + iTargets[i].iBaseState.iState = aState; + iTargets[i].iBaseState.iFade = aFade; + iTargets[i].iBaseState.iOnCycleDuration = aOnCycleTime; + iTargets[i].iBaseState.iOffCycleDuration = aOffCycleTime; + iTargets[i].iTimer->Cancel(); + } + } + } + } + else + { + // no else, this is for timer related calls, so no need to cancel or set timers or base data + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::UpdateTimersAndStoreStates - Timer/resume initiated call, base states not updated" ) ); + } + + // Store last states on every call + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( (updateTarget & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + iTargets[i].iLastState.iIntensity = aIntensity; + iTargets[i].iLastState.iState = aState; + iTargets[i].iLastState.iFade = aFade; + iTargets[i].iLastState.iOnCycleDuration = aOnCycleTime; + iTargets[i].iLastState.iOffCycleDuration = aOffCycleTime; + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::UpdateTimersAndStoreStates - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::GenericTimerFired +// Handles Light cutoff timer firing. +// aCutOff is not used with lights. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::GenericTimerFired(TInt aTimerId, TBool /*aCutOff*/) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::GenericTimerFired(0x%x)" ), aTimerId ); + + // Return the base state for target + RestoreState(iTargets[aTimerId], EStateChangeBaseState, ETrue); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::GenericTimerFired - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::RestoreState +// Restores target state. aTargetData is always single target data, except in case of +// restoring default state. In that case aDefaultTargetMask must contain a mask and +// aTargetData is ignored. It must still be a valid reference. +// aDefaultTargetMask may not contain both system and non-system targets. +// Note: If restored state used default intensity, restored state could potentially +// have different intensity or use sensor, if user has changed the settings +// while timer was active. This is correct behaviour however. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::RestoreState(const THWRMLightTargetData& aTargetData, + TStateChangeType aStateType, + TBool aTimerInitiated, + TInt aDefaultTargetMask, + const RMessage2* aMessage, + TBool aActivationInitiated ) + { + COMPONENT_TRACE7(_L( "HWRM Server - CHWRMLightService::RestoreState(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" ), aTargetData.iTarget, + aStateType, + aTimerInitiated, + aDefaultTargetMask, + aMessage ? aMessage->Handle() : 0, + aActivationInitiated ); + + TInt err(KErrNone); + + RMessage2 message; + + // If non-null message pointer is provided, use that. Otherwise empty dummy message is used. + if ( aMessage ) + { + message = *aMessage; + } + + // Get correct state data + TInt duration(KHWRMInfiniteDuration); + TInt targetMask(aTargetData.iTarget); + const THWRHLightTargetStateData* targetStateData = NULL; + + + TUint color = KHWRMDefaultColor; + + switch ( aStateType ) + { + case EStateChangeFrozenState: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::RestoreState - EStateChangeFrozenState")); + targetStateData = &(aTargetData.iFrozenState); + duration = aTargetData.iFrozenTime; + color = targetStateData->iColor; + break; + } + case EStateChangeBaseState: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::RestoreState - EStateChangeBaseState")); + targetStateData = &(aTargetData.iBaseState); + color = targetStateData->iColor; + COMPONENT_TRACE2(_L("HWRM Server - CHWRMLightService::RestoreState - EStateChangeBaseState color(0x%x)"), color); + break; + } + case EStateChangeLastState: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::RestoreState - EStateChangeLastState")); + targetStateData = &(aTargetData.iLastState); + color = targetStateData->iColor; + break; + } + case EStateChangeDefaultState: + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::RestoreState - EStateChangeDefaultState")); + // Target mask may not contain both system and non-system targets + targetMask = aDefaultTargetMask; + if (targetMask & iFullSystemTarget) + { + COMPONENT_TRACE1(_L("HWRM Server - CHWRMLightService::RestoreState - GetData")); + iDefaultState.iState = iLightCommonData.DefaultState(); + } + else + { + iDefaultState.iState = CHWRMLight::ELightOff; + } + + //Restore color only if light state is off. + if(iDefaultState.iState != CHWRMLight::ELightOff) + { + color = KHWRMInvalidColorMask; + } + + COMPONENT_TRACE2(_L("HWRM Server - CHWRMLightService::RestoreState - DefaultState=0x%x"), iDefaultState.iState); + targetStateData = &iDefaultState; + break; + } + default: + { + // Cannot get here. Panic if it does for some reason. + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::RestoreState - Invalid state: 0x%x - Panicing" ), aStateType ); + User::Panic(KPanicCategory, EPanicBadHandle); + break; + } + } + + // If state to be restored is unknown, default state is restored instead. + // Basically this is issue only when duration based call is used prior to infinite calls. + // + // Note: This can result in different targets being restored to different default + // states, if default state changes between target restorings. Should be + // extremely rare though, considering that most light users will have set + // some base state anyway. + if ( targetStateData->iState == CHWRMLight::ELightStatusUnknown ) + { + // Default state of non-system targets is always off + if (targetMask & iFullSystemTarget) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::RestoreState - State for state type (0x%x) unknown - Using default state" ), aStateType ); + iDefaultState.iState = iLightCommonData.DefaultState(); + targetStateData = &iDefaultState; + } + else + { + iDefaultState.iState = CHWRMLight::ELightOff; + targetStateData = &iDefaultState; + } + } + + if(color != KHWRMInvalidColorMask) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::RestoreState - Restore color with 0x%x" ), color); + TRAP_IGNORE(SetColorL(targetMask, color, message, aActivationInitiated)); + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::RestoreState - Invalid Color Mask")); + } + + // Call appropriate method to restore target state + switch ( targetStateData->iState ) + { + case CHWRMLight::ELightOn: + { + TRAP(err, LightsOnL(targetMask, duration, targetStateData->iIntensity, targetStateData->iFade, message, aTimerInitiated, aActivationInitiated)); + break; + } + case CHWRMLight::ELightOff: + { + TRAP(err, LightsOffL(targetMask, duration, targetStateData->iFade, message, aTimerInitiated, aActivationInitiated)); + break; + } + case CHWRMLight::ELightBlink: + { + TRAP(err, LightsBlinkL(targetMask, duration, targetStateData->iIntensity, targetStateData->iOnCycleDuration, targetStateData->iOffCycleDuration, message, aTimerInitiated, aActivationInitiated)); + break; + } + default: + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::RestoreState - Invalid target status: 0x%x" ), targetStateData->iState ); + break; + } + } + + if ( err != KErrNone ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::RestoreState - Error in restoring light state: %d" ), err ); + + // complete message if one is pending, as there will not be ProcessResponseL + if ( aMessage ) + { + if ( aMessage->Handle() ) + { + aMessage->Complete(KErrNone); + } + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::RestoreState - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::CheckCommonParametersL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::CheckCommonParametersL(TInt aTarget, + TInt aDuration, + TInt aIntensity) const + { + CheckTargetParameterL(aTarget); + + CheckDurationParameterL(aDuration); + + if ( aIntensity != KHWRMDefaultIntensity && (aIntensity < KHWRMLightMinIntensity || aIntensity > KHWRMLightMaxIntensity) ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::CheckCommonParametersL - Invalid Intensity: %d" ), aIntensity ); + User::Leave(KErrArgument); + } + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::CheckDurationParameterL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::CheckDurationParameterL(TInt aDuration) const + { + if ( aDuration < 0 || aDuration > KHWRMLightMaxDuration ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::CheckCommonParametersL - Invalid Duration: %d" ), aDuration ); + User::Leave(KErrArgument); + } + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::CheckTargetParameterL +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::CheckTargetParameterL(TInt aTarget) const + { + // All target combinations specified in supported targets mask + system target are legal + if ( (~(iSupportedTargets | CHWRMLight::ESystemTarget) & aTarget) || aTarget == CHWRMLight::ENoTarget ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::CheckCommonParametersL - Invalid Target: 0x%x. (Supported: 0x%x)" ), aTarget, iSupportedTargets ); + User::Leave(KErrNotSupported); + } + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::SuspendSubResource +// Suspends light target +// Suspension doesn't actually change light state, it is responsibility of the +// active reserver of the target to change the state to desirable one. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::SuspendSubResource(TInt aSubResource) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::SuspendSubResource(0x%x)" ), aSubResource ); + + iTargets[aSubResource].iSuspended = ETrue; + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::SuspendSubResource - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ResumeSubResource +// Resumes suspended light target +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ResumeSubResource(TInt aSubResource) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ResumeSubResource(0x%x)" ), aSubResource ); + + iTargets[aSubResource].iSuspended = EFalse; + + // Restore last state + // Set aTimerInitiated to ETrue on RestoreState call, so that base states and timers will + // not be affected by this state change. + RestoreState(iTargets[aSubResource], EStateChangeLastState, ETrue); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ResumeSubResource - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ActivateSubResource +// If subresource is activated, restore its state. +// If it is deactivated, turn it off +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ActivateSubResource(TInt aSubResource, TBool aActivate) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::ActivateSubResource(0x%x, 0x%x)" ), aSubResource, aActivate ); + + RMessage2 message; // dummy message + + // Set aActivationIntiated to ETrue on RestoreState/lights off calls, so that target is not recursively modified, + // and states/timers will not be affected by this call. + + if (aActivate) + { + RestoreState(iTargets[aSubResource], EStateChangeLastState, ETrue, CHWRMLight::ENoTarget, &message, ETrue); + } + else + { + // Just turn target off + TRAPD(err, LightsOffL(iTargets[aSubResource].iTarget, KHWRMInfiniteDuration, iDefaultState.iFade, message, ETrue, ETrue)); + + if ( err != KErrNone ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ActivateSubResource - error turning lights off: %d" ), err ); + } + } + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::GetAndCheckUnsuspendedTargetsL +// Checks which targets of specified aTarget mask are unsuspended and returns +// a new mask of those targets. +// ----------------------------------------------------------------------------- +// +TInt CHWRMLightService::GetAndCheckUnsuspendedTargetsL(TInt aTarget) const + { + TInt unsuspendedTargets(0); + + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( !iTargets[i].iSuspended && (aTarget & iTargets[i].iTarget) ) + { + unsuspendedTargets |= iTargets[i].iTarget; + } + } + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::GetAndCheckUnsuspendedTargetsL: 0x%x" ), unsuspendedTargets ); + + // If there are any unsuspended targets, check reservation status for those. + if ( unsuspendedTargets ) + { + // Check reservation. + if ( iReservationHandler->IsReserved(this, unsuspendedTargets) ) + { + User::Leave(KErrInUse); + } + } + + return unsuspendedTargets; + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ExecutePluginCommandL +// Executes a plugin command and handles related transaction. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::ExecutePluginCommandL(TInt aTarget, + const RMessage2& aMessage, + TInt aCommandId, + TDesC8& aPckg, + TBool aSplitCommand, + TInt aSplitCommandId , + TAny* aSplitCommandData ) + { + // Create new data (TransId is updated later) + THWRMPluginRequestData* data = new (ELeave) THWRMLightPluginRequestData(aTarget, aMessage, 0, aCommandId, aSplitCommand, aSplitCommandId, aSplitCommandData); + CleanupStack::PushL( data ); + + // When cleaning up, do not set callback as ProcessResponse would result in panic + if ( iCleaningUp ) + { + data->iTransId = iPluginHandler->ProcessCommandL(aCommandId, aPckg, NULL); + } + else + { + data->iTransId = iPluginHandler->ProcessCommandL(aCommandId, aPckg, this); + } + + // data still needed, do not destroy, just pop + CleanupStack::Pop( data ); + + // Add data to list + iTransactionList->AddTransaction( data ); + } + +// ----------------------------------------------------------------------------- +// CHWRMLightService::SystemLightsOn +// Turns all unreserved system lights on. +// Custom lights are assumed to be specialty lights and therefore not grouped +// for this common turn on of lights. +// ----------------------------------------------------------------------------- +// +void CHWRMLightService::SystemLightsOn() + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::SystemLightsOn()" ) ); + + TInt err(KErrNone); + + RMessage2 dummy; + + TRAP(err, LightsOnL(CHWRMLight::ESystemTarget, KHWRMInfiniteDuration, KHWRMDefaultIntensity, EFalse, dummy )); + + if ( err != KErrNone ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::SystemLightsOn - Error setting lights on: %d" ), err ); + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::SystemLightsOn - return" ) ); + } + + +// ----------------------------------------------------------------------------- +// CHWRMLightService::ModifyTargetMaskL +// Modifies target mask depending on current device configuration +// Note: Recursive calls to this method caused by activation callbacks from +// ReservationHandler must be avoided. Therefore target is only modified +// initially and activation caused calls will not call this method. +// ----------------------------------------------------------------------------- +// +TInt CHWRMLightService::ModifyTargetMaskL(TInt aTarget, TBool aLightsOff) + { + TInt modifiedMask(CHWRMLight::ENoTarget); + TInt target(aTarget); + + if ( aTarget & CHWRMLight::ESystemTarget ) + { + target = iFullSystemTarget; + } + + // Non-system target modifications are passed directly to plugin + modifiedMask = iLightCommonData.ModifyTargetL( target ); + + // Make sure modified mask doesn't contain any targets not in original mask, + // as this can cause problems with ReservationHandler and is therefore not supported. + modifiedMask &= target; + + // Update active mask to reservation handler + iReservationHandler->UpdateActiveMask(target, modifiedMask, this); + + // If command is lights off, do not return modified mask but the original + // or reservation corrected system mask, as lights off is ok for inactive targets. + if ( aLightsOff ) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::ModifyTargetMaskL - Lights off, target modification only used for activation purposes" ) ); + modifiedMask = target; + } + + if ( aTarget & CHWRMLight::ESystemTarget ) + { + TInt reservations(CHWRMLight::ENoTarget); + + // Get targets reserved for this session + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( iTargets[i].iReserved ) + { + reservations |= iTargets[i].iTarget; + } + } + + // Get Unreserved targets + reservations |= iReservationHandler->GetUnreservedTargets(); + + modifiedMask &= reservations; + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ModifyTargetMaskL - final system mask: 0x%x" ), modifiedMask ); + } + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::ModifyTargetMaskL - returning: 0x%x" ), modifiedMask ); + + return modifiedMask; + } + +TBool CHWRMLightService::SetColorL(TInt aTarget, TUint aColor, const RMessage2& aMessage, TBool aActivationInitiated, + TBool aSplitCommand, TInt aSplitCommandId, TAny* aSplitCommandData) + { + COMPONENT_TRACE7(_L( "HWRM Server - CHWRMLightService::SetColorL(0x%x, 0x%x, %d, 0x%x, 0x%x, 0x%x)" ), + aTarget, aColor, aActivationInitiated, aSplitCommand, aSplitCommandId, aSplitCommandData); + + TBool pluginCommandCalled = EFalse; + + CheckTargetParameterL( aTarget); + + TInt modTarget(aTarget); + + if ( !aActivationInitiated ) + { + modTarget = ModifyTargetMaskL(aTarget, EFalse); + } + + // Check suspended targets, only call plugin for unsuspended ones + TInt unsuspendedTargets = GetAndCheckUnsuspendedTargetsL(modTarget); + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::SetColorL unSuspended=0x%x)" ), unsuspendedTargets); + + // Call the plugin if any unsuspended targets + if ( unsuspendedTargets ) + { + HWRMLightCommand::TLightsColorData pluginCommand; + Mem::FillZ(&pluginCommand, sizeof(HWRMLightCommand::TLightsColorData)); + + pluginCommand.iTarget = unsuspendedTargets; + + if(aColor & KHWRMSetColorMask) + { + + pluginCommand.iBlue = ((aColor) & 0xFF); + pluginCommand.iGreen = ((aColor>>KHWRMGreenShift) & 0xFF); + pluginCommand.iRed = ((aColor>>KHWRMRedShift) & 0xFF); + + pluginCommand.iDefaultColor = EFalse; + } + else + { + pluginCommand.iDefaultColor = ETrue; + } + + HWRMLightCommand::TLightsColorCmdPackage pckg(pluginCommand); + + ExecutePluginCommandL(unsuspendedTargets, aMessage, HWRMLightCommand::ELightsSetColorCmdId, pckg, aSplitCommand, aSplitCommandId, aSplitCommandData); + + pluginCommandCalled = ETrue; + } + else + { + // complete message if suspended, as there will not be ProcessResponseL + if ( aMessage.Handle() && (!aSplitCommand)) + { + aMessage.Complete(KErrNone); + } + + if (aSplitCommand && aSplitCommandData) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMLightService::SetColorL Deleting allocated aSplitCommandData")); + //Release the data that is allocated, as there will not be ProcessResponseL + //coverity[freed_arg] + delete aSplitCommandData; + } + } + + for( TInt i = 0; i < KHWRMLightMaxTargets; i++ ) + { + if ( (aTarget & iTargets[i].iTarget) == iTargets[i].iTarget ) + { + if(aSplitCommand) + { + //Store the base state only if it is duration based call. + TUint color = iTargets[i].iLastState.iColor; + if(color == KHWRMInvalidColorMask) + { + color = KHWRMDefaultColor; + } + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMLightService::SetColorL BaseStateColor(0x%x) for target(0x%x)"), color, i); + iTargets[i].iBaseState.iColor = color; + } + else + { + //iTargets[i].iBaseState.iColor = KHWRMInvalidColorMask; + } + iTargets[i].iLastState.iColor = aColor; + } + } + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMLightService::SetColorL - return %d" ), pluginCommandCalled ); + + return pluginCommandCalled; + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File