resourcemgmt/hwresourcesmgr/extendedlight/src/HWRMExtendedLightStatusObserver.cpp
// 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 "HWRMPrivatePSKeys.h"
#include "HWRMtrace.h"
#include "HWRMExtendedLight.h"
#include "HWRMExtendedLightStatusObserver.h"
#include "HWRMLightClientServer.h" // for KHWRMLightMaxTargets
// CONSTANTS
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::CHWRMExtendedLightStatusObserver
// C++ constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CHWRMExtendedLightStatusObserver::CHWRMExtendedLightStatusObserver(MHWRMExtendedLightObserver* aCallback,
TInt aSupportedTargets)
: CActive(EPriorityStandard),
iCallback(aCallback),
iSupportedTargets(aSupportedTargets)
{
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::CHWRMExtendedLightStatusObserver(0x%x)" ), aCallback);
CActiveScheduler::Add(this);
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::CHWRMExtendedLightStatusObserver - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::NewL
// Two-phased constructor
// -----------------------------------------------------------------------------
//
CHWRMExtendedLightStatusObserver* CHWRMExtendedLightStatusObserver::NewL(MHWRMExtendedLightObserver* aCallback,
TInt aSupportedTargets)
{
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::NewL(0x%x)" ), aCallback);
CHWRMExtendedLightStatusObserver* newInstance = new (ELeave) CHWRMExtendedLightStatusObserver(aCallback, aSupportedTargets);
CleanupStack::PushL( newInstance );
newInstance->ConstructL();
CleanupStack::Pop();
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::NewL - return 0x%x" ), newInstance );
return newInstance;
}
// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CHWRMExtendedLightStatusObserver::~CHWRMExtendedLightStatusObserver()
{
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::~CHWRMExtendedLightStatusObserver()" ));
// Cancel property separately, as the following Cancel() call doesn't seem to
// cause DoCancel to fire.
iProperty.Cancel();
Cancel();
iProperty.Close();
iLastStatusValue.Close();
iStatusUnknownList.Close();
iCallback = NULL; // PCLint demands
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::~CHWRMExtendedLightStatusObserver - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CHWRMExtendedLightStatusObserver::ConstructL()
{
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::ConstructL()" ));
User::LeaveIfError( InitializeStatusArray( iLastStatusValue ) );
User::LeaveIfError( InitializeStatusArray( iStatusUnknownList ) );
User::LeaveIfError(iProperty.Attach(KPSUidHWResourceNotification, KHWRMLightStatus));
// Call RunL to order notification and do the initial notifying of the client
RunL();
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::ConstructL - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::RunL
// Handle notification from pubsub session.
// -----------------------------------------------------------------------------
//
void CHWRMExtendedLightStatusObserver::RunL()
{
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::RunL()" ));
// Reorder notification
OrderNotification();
// get value from pubsub
RLightStatusArray statusArray( KHWRMLightMaxTargets );
CleanupClosePushL( statusArray );
TInt err = InitializeStatusArray( statusArray );
if( err == KErrNone )
{
TInt arraySize = sizeof( THWRMStatusInfo ) * KHWRMLightMaxTargets;
TPtr8 arrayPtr( ( TUint8* )&statusArray[0], arraySize, arraySize );
err = iProperty.Get( arrayPtr );
if ( err == KErrNotFound || err == KErrNone )
{
NotifyCallback( statusArray );
}
}
else
{
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::RunL. Error (%d) in iProperty.Get()" ), err);
NotifyCallback(iStatusUnknownList );
}
CleanupStack::PopAndDestroy( &statusArray );
User::LeaveIfError( err );
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::RunL - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::DoCancel
// Handle cancel order on this active object.
// -----------------------------------------------------------------------------
//
void CHWRMExtendedLightStatusObserver::DoCancel()
{
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::DoCancel()" ));
iProperty.Cancel();
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::DoCancel - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::OrderNotification
// Order new notification from CenRep.
// -----------------------------------------------------------------------------
//
void CHWRMExtendedLightStatusObserver::OrderNotification()
{
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::OrderNotification()" ));
iProperty.Subscribe(iStatus);
SetActive();
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::OrderNotification - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::NotifyCallback
// Order new notification from CenRep.
// -----------------------------------------------------------------------------
//
void CHWRMExtendedLightStatusObserver::NotifyCallback( RLightStatusArray& aStatusList )
{
COMPONENT_TRACE1( ( _L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::NotifyCallback" ) ) );
// Loop through value and update client. Hold notifying client until end unless there are
// multiple differently changed target statuses.
TInt currentTarget = KHWRMLightFirstTarget;
TInt currentStatus = 0;
TInt lastChangedStatus = 0;
TInt index = 0;
for( TInt i = 0; i < KHWRMLightMaxTargets; i++ )
{
// only notify for supported targets
if( currentTarget & iSupportedTargets )
{
index = aStatusList.FindInOrder( currentTarget, FindByTarget );
if( index >= 0 && index < KHWRMLightMaxTargets )
{
currentStatus = aStatusList[index].iStatus;
index = iLastStatusValue.FindInOrder( currentTarget, FindByTarget );
if( index >= 0 && index < KHWRMLightMaxTargets )
{
lastChangedStatus = iLastStatusValue[index].iStatus;
// If last value for masked target is different than new value, prepare to notify about that target
if( lastChangedStatus != currentStatus )
{
// update last status value and notify client
iLastStatusValue[index].iStatus = currentStatus;
if( iCallback )
{
iCallback->LightStatusChanged( currentTarget,
static_cast<CHWRMExtendedLight::TLightStatus>( currentStatus ) );
}
}
}
}
}
// shift the target ready for next loop
currentTarget <<= 1;
}
COMPONENT_TRACE1(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::NotifyCallback - return" ) );
}
// -----------------------------------------------------------------------------
// CHWRMExtendedLightStatusObserver::CurrentStatus
// Return Light status
// -----------------------------------------------------------------------------
//
CHWRMExtendedLight::TLightStatus CHWRMExtendedLightStatusObserver::CurrentStatus(TInt aTarget) const
{
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::CurrentStatus(0x%x)" ), aTarget );
CHWRMExtendedLight::TLightStatus status( CHWRMExtendedLight::ELightStatusUnknown );
RLightStatusArray currentStatus( KHWRMLightMaxTargets );
TInt err = InitializeStatusArray( currentStatus );
if ( err == KErrNone )
{
TInt arraySize = sizeof( THWRMStatusInfo ) * KHWRMLightMaxTargets;
TPtr8 arrayPtr( ( TUint8* )¤tStatus[0], arraySize, arraySize );
err = RProperty::Get( KPSUidHWResourceNotification, KHWRMLightStatus, arrayPtr );
if( err == KErrNone )
{
TInt index = currentStatus.FindInOrder( aTarget, FindByTarget );
if( index >= 0 && index < KHWRMLightMaxTargets )
{
status = static_cast<CHWRMExtendedLight::TLightStatus>(
currentStatus[index].iStatus );
}
}
}
// Clean up
currentStatus.Close();
COMPONENT_TRACE2(_L( "HWRM ExtendedLightClient - CHWRMExtendedLightStatusObserver::CurrentStatus - return 0x%x" ), status );
return status;
}
// -----------------------------------------------------------------------------
// CHWRMLightExtendedStatusObserver::FindByTarget
// Finds item from iStatusList by target.
// -----------------------------------------------------------------------------
//
TInt CHWRMExtendedLightStatusObserver::FindByTarget( const TInt* aTarget,
const THWRMStatusInfo& aItem )
{
if ( *aTarget < aItem.iTarget )
{
return -1;
}
else if ( *aTarget > aItem.iTarget )
{
return 1;
}
return 0;
}
// -----------------------------------------------------------------------------
// CHWRMLightStatusObserver::InitializeStatusArray
// Initializes RLightStatusArray.
// -----------------------------------------------------------------------------
//
TInt CHWRMExtendedLightStatusObserver::InitializeStatusArray(
RLightStatusArray& aArray ) const
{
TInt err = KErrNone;
TInt currentTarget( KHWRMLightFirstTarget );
for( TInt i = 0; i < KHWRMLightMaxTargets; i++ )
{
THWRMStatusInfo info;
info.iTarget = currentTarget;
info.iStatus = CHWRMLight::ELightStatusUnknown;
err = aArray.Append( info );
if( err != KErrNone )
{
break;
}
// shift the mask and target ready for next loop
currentTarget <<= 1;
}
return err;
}
// End of File