srsf/vcommandhandler/src/vcommandrunnable.cpp
branchRCL_3
changeset 19 e36f3802f733
equal deleted inserted replaced
18:cad71a31b7fc 19:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of the CVCommandRunnable class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <vcommandapi.h>
       
    21 #include "rubydebug.h"
       
    22 
       
    23 #include <apaid.h>
       
    24 #include <apgcli.h>
       
    25 #include <apacmdln.h>
       
    26 #include <apgtask.h>
       
    27 #include <eikappui.h>
       
    28 
       
    29 /**
       
    30 * The version of the streamed data protocol
       
    31 * It is rather likely, that the format of the data streamed changes in the future.
       
    32 * Using the protocol version, the code can check if it knows how to parse the 
       
    33 * input stream
       
    34 */
       
    35 const TInt32 KVCRunnableProtocolVersion = 2;
       
    36 
       
    37 /**
       
    38 * @leave KErrOverflow if aArguments is longer, than KMaxVCArgumentLength
       
    39 * @leave KErrArgument if aAppUid is KNullUidValue
       
    40 */
       
    41 EXPORT_C CVCRunnable* CVCRunnable::NewL( TUid aAppUid, const TDesC8& aArguments )
       
    42     {
       
    43     CVCRunnable* self = new ( ELeave ) CVCRunnable;
       
    44     CleanupStack::PushL( self );
       
    45     self->ConstructL( aAppUid, aArguments );
       
    46     CleanupStack::Pop( self );
       
    47     return self;
       
    48     }
       
    49     
       
    50 /**
       
    51 * Factory function
       
    52 * @param aExeName Exe-file to start. Can be full or partical name according to 
       
    53 *        the RProcess::Create rules. Cannot be KNullDesC
       
    54 * @param aArguments Command line to pass to the application. This object makes
       
    55 *        a copy of the passed string
       
    56 * @leave KErrOverflow if aArguments is longer, than KMaxVCArgumentLength or 
       
    57 *		 aExeName is longer, than KMaxOsName
       
    58 * @leave KErrUndeflow if aExeName is empty
       
    59 */
       
    60 EXPORT_C CVCRunnable* CVCRunnable::NewL( const TDesC& aExeName, const TDesC8& aArguments )
       
    61 	{
       
    62 	CVCRunnable* self = new( ELeave ) CVCRunnable;
       
    63 	CleanupStack::PushL( self );
       
    64 	self->ConstructL( aExeName, aArguments);
       
    65 	CleanupStack::Pop( self );
       
    66 	return self;
       
    67 	}
       
    68     
       
    69 /**
       
    70 * Copy the existing CVRunnable
       
    71 */
       
    72 EXPORT_C CVCRunnable* CVCRunnable::NewL( const CVCRunnable& aOriginal )
       
    73 	{
       
    74 	CVCRunnable* self = new (ELeave) CVCRunnable;
       
    75 	CleanupStack::PushL( self );
       
    76 	if( aOriginal.Uid() == KNullUid ) 
       
    77 		{
       
    78 		self->ConstructL( aOriginal.ExeName(), aOriginal.Arguments() );
       
    79 		}
       
    80 	else 
       
    81 		{
       
    82 		self->ConstructL( aOriginal.Uid(), aOriginal.Arguments() );
       
    83 		}
       
    84 	CleanupStack::Pop( self );
       
    85 	return self;
       
    86 	}
       
    87 
       
    88 /** 
       
    89 * Internalizes from stream 
       
    90 * values are read in the same order as ExternalizeL wrote them
       
    91 */
       
    92 EXPORT_C CVCRunnable* CVCRunnable::NewL( RReadStream &aStream )
       
    93     {
       
    94     CVCRunnable* self = new (ELeave) CVCRunnable;
       
    95     CleanupStack::PushL( self );
       
    96     self->ConstructL( aStream );
       
    97     CleanupStack::Pop( self );
       
    98     return self;    
       
    99     }
       
   100     
       
   101 void CVCRunnable::ConstructL( RReadStream &aStream )
       
   102 	{
       
   103 	TInt32 ver;
       
   104     aStream >> ver;
       
   105     __ASSERT_ALWAYS( ver == KVCRunnableProtocolVersion, User::Leave( KErrNotSupported  ) );
       
   106     iExeUid = TUid::Uid( aStream.ReadInt32L() );
       
   107     iArguments = HBufC8::NewL( aStream.ReadInt32L() );
       
   108     TPtr8 pArguments = iArguments->Des();
       
   109     aStream >> pArguments;
       
   110     TInt exeNameLength = aStream.ReadInt32L();
       
   111     if( exeNameLength > 0 )
       
   112     	{
       
   113     	iExeName = HBufC::NewL( exeNameLength );
       
   114     	TPtr pExeName = iExeName->Des();
       
   115 	    aStream >> pExeName;
       
   116     	}
       
   117 	}
       
   118     
       
   119 void CVCRunnable::ConstructL( TUid aAppUid, const TDesC8& aArguments )
       
   120     {
       
   121     __ASSERT_ALWAYS( aArguments.Length() <= KMaxVCArgumentLength, User::Leave( KErrOverflow) );
       
   122     __ASSERT_ALWAYS( aAppUid != KNullUid, User::Leave( KErrArgument ) );
       
   123     iExeUid = TUid::Uid( aAppUid.iUid );
       
   124     iArguments = HBufC8::NewL( aArguments.Length() );
       
   125     *iArguments = aArguments;
       
   126     }
       
   127 
       
   128 void CVCRunnable::ConstructL( const TDesC& aExeName, const TDesC8& aArguments )
       
   129     {
       
   130     __ASSERT_ALWAYS( aArguments.Length() <= KMaxVCArgumentLength, User::Leave( KErrOverflow) );
       
   131     __ASSERT_ALWAYS( aExeName.Length() <= KMaxFileName, User::Leave( KErrOverflow ) );
       
   132     __ASSERT_ALWAYS( aExeName.Length() > 0, User::Leave( KErrUnderflow ) );
       
   133     iExeName = HBufC::NewL( aExeName.Length() );
       
   134     *iExeName = aExeName;
       
   135     iArguments = HBufC8::NewL( aArguments.Length() );
       
   136     *iArguments = aArguments;
       
   137     }
       
   138 
       
   139 EXPORT_C CVCRunnable::~CVCRunnable()
       
   140     {
       
   141     delete iExeName;
       
   142     delete iArguments;
       
   143     }
       
   144     
       
   145 /** 
       
   146  * Saves the object to stream.
       
   147  * The current format is as follows:
       
   148  * <protocol version: int32><uid: int32; KNullUidValue if no><argument length: int32>
       
   149  * <argument descriptor streamed by the default descriptor ExternalizeL>
       
   150  * <exe filename length><exe filename descriptor only if filename length is not 0>
       
   151  */
       
   152 EXPORT_C void CVCRunnable::ExternalizeL( RWriteStream &aStream ) const
       
   153     {
       
   154     aStream << KVCRunnableProtocolVersion;
       
   155     aStream << iExeUid.iUid;
       
   156     aStream << static_cast<TInt32>( iArguments->Length() );
       
   157     aStream << *iArguments;
       
   158     if( iExeName )
       
   159     	{
       
   160     	aStream << static_cast<TInt32>( iExeName->Length() );
       
   161     	aStream << *iExeName;
       
   162     	}
       
   163     else 
       
   164     	{
       
   165     	aStream << static_cast<TInt32>( 0 );
       
   166     	}
       
   167     }
       
   168     
       
   169 EXPORT_C TBool CVCRunnable::operator==( const CVCRunnable& aRunnable ) const
       
   170     {
       
   171     return ( 
       
   172             ( Uid() == aRunnable.Uid()) && 
       
   173             ( Arguments() == aRunnable.Arguments() ) &&
       
   174             ( ExeName() == aRunnable.ExeName() )
       
   175            );
       
   176     }
       
   177     
       
   178 
       
   179 /**
       
   180 * @return The uid of the application to be started
       
   181 */
       
   182 EXPORT_C const TUid CVCRunnable::Uid() const
       
   183     {
       
   184     return iExeUid;
       
   185     }
       
   186     
       
   187 /**
       
   188 * @return The filename of the application to be started. KNullDesC if there is none
       
   189 */
       
   190 EXPORT_C const TDesC& CVCRunnable::ExeName() const
       
   191 	{
       
   192 	if( iExeName )
       
   193 		{
       
   194 		return *iExeName;
       
   195 		}
       
   196 	else 
       
   197 		{
       
   198 		return KNullDesC;
       
   199 		}
       
   200 	}
       
   201 
       
   202 /**
       
   203 * The arguments to be passed to the application
       
   204 */
       
   205 EXPORT_C const TDesC8& CVCRunnable::Arguments() const
       
   206     {
       
   207     return *iArguments;
       
   208     }
       
   209     
       
   210 /** 
       
   211 * Run the command. In case of aAppUid specified during the construction
       
   212 * application is started via the RApaLsSession::StartApp, otherwise
       
   213 * via the RProcess::Create
       
   214 * @leave System-wide error code. In particular KErrNotFound if there is
       
   215 *        no such app in the system
       
   216 */
       
   217 EXPORT_C void CVCRunnable::ExecuteL() const
       
   218 	{
       
   219 	RUBY_DEBUG_BLOCK( "CVCRunnable::ExecuteL" );
       
   220 	if( iExeName ) 
       
   221 		{
       
   222 		RProcess process;
       
   223 		CleanupClosePushL( process );
       
   224 		// Convert arguments into system_number_of_bits-bit descriptor 
       
   225 		// (needed for exe, not needed for GUI apps)
       
   226 		HBufC* arguments = HBufC::NewLC( iArguments->Length() );
       
   227 		arguments->Des().Copy( *iArguments );
       
   228 		
       
   229 		User::LeaveIfError( process.Create( *iExeName, *arguments) );
       
   230 		process.Resume();
       
   231 		
       
   232 		CleanupStack::PopAndDestroy( arguments );
       
   233 		CleanupStack::PopAndDestroy( &process );
       
   234 		}
       
   235 	else 
       
   236 		{
       
   237         const TUid KLogsUID3 = { 270486741 };//101F4CD5
       
   238         //In case logs.exe run in background [EDCN-84B68Q]
       
   239         //todo: General support for this kind of case,
       
   240 		//      eg, add "view" keyworkd in defaultvoicecommands.xml...
       
   241         if ( iExeUid == KLogsUID3 )
       
   242             {
       
   243             TApaTaskList taskList( CCoeEnv::Static()->WsSession() );
       
   244             TApaTask task = taskList.FindApp( iExeUid );
       
   245             if( task.Exists() ) //Logs already open. Request it to
       
   246                 {               //activate the correct view
       
   247                 task.SendMessage( iExeUid, *iArguments );
       
   248                 return;
       
   249                 }
       
   250             }
       
   251         
       
   252 		TApaAppInfo appInfo;
       
   253 		RApaLsSession apaLsSession;
       
   254 		CleanupClosePushL( apaLsSession );
       
   255 		User::LeaveIfError( apaLsSession.Connect() );
       
   256 		User::LeaveIfError( apaLsSession.GetAppInfo( appInfo, iExeUid ) );
       
   257 		
       
   258 		CApaCommandLine* apaCommandLine = CApaCommandLine::NewLC();
       
   259 		apaCommandLine->SetExecutableNameL( appInfo.iFullName );
       
   260         apaCommandLine->SetTailEndL( *iArguments );
       
   261         User::LeaveIfError( apaLsSession.StartApp( *apaCommandLine ) );
       
   262 
       
   263 		CleanupStack::PopAndDestroy( apaCommandLine );
       
   264 		CleanupStack::PopAndDestroy( &apaLsSession );
       
   265 		}
       
   266 	}
       
   267 
       
   268 //End of file