--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contextframework/cfw/src/cfserver/CFMessageHandlerScript.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,711 @@
+/*
+* Copyright (c) 2006-2006 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: Message handler context class implementation.
+*
+*/
+
+
+#include <s32mem.h>
+
+#include "CFMessageHandlerScript.h"
+#include "cfcommon.h"
+#include "CFScriptInterface.h"
+#include "CFActionSubscriptionImpl.h"
+#include "CFActionIndicationImpl.h"
+#include "CFServSession.h"
+#include "cftrace.h"
+
+CCFMessageHandlerScript* CCFMessageHandlerScript::NewL(
+ MCFExtendedContextInterface& aCFContext,
+ MCFActionInterface& aCFAction,
+ MCFScriptInterface& aScriptInterface )
+ {
+ FUNC_LOG;
+
+ CCFMessageHandlerScript* self = CCFMessageHandlerScript::NewLC(
+ aCFContext,
+ aCFAction,
+ aScriptInterface );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+CCFMessageHandlerScript* CCFMessageHandlerScript::NewLC(
+ MCFExtendedContextInterface& aCFContext,
+ MCFActionInterface& aCFAction,
+ MCFScriptInterface& aScriptInterface )
+ {
+ FUNC_LOG;
+
+ CCFMessageHandlerScript* self = new( ELeave ) CCFMessageHandlerScript(
+ aCFContext,
+ aCFAction,
+ aScriptInterface );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+CCFMessageHandlerScript::~CCFMessageHandlerScript()
+ {
+ FUNC_LOG;
+
+ iCFScriptInterface.DeregisterScriptOwner( *this );
+ if( !iMessage.IsNull() )
+ {
+ // Complete message
+ iMessage.Complete( KErrCancel );
+ }
+ iScriptIds.Close();
+ }
+
+CCFMessageHandlerScript::CCFMessageHandlerScript(
+ MCFExtendedContextInterface& aCFContext,
+ MCFActionInterface& aCFAction,
+ MCFScriptInterface& aCFScriptInterface ):
+ CCFMessageHandlerBase( aCFContext, aCFAction, aCFScriptInterface )
+ {
+ FUNC_LOG;
+ }
+
+void CCFMessageHandlerScript::ConstructL()
+ {
+ FUNC_LOG;
+ }
+
+// METHODS
+
+//-----------------------------------------------------------------------------
+// CCFMessageHandlerScript::HandleMessageL
+//-----------------------------------------------------------------------------
+//
+TBool CCFMessageHandlerScript::HandleMessageL( const RMessage2& aMessage )
+ {
+ FUNC_LOG;
+
+ TBool handled = ETrue;
+ switch( aMessage.Function() )
+ {
+ // Slot[0] = RFs handle
+ // Slot[1] = RFile handle
+ case ERegisterScriptByName:
+ {
+ RFile scriptFile;
+ User::LeaveIfError( scriptFile.AdoptFromClient( aMessage, 0, 1 ) );
+ CleanupClosePushL( scriptFile );
+
+ HBufC8* script = LoadScriptFromFile( scriptFile );
+ TPtrC8 scriptPtrC( *script );
+ CleanupStack::PushL( script );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ HBufC* name = HBufC::NewLC( KMaxFileName );
+ TPtr namePtr( name->Des() );
+ User::LeaveIfError( scriptFile.Name( namePtr ) );
+
+ // Register script
+ TInt scriptId = 0;
+ TInt err = RegisterScript( client, namePtr, scriptPtrC, scriptId );
+
+ // Clean up
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( script );
+ CleanupStack::PopAndDestroy( &scriptFile );
+
+ if( err == KErrNone )
+ {
+ err = scriptId;
+ }
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDesC8 - Script
+ // Slot[1] = TDesC - Script name
+ case ERegisterScriptByNameAndDesc:
+ {
+ HBufC8* script = HBufC8::NewLC( aMessage.GetDesLengthL( 0 ) );
+ TPtr8 scriptPtr( script->Des() );
+ aMessage.ReadL( 0, scriptPtr );
+
+ HBufC* name = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) );
+ TPtr namePtr( name->Des() );
+ aMessage.ReadL( 1, namePtr );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Register script
+ TInt scriptId = 0;
+ TInt err = RegisterScript( client, namePtr, scriptPtr, scriptId );
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( script );
+
+ if( err == KErrNone )
+ {
+ err = scriptId;
+ }
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TInt - Script ID
+ case EDeregisterScriptById:
+ {
+ TInt scriptId = aMessage.Int0();
+
+ // Get handle to client process thread
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Deregister script
+ TInt err = iCFScriptInterface.DeregisterScript( scriptId, client );
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &client );
+
+ // Complete message and return
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = RFs handle
+ // Slot[1] = RFile handle
+ case ESaveScriptByName:
+ {
+ RFile scriptFile;
+ User::LeaveIfError( scriptFile.AdoptFromClient( aMessage, 0, 1 ) );
+ CleanupClosePushL( scriptFile );
+
+ HBufC8* script = LoadScriptFromFile( scriptFile );
+ TPtrC8 scriptPtrC( *script );
+ CleanupStack::PushL( script );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ HBufC* name = HBufC::NewLC( KMaxFileName );
+ TPtr namePtr( name->Des() );
+ User::LeaveIfError( scriptFile.Name( namePtr ) );
+
+ // Register script
+ TInt scriptId = 0;
+ TInt err = RegisterScript( client, namePtr, scriptPtrC, scriptId );
+ if( err == KErrNone )
+ {
+ // Script registered - save script
+ err = iCFScriptInterface.SaveScript(
+ scriptPtrC, scriptId, client );
+ if( err != KErrNone )
+ {
+ // Script save failed - deregister script
+ iCFScriptInterface.DeregisterScript( scriptId, client );
+ }
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( script );
+ CleanupStack::PopAndDestroy( &scriptFile );
+
+ if( err == KErrNone )
+ {
+ err = scriptId;
+ }
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDesC8 - Script
+ // Slot[1] = TDesC - Script name
+ case ESaveScriptByNameAndDesc:
+ {
+ HBufC8* script = HBufC8::NewLC( aMessage.GetDesLengthL( 0 ) );
+ TPtr8 scriptPtr( script->Des() );
+ aMessage.ReadL( 0, scriptPtr );
+
+ HBufC* name = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) );
+ TPtr namePtr( name->Des() );
+ aMessage.ReadL( 1, namePtr );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Register script
+ TInt scriptId = 0;
+ TInt err = RegisterScript( client, namePtr, scriptPtr, scriptId );
+ if( err == KErrNone )
+ {
+ // Register ok - save script
+ err = iCFScriptInterface.SaveScript(
+ scriptPtr, scriptId, client );
+ if( err != KErrNone )
+ {
+ // Script save failed - deregister script
+ iCFScriptInterface.DeregisterScript( scriptId, client );
+ }
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( script );
+
+ if( err == KErrNone )
+ {
+ err = scriptId;
+ }
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDesC - Script name
+ case EDeleteScriptByName:
+ {
+ HBufC* scriptName = HBufC::NewLC( aMessage.GetDesLengthL( 0 ) );
+ TPtr scriptNamePtr( scriptName->Des() );
+ aMessage.ReadL( 0, scriptNamePtr );
+
+ // Get handle to client process thread
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Delete script by name
+ TInt err = iCFScriptInterface.DeleteScript( scriptNamePtr, client );
+ if( err == KErrNone )
+ {
+ // cleanup script persistent data
+ iCFScriptInterface.CleanupPersistentDataByName(
+ scriptNamePtr, client );
+
+ // Delete ok - deregister script
+ err = iCFScriptInterface.DeregisterScript(
+ scriptNamePtr, client );
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( scriptName );
+
+ // Complete message and return
+ aMessage.Complete( err == KErrDeregisterNotNeeded ? KErrNone : err );
+ break;
+ }
+
+ // No params
+ case EDeleteScriptByUid:
+ {
+ // Get handle to client process thread
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Delete scripts from the client
+ TInt err = iCFScriptInterface.DeleteScripts( client );
+ if( err == KErrNone )
+ {
+ // cleanup script persistent data
+ iCFScriptInterface.CleanupPersistentDataByUid( client );
+
+ // Delete ok - deregister scripts
+ err = iCFScriptInterface.DeregisterScripts( client );
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &client );
+
+ // Complete message and return
+ aMessage.Complete( err == KErrDeregisterNotNeeded ? KErrNone : err );
+ break;
+ }
+
+ // Slot[0] = RFs handle
+ // Slot[1] = RFile handle
+ case EUpgradeRomScriptByName:
+ {
+ RFile scriptFile;
+ User::LeaveIfError( scriptFile.AdoptFromClient( aMessage, 0, 1 ) );
+ CleanupClosePushL( scriptFile );
+
+ HBufC8* script = LoadScriptFromFile( scriptFile );
+ TPtrC8 scriptPtrC( *script );
+ CleanupStack::PushL( script );
+
+ HBufC* name = HBufC::NewLC( KMaxFileName );
+ TPtr namePtr( name->Des() );
+ User::LeaveIfError( scriptFile.Name( namePtr ) );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Check if client is allowed to upgrade
+ TInt err = iCFScriptInterface.IsUpgradeAllowed(
+ namePtr, *script, client );
+ if( err == KErrNone )
+ {
+ // Upgrade script
+ err = UpgradeScript( namePtr, scriptPtrC );
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( script );
+ CleanupStack::PopAndDestroy( &scriptFile );
+
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDesC8 - Script
+ // Slot[1] = TDesC - Script name
+ case EUpgradeRomScriptByNameAndDesc:
+ {
+ HBufC8* script = HBufC8::NewLC( aMessage.GetDesLengthL( 0 ) );
+ TPtr8 scriptPtr( script->Des() );
+ aMessage.ReadL( 0, scriptPtr );
+
+ HBufC* name = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) );
+ TPtr namePtr( name->Des() );
+ aMessage.ReadL( 1, namePtr );
+
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Check if client is allowed to upgrade
+ TInt err = iCFScriptInterface.IsUpgradeAllowed(
+ namePtr, *script, client );
+ if( err == KErrNone )
+ {
+ // Upgrade script
+ err = UpgradeScript( namePtr, scriptPtr );
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &client );
+ CleanupStack::PopAndDestroy( name );
+ CleanupStack::PopAndDestroy( script );
+
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDesC - Script name
+ case ERestoreRomScript:
+ {
+ // Read file name
+ HBufC* scriptName = HBufC::NewLC( aMessage.GetDesLengthL( 0 ) );
+ TPtr scriptNamePtr( scriptName->Des() );
+ aMessage.ReadL( 0, scriptNamePtr );
+
+ RThread mainThread;
+ CleanupClosePushL( mainThread );
+
+ // Check if the script exists
+ TInt err = KErrNotFound;
+ TInt scriptId = 0;
+ TBool exists = iCFScriptInterface.AlreadyExists(
+ scriptNamePtr, mainThread, scriptId );
+ if( exists )
+ {
+ // Get handle to the client thread
+ RThread client;
+ aMessage.ClientL( client );
+ CleanupClosePushL( client );
+
+ // Restore script - check that client is allowed to restore
+ err = iCFScriptInterface.RestoreRomScript(
+ scriptId, client );
+ if( err == KErrNone )
+ {
+ // Delete ram script
+ err = iCFScriptInterface.DeleteScript(
+ scriptNamePtr, mainThread );
+ }
+ CleanupStack::PopAndDestroy( &client );
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &mainThread );
+ CleanupStack::PopAndDestroy( scriptName );
+
+ // Complete message
+ aMessage.Complete( err );
+ break;
+ }
+
+ // Slot[0] = TDes
+ // Slot[1] = TInt
+ case EScriptNotificationStart:
+ {
+ // Check if we already have message listening active
+ // Client has messed up
+ if( !iMessage.IsNull() )
+ {
+ // Panic client
+ iMessage.Panic( KPanicCatClient,
+ EAlreadyReceivingScriptNotification );
+ }
+ else
+ {
+ // Store message and check if there are removed scripts notified
+ iMessage = aMessage;
+ NotifyRemovedScriptsL( iMessage );
+ }
+ break;
+ }
+
+ // No args
+ case EScriptNotificationCancel:
+ {
+ if( !iMessage.IsNull() )
+ {
+ // Complete message
+ iMessage.Complete( KErrCancel );
+ }
+ aMessage.Complete( KErrNone );
+ break;
+ }
+
+ // Slot[0] = TDes
+ case EGetScriptNotification:
+ {
+ // Message will be completed during the function call
+ NotifyRemovedScriptsL( aMessage );
+ break;
+ }
+
+ default:
+ {
+ // Message not handled
+ handled = EFalse;
+ break;
+ }
+ }
+
+ return handled;
+ }
+
+//------------------------------------------------------------------------------
+// CCFMessageHandlerScript::HandleScriptsRemoved
+//------------------------------------------------------------------------------
+//
+void CCFMessageHandlerScript::HandleScriptsRemoved(
+ const RArray<TInt>& aScriptIds )
+ {
+ FUNC_LOG;
+
+ // Add ids in to list
+ for( TInt i = 0; i < aScriptIds.Count(); i++ )
+ {
+ // Ignore errors since this can occur only due to OOM
+ iScriptIds.Append( aScriptIds[i] );
+ }
+
+ // Check if there is a message pending
+ TRAP_IGNORE( NotifyRemovedScriptsL( iMessage ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CCFMessageHandlerScript::LoadScriptFromFile
+// -----------------------------------------------------------------------------
+//
+HBufC8* CCFMessageHandlerScript::LoadScriptFromFile( RFile& aFile )
+ {
+ FUNC_LOG;
+
+ HBufC8* script = NULL;
+ TInt size = 0;
+ TInt err = aFile.Size( size );
+ if( err == KErrNone )
+ {
+ script = HBufC8::New( size );
+ if( script )
+ {
+ TPtr8 scriptPtr = script->Des();
+ err = aFile.Read( scriptPtr );
+ if( err == KErrNone )
+ {
+ // Strip all unnecassary data from script
+ TInt pos = scriptPtr.FindF( KScriptStartTag );
+ if( pos != KErrNotFound )
+ {
+ scriptPtr.Copy( scriptPtr.MidTPtr( pos ) );
+ }
+ else
+ {
+ // Incorrect script
+ delete script;
+ script = NULL;
+ }
+ }
+ else
+ {
+ delete script;
+ script = NULL;
+ }
+ }
+ }
+
+ ERROR( err, "Failed loading script" );
+
+ return script;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFMessageHandlerScript::RegisterScript
+// -----------------------------------------------------------------------------
+//
+TInt CCFMessageHandlerScript::RegisterScript( const RThread& aClient,
+ const TDesC& aName,
+ const TDesC8& aScript,
+ TInt& aScriptId )
+ {
+ FUNC_LOG;
+
+ TInt err = KErrNone;
+
+ // Check if the client already has a script with the same name
+ TBool exists = iCFScriptInterface.AlreadyExists(
+ aName, aClient, aScriptId );
+ if( exists )
+ {
+ // Update the script
+ err = iCFScriptInterface.UpdateScript(
+ aScriptId, aClient, aScript, *this );
+ }
+ else
+ {
+ // Register a new script
+ err = iCFScriptInterface.RegisterScript(
+ aName, aScript, aScriptId, aClient, *this );
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCFMessageHandlerScript::UpgradeScript
+// -----------------------------------------------------------------------------
+//
+TInt CCFMessageHandlerScript::UpgradeScript( const TDesC& aName,
+ const TDesC8& aScript )
+ {
+ FUNC_LOG;
+
+ RThread mainThread;
+ TInt err = KErrNotFound;
+ TInt scriptId = 0;
+ TBool found = iCFScriptInterface.AlreadyExists(
+ aName, mainThread, scriptId );
+ if( found )
+ {
+ // Update script
+ err = iCFScriptInterface.UpdateScript( scriptId, mainThread, aScript, *this );
+ if( err == KErrNone )
+ {
+ // Script updated - save script
+ err = iCFScriptInterface.SaveScript(
+ aScript, scriptId, mainThread );
+ }
+ }
+
+ // Clean up
+ mainThread.Close();
+
+ return err;
+ }
+
+//------------------------------------------------------------------------------
+// CCFMessageHandlerScript::NotifyRemovedScriptsL
+//------------------------------------------------------------------------------
+//
+void CCFMessageHandlerScript::NotifyRemovedScriptsL(
+ const RMessage2& aMessage )
+ {
+ FUNC_LOG;
+
+ // Double check that the message is not already completed and there are
+ // script ids which have not yet been notified
+ if( !aMessage.IsNull() && iScriptIds.Count() )
+ {
+ TInt err = KErrNone;
+
+ // Check if the client side buffer is large enough
+ TInt size = 0;
+
+ // Count
+ size += sizeof( TInt );
+ // Ids
+ for( TInt i = 0; i < iScriptIds.Count(); i++ )
+ {
+ size += sizeof( TInt );
+ }
+ // Client buffer length
+ TInt clientBufLen = aMessage.GetDesMaxLengthL( 0 );
+ if( clientBufLen >= size )
+ {
+ // Buffer large enough
+ HBufC8* buf = HBufC8::NewLC( size );
+ TPtr8 bufPtr( buf->Des() );
+ RDesWriteStream write( bufPtr );
+ write.PushL();
+
+ // Write content in to the stream and then to client side buffer
+ write.WriteInt16L( iScriptIds.Count() );
+ for( TInt i = 0; i < iScriptIds.Count(); i++ )
+ {
+ write.WriteInt16L( iScriptIds[i] );
+ }
+ write.CommitL();
+ aMessage.WriteL( 0, bufPtr );
+
+ // Clean up
+ CleanupStack::PopAndDestroy( &write );
+ CleanupStack::PopAndDestroy( buf );
+
+ // Reset script ids
+ iScriptIds.Reset();
+ }
+ else
+ {
+ // Buffer too small
+ err = KErrTooBig;
+ TPckg<TInt> bufferSize( size );
+ aMessage.WriteL( 1, bufferSize );
+ }
+
+ // Complete message
+ aMessage.Complete( err );
+ }
+ }
+
+// End of file