--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contextframework/cfw/src/cfscriptengine/CFScript.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,713 @@
+/*
+* Copyright (c) 2002-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:
+*
+*/
+
+
+
+#include <e32std.h>
+#include <gmxmlelement.h>
+#include <cfcontextsourcecommand.h>
+
+#include "cfextendedcontextinterface.h"
+#include "cfcontextindication.h"
+#include "cfpluginoperation.h"
+#include "CFScript.h"
+#include "CFContextSubscriptionImpl.h"
+#include "cfscriptsubscription.h"
+#include "cfoperationnode.h"
+#include "cfscriptroot.h"
+#include "cfconstants.h"
+#include "cfscriptlistener.h"
+#include "cfactionhandler.h"
+#include "cftrace.h"
+#include "cfpersistentdata.h"
+#include "cfscriptinfo.h"
+
+// MEMBER FUNCTIONS
+
+// -----------------------------------------------------------------------------
+// CCFScript::CCFScript
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CCFScript::CCFScript( MCFExtendedContextInterface& aCF,
+ MCFActionHandler& aActionHandler,
+ MCFSecurityChecker& aSecurityChecker,
+ MCFPlugInOperation& aPlugInOperation,
+ RFs& aFs ):
+ iCF( aCF ),
+ iActionHandler( aActionHandler ),
+ iSecurityChecker( aSecurityChecker ),
+ iPlugInOperation( aPlugInOperation ),
+ iFs( aFs )
+ {
+ FUNC_LOG;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCFScript::ConstructL( CMDXMLNode& aStartNode, const TDesC& aName,
+ TInt aScriptId, const TUid& aOwner, TInt aLength,
+ MCFScriptOwner* aScriptOwner )
+ {
+ FUNC_LOG;
+
+ // local variable declaration & initialization
+ TInt err( KErrNone );
+
+ // Script related information
+ iInfo = CCFScriptInfo::NewL( aName, aScriptId, aOwner, aLength, aScriptOwner );
+ iPersistentData = CCFPersistentData::NewL( iFs, aOwner, iInfo->Name() );
+
+ // parse script to objects
+ err = ParseScriptL( aStartNode );
+ ERROR_1( err, "Parse script error: %d", err );
+
+ // leave if error occurred
+ User::LeaveIfError( err );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCFScript* CCFScript::NewL( CMDXMLNode& aStartNode,
+ const TDesC& aName,
+ TInt aScriptId,
+ const TUid& aOwner,
+ MCFActionHandler& aActionHandler,
+ TInt aLength,
+ MCFExtendedContextInterface& aCF,
+ MCFSecurityChecker& aSecurityChecker,
+ MCFPlugInOperation& aPlugInOperation,
+ RFs& aFs,
+ MCFScriptOwner* aScriptOwner )
+ {
+ FUNC_LOG;
+
+ CCFScript* self = NewLC( aStartNode,
+ aName,
+ aScriptId,
+ aOwner,
+ aActionHandler,
+ aLength,
+ aCF,
+ aSecurityChecker,
+ aPlugInOperation,
+ aFs,
+ aScriptOwner );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCFScript* CCFScript::NewLC( CMDXMLNode& aStartNode,
+ const TDesC& aName,
+ TInt aScriptId,
+ const TUid& aOwner,
+ MCFActionHandler& aActionHandler,
+ TInt aLength,
+ MCFExtendedContextInterface& aCF,
+ MCFSecurityChecker& aSecurityChecker,
+ MCFPlugInOperation& aPlugInOperation,
+ RFs& aFs,
+ MCFScriptOwner* aScriptOwner )
+ {
+ FUNC_LOG;
+
+ CCFScript* self = new( ELeave ) CCFScript( aCF,
+ aActionHandler,
+ aSecurityChecker,
+ aPlugInOperation,
+ aFs );
+ CleanupStack::PushL( self );
+ self->ConstructL( aStartNode, aName, aScriptId, aOwner, aLength, aScriptOwner );
+ return self;
+ }
+
+// Destructor
+CCFScript::~CCFScript()
+ {
+ FUNC_LOG;
+
+ iCF.UnsubscribeContexts( *this );
+ iScriptSubscriptions.ResetAndDestroy();
+ iRequiresAll.Close();
+ delete iScriptRoot;
+ iScriptRoot = NULL;
+ delete iPersistentData;
+ delete iInfo;
+ iDependencyList.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ActivateL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::ActivateL()
+ {
+ FUNC_LOG;
+
+ iScriptRoot->ActivateL();
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::CheckSecurity
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::CheckSecurity( const RThread& aOwnerThread )
+ {
+ FUNC_LOG;
+
+ iScriptThreadForSecurityCheck = &aOwnerThread;
+
+ TInt err = iScriptRoot->CheckSecurity();
+
+ iScriptThreadForSecurityCheck = NULL;
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ActionHandler
+// -----------------------------------------------------------------------------
+//
+MCFActionHandler& CCFScript::ActionHandler() const
+ {
+ FUNC_LOG;
+
+ return iActionHandler;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::UpgradeSecurity
+// -----------------------------------------------------------------------------
+//
+const TCapabilitySet& CCFScript::UpgradeSecurity() const
+ {
+ FUNC_LOG;
+
+ return iScriptRoot->UpgradeSecurity();
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ContextIndicationL
+//
+// -----------------------------------------------------------------------------
+//
+void CCFScript::ContextIndicationL( CCFContextIndication* aIndication )
+ {
+ FUNC_LOG;
+
+ // Initialize local variables.
+ TInt contextLevelDelay( 0 );
+
+ // Guards firing actions so that an operation of the script must have been
+ // evaluated before actions are allowed to be fired.
+ TBool evaluated = EvaluateScript( aIndication->Context(),
+ contextLevelDelay );
+ delete aIndication; // Cleanup the transferred indication.
+ aIndication = NULL;
+
+ if ( evaluated )
+ {
+ TInt err( KErrNone );
+ TRAP( err, iScriptRoot->ContextEvaluatedL( contextLevelDelay ) );
+
+ ERROR( err, "Signalling script evaluation by context to script root leaved." );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::Client
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::Client( RThread& /*aThread*/ ) const
+ {
+ FUNC_LOG;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::HandleContextSubscriptionError
+//
+// -----------------------------------------------------------------------------
+//
+void CCFScript::HandleContextSubscriptionError( TInt /*aError*/,
+ const TDesC& /*aSource*/,
+ const TDesC& /*aType*/ )
+ {
+ FUNC_LOG;
+
+ // Nothing to do.
+ // Generally this can only happen with OOM
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCFScript::SubscribeContextL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::SubscribeContextL( MCFScriptListener* aListener )
+ {
+ FUNC_LOG;
+
+ CCFScriptSubscription* subscription = NULL;
+ for ( TInt i = 0; i < iScriptSubscriptions.Count(); ++i )
+ {
+ subscription = iScriptSubscriptions[ i ];
+ if ( subscription->Match( *aListener ) )
+ {
+ break;
+ }
+ subscription = NULL;
+ }
+
+ if ( subscription )
+ {
+ subscription->AddListenerL( aListener );
+ }
+ else
+ {
+ // below // CLEANUP<< subscription
+ subscription = CCFScriptSubscription::NewLC( iCF, *this, aListener );
+ iScriptSubscriptions.AppendL( subscription );
+ CleanupStack::Pop( subscription ); // CLEANUP>> subscription
+ }
+
+ if ( aListener->IsAllRequired() )
+ {
+ iRequiresAll.AppendL( aListener );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::RemoveSubscription
+// -----------------------------------------------------------------------------
+//
+void CCFScript::RemoveSubscription( MCFScriptListener* aListener )
+ {
+ FUNC_LOG;
+
+ for ( TInt i = 0; i < iScriptSubscriptions.Count(); ++i )
+ {
+ CCFScriptSubscription* subscription = iScriptSubscriptions[ i ];
+ if ( subscription->Match( *aListener ) )
+ {
+ if ( subscription->RemoveListener( aListener ) )
+ {
+ // Last listener removed, clean up.
+ iScriptSubscriptions.Remove( i );
+ delete subscription;
+ }
+ break;
+ }
+ }
+
+ if ( aListener->IsAllRequired() )
+ {
+ TInt index = iRequiresAll.Find( aListener );
+ if ( index != KErrNotFound )
+ {
+ iRequiresAll.Remove( index );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::CheckContextReadSecurity
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::CheckContextReadSecurity( const TDesC& aSource,
+ const TDesC& aType )
+ {
+ FUNC_LOG;
+
+ TSecurityPolicy securityPolicy;
+ TInt err = iCF.GetReadSecurityPolicy( aSource, aType, securityPolicy );
+ if ( err != KErrNone )
+ {
+ return err;
+ }
+
+ TBool securityPassed = iSecurityChecker.CheckClientSecurity(
+ *iScriptThreadForSecurityCheck, securityPolicy );
+ if (!securityPassed)
+ {
+ return KErrPermissionDenied;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::CheckWriteSecurity
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::CheckScriptOwnerAccess( const TSecurityPolicy& aPolicy )
+ {
+ FUNC_LOG;
+
+ TInt ret( KErrNone );
+
+ TBool securityPassed = iSecurityChecker.CheckClientSecurity(
+ *iScriptThreadForSecurityCheck, aPolicy );
+ if ( !securityPassed )
+ {
+ ret = KErrPermissionDenied;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ParseL
+// -----------------------------------------------------------------------------
+//
+CCFOperationNode* CCFScript::ParseL( CCFOperationNode* aParent,
+ CMDXMLNode& aNode )
+ {
+ FUNC_LOG;
+
+ TUid providerUid = KNullUid;
+ CCFOperationNode* opNode = iPlugInOperation.ParseL(
+ aParent, aNode, *this, providerUid );
+ if ( opNode )
+ {
+ // Node found, add dependency
+ AddDependencyL( providerUid );
+ }
+ else
+ {
+ TPtrC nodeName( aNode.NodeName() );
+ ERROR_GEN_1( "Unknown node name: %S" , &nodeName );
+ }
+
+ return opNode;
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::ScriptId
+//------------------------------------------------------------------------------
+//
+TInt CCFScript::ScriptId() const
+ {
+ FUNC_LOG;
+
+ return iInfo->Id();
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::RestoreL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::RestoreL( const TDesC& aFile, CCFOperationNode& aOperation )
+ {
+ FUNC_LOG;
+
+ iPersistentData->RestoreL( aFile, aOperation );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::StoreL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::StoreL( const TDesC& aFile, CCFOperationNode& aOperation )
+ {
+ FUNC_LOG;
+
+ iPersistentData->StoreL( aFile, aOperation );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::StoreL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::Delete( const TDesC& aFile )
+ {
+ FUNC_LOG;
+
+ iPersistentData->Delete( aFile );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCFScript::LaunchActivatedActions
+// -----------------------------------------------------------------------------
+//
+void CCFScript::LaunchActivatedActions()
+ {
+ FUNC_LOG;
+
+ TInt err( KErrNone );
+ TRAP( err, iScriptRoot->EvaluatedL() );
+
+ ERROR( err, "Signalling script evaluation without context to script root leaved." );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ContextInterface
+// -----------------------------------------------------------------------------
+//
+MCFContextInterface& CCFScript::ContextInterface() const
+ {
+ FUNC_LOG;
+
+ return iCF;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::FireActionL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::FireActionL( CCFScriptEvent* aEvent )
+ {
+ FUNC_LOG;
+
+ iActionHandler.FireActionL( aEvent );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::FireActionL
+// -----------------------------------------------------------------------------
+//
+void CCFScript::FireActionL( const CCFContextSourceCommand& aCommand )
+ {
+ FUNC_LOG;
+
+ iActionHandler.FireActionL( aCommand );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::GetSecurityPolicy
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::GetActionSecurityPolicy( const TDesC& aActionId,
+ TSecurityPolicy& aPolicy )
+ {
+ FUNC_LOG;
+
+ return iActionHandler.GetActionSecurityPolicy( aActionId, aPolicy );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::CleanupPersistentData
+// -----------------------------------------------------------------------------
+//
+void CCFScript::CleanupPersistentData()
+ {
+ FUNC_LOG;
+
+ iScriptRoot->Cleanup();
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::HasDependency
+//------------------------------------------------------------------------------
+//
+TBool CCFScript::HasDependency( const TUid& aUid ) const
+ {
+ FUNC_LOG;
+
+ // Check if the dependency is needed to be added
+ TBool found = EFalse;
+ if( aUid != KNullUid )
+ {
+ for( TInt i = 0; i < iDependencyList.Count(); i++ )
+ {
+ if( iDependencyList[i] == aUid )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ }
+ return found;
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::CopyInfoLC
+//------------------------------------------------------------------------------
+//
+CCFScriptInfo* CCFScript::CopyInfoLC() const
+ {
+ FUNC_LOG;
+
+ return CCFScriptInfo::NewLC( iInfo->Name(),
+ iInfo->Id(),
+ iInfo->OwnerUid(),
+ iInfo->Length(),
+ iInfo->OwnerSession() );
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::OwnerUid
+//------------------------------------------------------------------------------
+//
+const TUid& CCFScript::OwnerUid() const
+ {
+ FUNC_LOG;
+
+ return iInfo->OwnerUid();
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::Name
+//------------------------------------------------------------------------------
+//
+TPtrC CCFScript::Name() const
+ {
+ FUNC_LOG;
+
+ return iInfo->Name();
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::Length
+//------------------------------------------------------------------------------
+//
+TInt CCFScript::Length() const
+ {
+ FUNC_LOG;
+
+ return iInfo->Length();
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::Info
+//------------------------------------------------------------------------------
+//
+CCFScriptInfo& CCFScript::Info() const
+ {
+ FUNC_LOG;
+
+ return *iInfo;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::ParseScriptL
+// -----------------------------------------------------------------------------
+//
+TInt CCFScript::ParseScriptL( CMDXMLNode& aStartNode )
+ {
+ FUNC_LOG;
+
+ TUid providerUid = KNullUid;
+ iScriptRoot = iPlugInOperation.ParseScriptRootL(
+ NULL, aStartNode, *this, providerUid );
+ TInt err( KErrNone );
+ if ( iScriptRoot )
+ {
+ // Script root found, add dependency
+ AddDependencyL( providerUid );
+ }
+ else
+ {
+ ERROR_GEN( "CCFScript::ParseScriptL: The script has invalid root element" );
+ err = KErrNotFound;
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFScript::EvaluateScript
+// -----------------------------------------------------------------------------
+//
+TBool CCFScript::EvaluateScript( const CCFContextObject& aContext,
+ TInt& aContextLevelDelay )
+ {
+ FUNC_LOG;
+
+ TBool evaluated( EFalse );
+ TInt delayRequirement( 0 );
+ TInt delay( 0 );
+
+ TPtrC name( iInfo->Name() );
+ INFO_2( "CCFScript::EvaluateScript - Evaluating script NAME=[%S] ID=[%d] with context:",
+ &name, iInfo->Id() );
+ INFO_3( ">> %S: %S: %S", &aContext.Source(), &aContext.Type(), &aContext.Value() );
+
+ // Evaluate first all operations requiring all context indications.
+ for ( TInt index = 0; index < iRequiresAll.Count(); ++index )
+ {
+ if ( iRequiresAll[ index ]->Evaluate( aContext, delay ) )
+ {
+ evaluated = ETrue;
+ if ( delay > delayRequirement )
+ {
+ delayRequirement = delay;
+ }
+ }
+ }
+
+ for ( TInt j = 0; j < iScriptSubscriptions.Count(); ++j )
+ {
+ CCFScriptSubscription* subscription = iScriptSubscriptions[ j ];
+ if ( subscription->Match( aContext ) )
+ {
+ if ( subscription->NotifyListeners( aContext, delay ) )
+ {
+ evaluated = ETrue;
+ }
+
+ if ( delay > delayRequirement )
+ {
+ delayRequirement = delay;
+ }
+ break;
+ }
+ }
+
+ if ( delayRequirement > 0 )
+ {
+ aContextLevelDelay = delayRequirement;
+ }
+
+ INFO_3( "CCFScript::EvaluateScript - Evaluated script ID=[%d]: CtxLevDelay=%dms, (1=evaluated, 0=no evaluation): %d",
+ iInfo->Id(), aContextLevelDelay, evaluated );
+
+ return evaluated;
+ }
+
+//------------------------------------------------------------------------------
+// CCFScript::AddDependencyL
+//------------------------------------------------------------------------------
+//
+void CCFScript::AddDependencyL( const TUid& aUid )
+ {
+ FUNC_LOG;
+
+ // Check if the dependency is needed to be added
+ TBool found = HasDependency( aUid );
+ if( !found )
+ {
+ iDependencyList.AppendL( aUid );
+ }
+ }
+
+// End of file
+