csxhelp/src/AppLauncherForCSXH.cpp
branchRCL_3
changeset 18 cbffe13eac63
parent 0 1f04cf54edd8
--- /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 <cshelp.rsg>
+
+#include <e32std.h>
+#include <apgtask.h>
+#include <apgcli.h> 
+#include <utf.h>
+#include <aknnotewrappers.h> 
+#include <AknGlobalNote.h>
+#include "csxhconstants.h"
+#include <e32std.h> 
+
+
+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<AppLauncherForCSXH*>( 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<KBackSlashLength> 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<KBackSlashLength> 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<KBackSlashLength> 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<RApaLsSession>( 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 );
+    }