--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/Client/src/alfcommandscheduler.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,591 @@
+/*
+* Copyright (c) 2007 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: Command scheduler.
+*
+*/
+
+
+
+#include "alfcommandscheduler.h"
+#include "alf/alfcommand.h"
+#include "alflogger.h"
+
+#include <uiacceltk/HuiUtil.h>
+
+// Internal flags.
+enum TAlfSchedulerFlags
+ {
+ EAlfSchedulerPrimaryLightsOn = 0x01,
+ EAlfSchedulerSecondaryLightsOn = 0x02,
+ EAlfSchedulerApplicationForeground = 0x04,
+ EAlfSchedulerRunning = 0x08
+ };
+
+// ======== CTimedEvent MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler::CTimedEvent* CAlfCommandScheduler::CTimedEvent::NewLC(
+ const TAlfCommand& aCommand,
+ CAlfCommandScheduler& aScheduler )
+ {
+ CTimedEvent* self = new (ELeave) CTimedEvent(aScheduler);
+ CleanupStack::PushL( self );
+ self->ConstructL( aCommand );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler::CTimedEvent::~CTimedEvent()
+ {
+ Cancel();
+ delete iCommand;
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler::CTimedEvent::CTimedEvent( CAlfCommandScheduler& aScheduler )
+ : CTimer( EPriorityStandard ), iScheduler( aScheduler )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CTimedEvent::ConstructL(const TAlfCommand& aCommand)
+ {
+ CTimer::ConstructL();
+
+ // Make a copy of the command.
+ TAlfCommand* data = (TAlfCommand*) new (ELeave) TUint8[aCommand.Size()];
+ Mem::Copy((TAny*)data, (TAny*)&aCommand, aCommand.Size());
+ iCommand = data;
+ }
+
+// ---------------------------------------------------------------------------
+// Called when timer triggers.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CTimedEvent::RunL()
+ {
+ iScheduler.ExecuteEventL( *iCommand );
+ delete this;
+ }
+
+// ---------------------------------------------------------------------------
+// Called when RunL leaves
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCommandScheduler::CTimedEvent::RunError(TInt aError)
+ {
+ __ALFLOGSTRING1( "CAlfCommandScheduler::ExecuteEventL leaves with %d", aError )
+ delete this;
+ return aError;
+ }
+
+// ---------------------------------------------------------------------------
+// Execute command after given timed.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CTimedEvent::ExecuteAfter(
+ TInt aIntervalInMilliSeconds,
+ TBool aStartPaused )
+ {
+ __ASSERT_ALWAYS( !IsActive(), USER_INVARIANT() );
+ iTimeLeftInMilliSeconds = aIntervalInMilliSeconds;
+
+ // If the scheduler is not paused...
+ if ( !aStartPaused )
+ {
+ // ...start the timer.
+ After( aIntervalInMilliSeconds * 1000 );
+ iLastStartTime.UniversalTime(); // Update the start-time stamp.
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Pauses the time
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CTimedEvent::Pause()
+ {
+ // If not paused...
+ if ( IsActive() )
+ {
+ // ... cancel the timer and update the time left.
+ Cancel();
+ TTime timeNow;
+ timeNow.UniversalTime();
+ iTimeLeftInMilliSeconds -=
+ timeNow.MicroSecondsFrom( iLastStartTime ).Int64()/1000;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Continue timer.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CTimedEvent::Continue()
+ {
+ // If not running...
+ if ( !IsActive() )
+ {
+ // ... execute the event...
+ if ( iTimeLeftInMilliSeconds <= 0 )
+ {
+ // ...now
+ TRAP_IGNORE(iScheduler.ExecuteEventL( *iCommand ))
+ delete this;
+ }
+ else
+ {
+ // ...after the time left.
+ After( iTimeLeftInMilliSeconds * 1000 );
+ iLastStartTime.UniversalTime(); // Update the start-time stamp.
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Calculates the time left.
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCommandScheduler::CTimedEvent::TimeLeftInMilliSeconds() const
+ {
+ TInt timeLeftInMilliSeconds = 0;
+ if ( IsActive() )
+ {
+ TTime timeNow;
+ timeNow.UniversalTime();
+ timeLeftInMilliSeconds =
+ iTimeLeftInMilliSeconds -
+ timeNow.MicroSecondsFrom( iLastStartTime ).Int64()/1000;
+ }
+ else
+ {
+ timeLeftInMilliSeconds = iTimeLeftInMilliSeconds;
+ }
+
+ if ( timeLeftInMilliSeconds < 0 )
+ {
+ timeLeftInMilliSeconds = 0;
+ }
+ return timeLeftInMilliSeconds;
+ }
+
+// ======== CAlfCommandScheduler MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler* CAlfCommandScheduler::NewL( CAlfEnv& aEnv)
+ {
+ CAlfCommandScheduler* self = new (ELeave) CAlfCommandScheduler( aEnv );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler::CAlfCommandScheduler( CAlfEnv& aEnv)
+ : iEnv(aEnv)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// Update internal flags.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::ConstructL()
+ {
+ iLight = CHWRMLight::NewL(this); // Calls LightStatusChanged()
+
+ iFlags |= EAlfSchedulerApplicationForeground;
+ iFlags |= EAlfSchedulerRunning;
+
+ // Workaround for non-working light status reports
+ iFlags |= EAlfSchedulerPrimaryLightsOn;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CAlfCommandScheduler::~CAlfCommandScheduler()
+ {
+ iEvents.ResetAndDestroy();
+ delete iLight;
+ }
+
+// ---------------------------------------------------------------------------
+// Executes given command after given time
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::ScheduleCommandL(
+ const TAlfCommand& aCommand,
+ TInt aTimeInMilliSeconds )
+ {
+ if (aTimeInMilliSeconds == 0)
+ {
+ __ALFLOGSTRING( "CAlfCommandScheduler::ScheduleCommandL execute now" )
+ // Execute now
+ aCommand.ExecuteL( iEnv );
+ return;
+ }
+
+ // Create timed event
+ __ALFLOGSTRING1( "CAlfCommandScheduler::ScheduleCommandL in %dms", aTimeInMilliSeconds )
+ CTimedEvent* event = CTimedEvent::NewLC( aCommand, *this );
+ iEvents.AppendL( event );
+ CleanupStack::Pop( event );
+ event->ExecuteAfter( aTimeInMilliSeconds, !(iFlags&EAlfSchedulerRunning) );
+ }
+
+// ---------------------------------------------------------------------------
+// Cancel all object commands.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CancelCommands( TAny* aObject )
+ {
+ for ( TInt i = iEvents.Count() - 1; i >= 0; i--)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+ if(objectCommand && objectCommand->Object() == aObject)
+ {
+ delete iEvents[i];
+ iEvents.Remove( i );
+ }
+ }
+ iEvents.Compress();
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels specific operation for given object
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CancelCommands(TAny* aObject, TAlfOp aCommandOperation)
+ {
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+ if(objectCommand &&
+ objectCommand->Object() == aObject &&
+ objectCommand->Operation() == aCommandOperation)
+ {
+ // Cancel this one.
+ delete iEvents[i];
+ iEvents.Remove( i );
+ }
+ }
+ iEvents.Compress();
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels given command types from given object
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::CancelCommands(TAny* aObject,
+ TAlfCommandType aCommandType,
+ TInt aParam)
+ {
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+
+ if(objectCommand &&
+ objectCommand->Object() == aObject &&
+ objectCommand->Type() == aCommandType)
+ {
+ if(objectCommand->Type() == EAlfCommandTypeCustomEvent)
+ {
+ const TAlfCustomEventCommand* cec =
+ (const TAlfCustomEventCommand*) objectCommand;
+
+ if(cec->Param() != aParam)
+ {
+ // Not this one, wrong parameter.
+ continue;
+ }
+ }
+ // Cancel this one.
+ delete iEvents[i];
+ iEvents.Remove( i );
+ }
+ }
+
+ iEvents.Compress();
+ }
+
+// ---------------------------------------------------------------------------
+// Returns time left ot the command
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCommandScheduler::MilliSecondsUntilCommand(
+ TAny* aObject )
+ {
+ TInt returnValue = KErrNotFound;
+
+ for ( TInt i = iEvents.Count() - 1; i >= 0; i--)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+ if(objectCommand && objectCommand->Object() == aObject)
+ {
+ TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds();
+ if ( returnValue == KErrNotFound || timeLeft < returnValue )
+ {
+ returnValue = timeLeft;
+ }
+ }
+ }
+
+ return returnValue;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns time left ot the command
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCommandScheduler::MilliSecondsUntilCommand(
+ TAny* aObject,
+ TAlfOp aCommandOperation )
+ {
+ TInt returnValue = KErrNotFound;
+
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+ if(objectCommand &&
+ objectCommand->Object() == aObject &&
+ objectCommand->Operation() == aCommandOperation)
+ {
+ TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds();
+ if ( returnValue == KErrNotFound || timeLeft < returnValue )
+ {
+ returnValue = timeLeft;
+ }
+ }
+ }
+
+ return returnValue;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns time left ot the command
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCommandScheduler::MilliSecondsUntilCommand(
+ TAny* aObject,
+ TAlfCommandType aCommandType,
+ TInt aParam )
+ {
+ TInt returnValue = KErrNotFound;
+
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ const TAlfObjectCommand* objectCommand =
+ iEvents[i]->iCommand->ObjectCommand();
+
+ if(objectCommand &&
+ objectCommand->Object() == aObject &&
+ objectCommand->Type() == aCommandType)
+ {
+ if(objectCommand->Type() == EAlfCommandTypeCustomEvent)
+ {
+ const TAlfCustomEventCommand* cec =
+ (const TAlfCustomEventCommand*) objectCommand;
+
+ if(cec->Param() != aParam)
+ {
+ // Not this one, wrong parameter.
+ continue;
+ }
+ }
+ TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds();
+ if ( returnValue == KErrNotFound || timeLeft < returnValue )
+ {
+ returnValue = timeLeft;
+ }
+ }
+ }
+
+ return returnValue;
+ }
+
+// ---------------------------------------------------------------------------
+// Executes command
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::ExecuteEventL( TAlfCommand& aCommand )
+ {
+ for ( TInt i = 0 ; i < iEvents.Count() ; i++ )
+ {
+ if ( iEvents[i]->iCommand == &aCommand )
+ {
+ iEvents.Remove( i );
+ iEvents.Compress();
+ break;
+ }
+ }
+
+ aCommand.ExecuteL( iEnv );
+ }
+
+// ---------------------------------------------------------------------------
+// Called when foreground status changes.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::AppicationOnForeground( TBool aForeground )
+ {
+ if ( aForeground )
+ {
+ iFlags |= EAlfSchedulerApplicationForeground;
+ }
+ else
+ {
+ iFlags &= ~EAlfSchedulerApplicationForeground;
+ }
+
+ UpdateSchedulerState();
+ }
+
+// ---------------------------------------------------------------------------
+// Called when display light status changes.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::LightStatusChanged(
+ TInt aTarget,
+ CHWRMLight::TLightStatus aStatus )
+ {
+ if( aTarget&CHWRMLight::EPrimaryDisplay )
+ {
+ if( aStatus == CHWRMLight::ELightOn ||
+ aStatus == CHWRMLight::ELightStatusUnknown )
+ {
+ iFlags |= EAlfSchedulerPrimaryLightsOn;
+ }
+ else if( aStatus == CHWRMLight::ELightOff )
+ {
+ iFlags &= ~EAlfSchedulerPrimaryLightsOn;
+ }
+ else
+ {
+ // for PC lint
+ }
+ }
+
+ if( aTarget&CHWRMLight::ESecondaryDisplay )
+ {
+ if( aStatus == CHWRMLight::ELightOn ||
+ aStatus == CHWRMLight::ELightStatusUnknown )
+ {
+ iFlags |= EAlfSchedulerSecondaryLightsOn;
+ }
+ else if( aStatus == CHWRMLight::ELightOff )
+ {
+ iFlags &= ~EAlfSchedulerSecondaryLightsOn;
+ }
+ else
+ {
+ // for PC lint
+ }
+ }
+
+ UpdateSchedulerState();
+ }
+
+// ---------------------------------------------------------------------------
+// Updates scheduling state based on the internal flags.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::UpdateSchedulerState()
+ {
+ if ( (iFlags&EAlfSchedulerPrimaryLightsOn ||
+ iFlags&EAlfSchedulerSecondaryLightsOn ) &&
+ iFlags&EAlfSchedulerApplicationForeground )
+ {
+ // Run the scheduler
+ Run();
+ }
+ else
+ {
+ // Pause schduler
+ Pause();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Restarts the scheduling.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::Run()
+ {
+ if ( iFlags&EAlfSchedulerRunning )
+ {
+ return; // Already running
+ }
+
+ iFlags |= EAlfSchedulerRunning;
+
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ iEvents[i]->Continue();
+
+ // Executing a command may have potentially altered the iEvents array,
+ // e.g. application may have canceled other commands when one command was
+ // executed. We must make sure that we don't overindex here !
+ if (i > iEvents.Count() + 1)
+ {
+ i = iEvents.Count();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Pause scheduling.
+// ---------------------------------------------------------------------------
+//
+void CAlfCommandScheduler::Pause()
+ {
+ if ( !(iFlags&EAlfSchedulerRunning) )
+ {
+ return; // Already paused
+ }
+
+ iFlags &= ~EAlfSchedulerRunning;
+ for(TInt i = iEvents.Count() - 1; i >= 0; --i)
+ {
+ iEvents[i]->Pause();
+ }
+
+ }