diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfserver/CFMessageHandlerScript.cpp --- /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 + +#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& 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 bufferSize( size ); + aMessage.WriteL( 1, bufferSize ); + } + + // Complete message + aMessage.Complete( err ); + } + } + +// End of file