diff -r 12f60d9a73b3 -r cbffe13eac63 csxhelp/src/AppLauncherForCSXH.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/csxhelp/src/AppLauncherForCSXH.cpp Wed Sep 01 12:30:56 2010 +0100 @@ -0,0 +1,453 @@ +/* +* Copyright (c) 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: AppLauncherForCSXH class definition +* +*/ + + +#include "AppLauncherForCSXH.h" +#include "CSXHAppUi.h" +#include + +#include +#include +#include +#include +#include +#include +#include "csxhconstants.h" +#include + + +const TInt KBackSlashesInPrefix = 3; +#ifndef __SERIES60_30__ + const TUid KUidBrowserApplication = { 0x10008D39 }; +#else + const TUid KUidBrowserApplication = { 0x1020724D }; +#endif + +const TInt KKeyBlockTime = 100000; + +enum TAppLaunchMode + { + ENoAppLaunch = 0, + EVSAMode = 1, + ECmdMode = 2, + EAppLaunchFromInternet = 3, + }; +enum TAppLauchParams + { + EParamsInvalid = 0, + EParamsNoMsg, + EParamsWithMsg, + }; + + +AppLauncherForCSXH* AppLauncherForCSXH::NewL() + { + AppLauncherForCSXH* self = new(ELeave) AppLauncherForCSXH(); + self->ConstructL(); + return self; + } + +AppLauncherForCSXH::AppLauncherForCSXH() + {} + +void AppLauncherForCSXH::ConstructL() + { + iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + } + +AppLauncherForCSXH::~AppLauncherForCSXH() + { + if(iTimer) + delete iTimer; + } + +// -------------------------------------------------------------------------- +// Launches an application based on the Application Launch Link URL +// -------------------------------------------------------------------------- +TBool AppLauncherForCSXH::LaunchAppL(const TDesC& aUrl,const TDesC& aCurrentUrl) + { + switch(GetAppLaunchModeL(aUrl,aCurrentUrl)) + { + case ENoAppLaunch: + return EFalse; + case EAppLaunchFromInternet: + HandleAppLauchFromInternetL(); + return ETrue; + case EVSAMode: + { + if(!LaunchApp(aUrl,ETrue)) + HandleFailedAppLauchL(); + return ETrue; + } + case ECmdMode: + { + if(!LaunchApp(aUrl,EFalse)) + HandleFailedAppLauchL(); + return ETrue; + } + default: + return EFalse; + } + } + +TInt AppLauncherForCSXH::GetAppLaunchModeL(const TDesC& aUrl,const TDesC& aCurrentUrl) + { + TInt Position = aUrl.Find(_L("app://vsa@localhost/")); + if(KErrNotFound != Position && 0 == Position) + { + return CheckAppLaunchFromInternetL(EVSAMode,aCurrentUrl); + } + + Position = aUrl.Find(_L("app://cmd@localhost/")); + if(KErrNotFound != Position && 0 == Position) + { + return CheckAppLaunchFromInternetL(ECmdMode,aCurrentUrl); + } + + return ENoAppLaunch; + } + +TBool AppLauncherForCSXH::LaunchApp(const TDesC& aUrl, TBool aVSAMode) + { + iParam1.Copy(KEmptyString); + iParam2.Copy(KEmptyString); + iParam3.Copy(KEmptyString); + iParam4.Copy(KEmptyString); + + switch(CheckMsgParams(aUrl)) + { + case EParamsInvalid: + return EFalse; + case EParamsNoMsg: + { + ExtractTwoParams(aUrl); + if(aVSAMode) + { + TInt32 AId,VId; + GetUid(iParam1,AId); + GetUid(iParam2,VId); + TRAPD(res,CCSXHAppUi::GetInstance()->AppLaunchL(AId,VId)); + return (res == KErrNone) ? ETrue : EFalse; + } + else + { + return LaunchCmdApp(EFalse); + } + } + case EParamsWithMsg: + { + ExtractFourParams(aUrl); + if(aVSAMode) + { + TInt32 AId,VId,MId; + GetUid(iParam1,AId); + GetUid(iParam2,VId); + GetUid(iParam3,MId); + TRAPD(res,CCSXHAppUi::GetInstance()->AppLaunchL(AId,VId,MId,iParam4)); + return (res == KErrNone) ? ETrue : EFalse; + } + else + { + return LaunchCmdApp(ETrue); + } + } + default: + return EFalse; + } + } +TBool AppLauncherForCSXH::LaunchCmdApp(TBool aParamsMode) + { + TRAPD(res,LaunchCmdAppL(aParamsMode)); + if(res != KErrNone) + return EFalse; + return ETrue; + } +TBool AppLauncherForCSXH::LaunchCmdAppL(TBool aParamsMode) + { + /*valid cases + app://cmd@localhost/APP_NAME/APP_UID + app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters + */ + TApaTask task = GetCmdAppTask(); + if (task.Exists()) + {//App is already running + if(aParamsMode) + SendMsgToCmdAppTaskL(task); + + task.BringToForeground(); + return ETrue; + } + //Application has to be started + CApaCommandLine* cmdLine=CApaCommandLine::NewLC(); + cmdLine->SetExecutableNameL(iParam1); + cmdLine->SetCommandL(EApaCommandRun); + + RApaLsSession lsSession; + User::LeaveIfError(lsSession.Connect()); + CleanupClosePushL(lsSession); + User::LeaveIfError(lsSession.StartApp(*cmdLine)); + CleanupStack::PopAndDestroy(&lsSession); + CleanupStack::PopAndDestroy(cmdLine); + if(aParamsMode) + { + iCount = 0; + TCallBack timer_Callback_to_terminateApp( Timer_Callback_to_TerminateApp,this ); + StartTimer(timer_Callback_to_terminateApp); + } + + return ETrue; + } + +TInt AppLauncherForCSXH::Timer_Callback_to_TerminateApp(TAny* aPtr) + { + return static_cast( aPtr )->SendMsgToApplication(); + } + +TInt AppLauncherForCSXH::SendMsgToApplication() + { + //If parameters has to be passed then the following is required + TApaTask cmdTask = GetCmdAppTask(); + if (cmdTask.Exists()) + { + TRAPD(res,SendMsgToCmdAppTaskL(cmdTask)); + if(res != KErrNone) + return 0; + cmdTask.BringToForeground(); + iTimer->Cancel(); + } + else if(++iCount > 20) + { + iTimer->Cancel(); + } + return 0; + } + +TApaTask AppLauncherForCSXH::GetCmdAppTask() + { + TInt32 AId; + GetUid(iParam2,AId); + TApaTaskList taskList(CCSXHAppUi::GetInstance()->GetWsSession()); + TUid KtestAppUid( TUid::Uid( AId ) ); + return taskList.FindApp(KtestAppUid); + } +void AppLauncherForCSXH::SendMsgToCmdAppTaskL(TApaTask& aTask) + { + + TInt32 MId; + GetUid(iParam3,MId); + TUid KtestMsgUid( TUid::Uid( MId ) ); + HBufC8* params = CnvUtfConverter::ConvertFromUnicodeToUtf8L(iParam4); + CleanupStack::PushL(params); + aTask.SendMessage (KtestMsgUid, *params); + CleanupStack::PopAndDestroy(params); + } + +void AppLauncherForCSXH::HandleFailedAppLauchL() + { + HBufC* ErrorMessage = CCSXHAppUi::GetCoeEnv()->AllocReadResourceLC( + R_QTN_HELP_NOTE_UNABLE_TO_LAUNCH_APP); + CAknGlobalNote* note = CAknGlobalNote::NewLC(); + note->ShowNoteL(EAknGlobalInformationNote, *ErrorMessage); + CleanupStack::PopAndDestroy(note); + CleanupStack::PopAndDestroy(ErrorMessage); + } +void AppLauncherForCSXH::HandleAppLauchFromInternetL() + { + HBufC* ErrorMessage = CCSXHAppUi::GetCoeEnv()->AllocReadResourceLC( + R_QTN_HELP_NOTE_APP_LAUNCH_NOT_ALLOWED); + CAknGlobalNote* note = CAknGlobalNote::NewLC(); + note->ShowNoteL(EAknGlobalInformationNote, *ErrorMessage); + CleanupStack::PopAndDestroy(note); + CleanupStack::PopAndDestroy(ErrorMessage); + } + +TInt AppLauncherForCSXH::CheckAppLaunchFromInternetL(TInt aCurrentMode,const TDesC& /*aCurrentUrl*/ ) + { + + return aCurrentMode; + //BrowserNG is lauched for Externalhyperlinks, + //All the security issues are addresed by BrowserNG, + + /*(0 == aCurrentUrl.Find(KFileUrlPrefix) ) ? + aCurrentMode : EAppLaunchFromInternet;*/ + } + +TInt AppLauncherForCSXH::CheckMsgParams(const TDesC& aUrl) + { + /* + The following are valid cases + app://vsa@localhost/APP_UID/VIEW_UID + app://vsa@localhost/APP_UID/VIEW_UID/MSG_UID/Parameters + app://cmd@localhost/APP_NAME/APP_UID + app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters + + That is, it should have exactly 4 backslashes or + >= 6 backslashes (considering the possibility that parameters + can have embedded backslashes) + */ + TBuf backSlash(KBackSlash); + TInt count = 0; + + for(TInt i = 0 ; i < aUrl.Length() ; ++i) + { + if(KErrNotFound != backSlash.Find(&aUrl[i],KBackSlashLength)) + ++count; + } + + if(count == 4) + return EParamsNoMsg; + else if (count >=6) + return EParamsWithMsg; + else + return EParamsInvalid; + } + +void AppLauncherForCSXH::ExtractTwoParams(const TDesC& aUrl) + { + /*Will be called for the following cases + app://vsa@localhost/APP_UID/VIEW_UID + app://cmd@localhost/APP_NAME/APP_UID + */ + iParam1.Copy(KEmptyString); + iParam2.Copy(KEmptyString); + + TBuf backSlash(KBackSlash); + TInt count = 0; + TInt pos; + + for(pos = 0; pos < aUrl.Length() ; ++pos) + { + if(KErrNotFound != backSlash.Find(&aUrl[pos],KBackSlashLength)) + ++count; + if(count == KBackSlashesInPrefix) + break; + } + TPtrC16 url = aUrl.Mid(pos + 1); + pos = url.Find(KBackSlash); + iParam1 = url.Left(pos); + iParam2 = url.Mid(pos + 1); + } + +void AppLauncherForCSXH::ExtractFourParams(const TDesC& aUrl) + { + /*Will be called for the following cases + app://vsa@localhost/APP_UID/VIEW_UID/MSG_UID/Parameters + app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters + */ + iParam1.Copy(KEmptyString); + iParam2.Copy(KEmptyString); + iParam3.Copy(KEmptyString); + iParam4.Copy(KEmptyString); + + TBuf backSlash(KBackSlash); + TInt count = 0; + TInt pos; + + for(pos = 0; pos < aUrl.Length() ; ++pos) + { + if(KErrNotFound != backSlash.Find(&aUrl[pos],KBackSlashLength)) + ++count; + if(count == KBackSlashesInPrefix) + break; + } + + TPtrC16 url = aUrl.Mid(pos + 1); + pos = url.Find(KBackSlash); + iParam1 = url.Left(pos); + + TPtrC16 url2 = url.Mid(pos + 1); + pos = url2.Find(KBackSlash); + iParam2 = url2.Left(pos); + + TPtrC16 url3 = url2.Mid(pos + 1); + pos = url3.Find(KBackSlash); + iParam3 = url3.Left(pos); + + iParam4 = url3.Mid(pos+1); + } + +void AppLauncherForCSXH::GetUid(TPtrC aUid, TInt32& aResult) + { + TInt hexPos = aUid.Find(_L("x")); + if(KErrNotFound == hexPos) + TLex(aUid).Val(aResult); + else + { + TPtrC16 uidt = aUid.Mid(hexPos+1); + TInt64 res; + //During this operation sometimes values exceed TInt32, but the end result is always + //fits into TInt32 + TLex(uidt).Val(res,EHex); + aResult = res; + } + } + +void AppLauncherForCSXH::LaunchBrowserNGL(const TDesC& aUrl) + { + _LIT( KBrowserCmdFetchUrl, "4 " ); + HBufC* param = HBufC::NewLC( KBrowserCmdFetchUrl().Length() + + aUrl.Length() ); + TPtr paramPtr = param->Des(); + paramPtr.Copy( KBrowserCmdFetchUrl ); + paramPtr.Append( aUrl ); + + if(!SendMsgToBrowserNGL(param)) + { + RApaLsSession appArcSession; + User::LeaveIfError( appArcSession.Connect() ); + CleanupClosePushL( appArcSession ); + + TThreadId id; + User::LeaveIfError + ( + appArcSession.StartDocument(*param,KUidBrowserApplication,id ) + ); + CleanupStack::PopAndDestroy( &appArcSession ); + } + + CleanupStack::PopAndDestroy( param ); + } + +TBool AppLauncherForCSXH::SendMsgToBrowserNGL(const HBufC* aUrl) + { + TApaTaskList taskList(CCSXHAppUi::GetInstance()->GetWsSession()); + TApaTask task = taskList.FindApp(KUidBrowserApplication); + if(task.Exists()) + { + // 8-bit buffer is required. + HBufC8* param8 = HBufC8::NewLC( aUrl->Length() ); + param8->Des().Copy( *aUrl ); + task.SendMessage( TUid::Uid( 0 ), *param8 ); // Uid is not used + CleanupStack::PopAndDestroy( param8 ); + return ETrue; + } + else + return EFalse; + } + +void AppLauncherForCSXH::StartTimer(TCallBack aCallBack) + { + if( iTimer->IsActive() ) + { + iTimer->Cancel(); + } + + iTimer->Start( + TTimeIntervalMicroSeconds32( KKeyBlockTime ), + TTimeIntervalMicroSeconds32( KKeyBlockTime ), + aCallBack ); + }