--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sapi_applicationmanager/appmanagerservice/src/launcher.cpp Mon Mar 30 12:51:10 2009 +0300
@@ -0,0 +1,407 @@
+/*
+* Copyright (c) 2007-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: This Class provides the functionality to launch the application
+*
+*/
+
+
+
+
+#include <apgcli.h>
+#include <apacmdln.h>
+#include <e32std.h>
+#include <eikappui.h>
+#include <eikenv.h>
+#include <e32base.h>
+#include <f32file.h>
+//#include <documenthandler.h>
+
+#include "launcher.h"
+#include "launcherobserver.h"
+#include "appmanagerservice.h"
+
+_LIT(KBackground ,"Background");
+_LIT(KChained,"Chained");
+_LIT(KScheme,"s60uid://0x");
+const TInt KDocMaxDigitsInHexString = 8; // 32 bits.
+
+const TInt KLen = 2; // "//" for count these
+
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::NewLC
+// Returns the instance of CLauncher class.
+// -----------------------------------------------------------------------------
+CLauncher* CLauncher::NewL( RApaLsSession& aSession )
+ {
+ CLauncher* self = new ( ELeave )CLauncher( aSession );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::LaunchApplication
+// This function Launch the Given Application
+// -----------------------------------------------------------------------------
+
+ TThreadId CLauncher::LaunchApplicationL( const TDesC& aAppId,
+ const TDesC8& aCmdLine,
+ const TOptions& aOptions
+ )
+ {
+
+ TUid appUid;
+ TApaAppInfo appInfo;
+
+ //parse the application string
+ ParseAppIdL( aAppId, appUid );
+
+
+ if(!( (0==aOptions.iMode.CompareF( KChained ) || 0 == aOptions.iMode.CompareF( KStandalone ) ) && (0==aOptions.iPostion.CompareF( KBackground ) || 0 == aOptions.iPostion.CompareF( KForeground ) ) ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+
+ //Setting Executable name
+
+ if( KErrNone == iApaLsSession.GetAppInfo( appInfo, appUid) )
+ {
+ cmdLine->SetExecutableNameL( appInfo.iFullName );
+ }
+ else
+ {
+ //Invalid UID
+ User::Leave( KErrArgument );
+ }
+
+
+ //Setting command Line Argument
+
+ if ( aCmdLine.Length() )
+ {
+ cmdLine->SetTailEndL( aCmdLine );
+ }
+
+
+ //Setting Document Name
+
+ if ( aOptions.iDocument.Length() )
+ {
+ CAppManagerService::ValidateFilePathL(aOptions.iDocument);
+
+ cmdLine->SetDocumentNameL( aOptions.iDocument );
+ }
+
+ //Set the Launchine Mode
+ if( 0 == aOptions.iMode.CompareF( KChained ) )
+ {
+
+ //Chianed mode doesn;t make any sense with background
+ if( 0 != aOptions.iPostion.CompareF( KBackground ) )
+ cmdLine->SetCommandL( EApaCommandRun );
+ else
+ User::Leave( KErrNotSupported );
+
+ SetChainedModeL( cmdLine, appUid );
+
+ }
+
+ else
+ {
+ //Setting the Launching postion means either background or foreground
+ if( 0 == aOptions.iPostion.CompareF( KBackground ) )
+ {
+ cmdLine->SetCommandL( EApaCommandBackground );
+ }
+ else
+ {
+ cmdLine->SetCommandL( EApaCommandRun );
+ }
+
+ }
+
+ // Launch the requested Application
+ TThreadId threadNotUsed;
+ TRequestStatus requestStatusForRendezvous;
+ User::LeaveIfError( iApaLsSession.StartApp( *cmdLine,
+ threadNotUsed,
+ &requestStatusForRendezvous ));
+
+
+
+ User::WaitForRequest( requestStatusForRendezvous );
+ User::LeaveIfError( requestStatusForRendezvous.Int());
+ CleanupStack::PopAndDestroy( cmdLine );
+
+
+ return threadNotUsed;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::LaunchDocumentL
+// This function Launch the Given Document
+// -----------------------------------------------------------------------------
+
+ TThreadId CLauncher::LaunchDocumentL(TDocument& aCriteria,
+ const TDesC8& aMimeType,
+ const TOptions& aOptions ,
+ TDesC& aFileName
+ )
+ {
+
+ TUid appUid;
+ TApaAppInfo appInfo;
+ TDataType dataType( aMimeType );
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+ TFileName temp;
+
+ //Extracting Application Uid
+ if( 0 != aCriteria.iHandle.SubSessionHandle())
+ {
+ iApaLsSession.AppForDocument( aCriteria.iHandle,appUid,dataType);
+ cmdLine->SetCommandL( EApaCommandOpen );
+ cmdLine->SetFileByHandleL( aCriteria.iHandle );
+ }
+ else if (0 != aCriteria.iPath.CompareF(KNullDesC) )
+ {
+ CAppManagerService::ValidateFilePathL(aCriteria.iPath);
+
+ iApaLsSession.AppForDocument( aCriteria.iPath,appUid,dataType);
+ cmdLine->SetCommandL( EApaCommandOpen );
+ cmdLine->SetDocumentNameL(aCriteria.iPath );
+ }
+ else if ( 0 != aMimeType.CompareF( KNullDesC8 ) )
+ {
+ iApaLsSession.AppForDataType(dataType,appUid);
+ cmdLine->SetCommandL( EApaCommandCreate );
+
+ //This is the logic for handling the buffer right now we are not supported as
+ //underlying S60 classes showing memory leak and pecular behaviour with different
+ //buffer
+
+ /*if( 0 != aOptions.iBuffer.CompareF( KNullDesC8 ) )
+ {
+ __UHEAP_MARK;
+ CDocumentHandler *temp = CDocumentHandler::NewLC();
+ TRAPD (err, temp->SaveL(aOptions.iBuffer,dataType,KEntryAttNormal) );
+ temp->GetPath(aFileName);
+ __UHEAP_MARKEND;
+ CleanupStack::PopAndDestroy( );
+ }*/
+
+ //left to the launch application for setting
+ cmdLine->SetDocumentNameL( aFileName );
+
+
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ //extraction application path
+ if( KErrNone == iApaLsSession.GetAppInfo( appInfo, appUid) )
+ {
+ cmdLine->SetExecutableNameL( appInfo.iFullName );
+ }
+ else
+ {
+ User::Leave( KErrNotFound );
+ }
+
+
+
+
+ //Set the Launchine Mode
+ if( 0 == aOptions.iMode.CompareF( KChained ) )
+ {
+ SetChainedModeL( cmdLine ,appUid );
+ }
+ else if ( 0 != aOptions.iMode.CompareF( KStandalone ) ) //The only other mode is "Standalone"
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ // Launch the requested Application
+ TThreadId threadNotUsed;
+ TRequestStatus requestStatusForRendezvous;
+ User::LeaveIfError( iApaLsSession.StartApp( *cmdLine,
+ threadNotUsed,
+ &requestStatusForRendezvous ));
+
+
+
+ User::WaitForRequest( requestStatusForRendezvous );
+ User::LeaveIfError( requestStatusForRendezvous.Int());
+ CleanupStack::PopAndDestroy( cmdLine );
+
+
+
+ return threadNotUsed;
+
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::LaunchDocumentL
+// This function will parse the application ID string and return the UID
+// -----------------------------------------------------------------------------
+
+void CLauncher::ParseAppIdL( const TDesC & aSource ,TUid & aUid )
+{
+
+ // Icoming string : s60uid://0x101f4d90 , output : 0x101f4d90
+
+ if( (aSource.Length() > KScheme.iTypeLength ) &&(0 == aSource.Mid(0,KScheme.iTypeLength).CompareF(KScheme) ) )
+ {
+ TChar a('/');
+ TInt offset = aSource.Locate(a);
+
+ TPtrC uiddata;
+
+ // To chk for pattern ://
+ if((0 != aSource.Mid(offset+1,1).Compare(_L("/"))) && (0 != aSource.Mid(offset-1,1).Compare(_L(":"))) )
+ User::LeaveIfError(KErrArgument);
+
+ TPtrC a1(aSource.Mid(offset+1,1));
+ TPtrC a2(aSource.Mid(offset-1,1));
+
+ TInt sourcelen = aSource.Length();
+ TInt off = offset + KLen;
+ TInt len = sourcelen -(off) ;
+
+ uiddata.Set(aSource.Mid(off,len));
+ TInt32 uidinint ;
+ User::LeaveIfError( ConvertHexStringToInt32(uiddata,uidinint) );
+
+ aUid.iUid = uidinint;
+ }
+ else
+ {
+ TUid empt(TUid::Null());
+ aUid.iUid = empt.iUid;
+ }
+
+}
+
+// -----------------------------------------------------------------------------
+// CLauncher::ConvertHexStringToInt32
+// This function will convert the Hax string into TInt32
+// -----------------------------------------------------------------------------
+
+
+
+TInt CLauncher::ConvertHexStringToInt32(const TDesC& aHexString,TInt32& aInt32 )
+ {
+ aInt32 = 0;
+
+ TInt pos = aHexString.LocateF( 'x' );
+ if ( pos == KErrNotFound )
+ {
+ pos = 0;
+ }
+ else
+ {
+ pos++;
+ }
+
+ if( ( aHexString.Length() - pos ) > KDocMaxDigitsInHexString )
+ {
+ return KErrArgument; // Error: value too big.
+ }
+ TPtrC hexStringPtr( aHexString.Mid( pos ) );
+
+ TInt64 value64;
+ if ( TLex( hexStringPtr ).Val( value64, EHex ) != KErrNone )
+ {
+ return KErrArgument; // Error: conversion failed.
+ }
+ aInt32 = value64;
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::SetChainedModeL
+// This function will set the application to launch in chained mode
+// -----------------------------------------------------------------------------
+
+
+void CLauncher::SetChainedModeL( CApaCommandLine* aCmdLine , const TUid& aAppUid )
+ {
+
+ CEikonEnv* eikEnv = CEikonEnv::Static();
+
+ if( !eikEnv )
+ {
+ //Console Based Application can not launch another application in
+ //chained mode
+ User::Leave( KErrNotSupported );
+ }
+ else
+ {
+ RWindowGroup& wg = eikEnv->RootWin();
+ CEikAppUi* appUi = eikEnv->EikAppUi();
+
+
+ // Window chain the client with the current application
+ const TInt parentWindowGroupID = wg.Identifier();
+ if ( parentWindowGroupID )
+ {
+ aCmdLine->SetParentWindowGroupID( parentWindowGroupID );
+ wg.AllowProcessToCreateChildWindowGroups( aAppUid );
+ }
+
+ if ( appUi )
+ {
+ appUi->DeactivateActiveViewL();
+ }
+ }
+ }
+
+
+
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::CLauncher
+// Constructor
+// -----------------------------------------------------------------------------
+CLauncher::CLauncher( RApaLsSession& aSession ): iApaLsSession( aSession )
+
+ {
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CLauncher::~CLauncher
+// Destructor
+// -----------------------------------------------------------------------------
+CLauncher::~CLauncher( )
+
+ {
+
+ }
+
+
+