|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // apgstart.cpp |
|
15 // |
|
16 |
|
17 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
18 #if !defined(__APA_INTERNAL_H__) |
|
19 #include "apainternal.h" |
|
20 #endif |
|
21 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS |
|
22 #include "../apserv/APSCLSV.H" |
|
23 #include "APGCLI.H" |
|
24 #include "APACMDLN.H" |
|
25 #include "APGSTD.H" |
|
26 |
|
27 #if defined(USE_IH_RAISE_EVENT) |
|
28 // For performance system test |
|
29 // see /common/testtools/systemmonitor/instrumentationhandler/inc/raiseevent.h |
|
30 // and /common/generic/plattest/Group/SetEnv.bat |
|
31 #include <systemmonitor/raiseevent.h> |
|
32 #include <test/testinstrumentation.h> |
|
33 #endif |
|
34 |
|
35 /** Starts an application defined by the specified command line information. |
|
36 This is an asynchronous method which doesn't wait for the process creation to complete. |
|
37 To be informed of the process creation success, |
|
38 then appropriate overloaded method taking a TRequestStatus parameter should be used. |
|
39 |
|
40 This is only recommended for non document based applications. |
|
41 |
|
42 View based applications are usually started by activating a specific view |
|
43 using CCoeAppUi::ActivateViewL. Alternatively, using StartApp() to start a |
|
44 view based application will activate the application's default view. |
|
45 |
|
46 @param aCommandLine The command line. |
|
47 @return KErrNone, if successful; KErrNotFound, if the application cannot be |
|
48 found; otherwise one of the other system-wide error codes. |
|
49 @see CCoeAppUi::ActivateViewL() |
|
50 */ |
|
51 EXPORT_C TInt RApaLsSession::StartApp(const CApaCommandLine& aCommandLine) |
|
52 { |
|
53 return DoStartApp(aCommandLine, NULL,NULL); |
|
54 } |
|
55 |
|
56 /** Starts an application defined by the specified command line information. |
|
57 This is an asynchronous method which doesn't wait for the process creation to complete. |
|
58 To be informed of the process creation success, |
|
59 then appropriate overloaded method taking a TRequestStatus parameter should be used. |
|
60 |
|
61 This is only recommended for non document based applications. |
|
62 |
|
63 View based applications are usually started by activating a specific view |
|
64 using CCoeAppUi::ActivateViewL. Alternatively, using StartApp() to start a |
|
65 view based application will activate the application's default view. |
|
66 |
|
67 @param aCommandLine The command line. |
|
68 @param aThreadId On return, the id of the main thread started. |
|
69 @return KErrNone, if successful; KErrNotFound, if the application cannot be |
|
70 found; otherwise one of the other system-wide error codes. |
|
71 @see CCoeAppUi::ActivateViewL() |
|
72 */ |
|
73 EXPORT_C TInt RApaLsSession::StartApp(const CApaCommandLine& aCommandLine,TThreadId& aThreadId) |
|
74 { |
|
75 return DoStartApp(aCommandLine, &aThreadId,NULL); |
|
76 } |
|
77 |
|
78 |
|
79 /** Starts an application defined by the specified command line information. |
|
80 |
|
81 This is only recommended for non document based applications. |
|
82 |
|
83 View based applications are usually started by activating a specific view |
|
84 using CCoeAppUi::ActivateViewL. Alternatively, using StartApp() to start a |
|
85 view based application will activate the application's default view. |
|
86 |
|
87 @param aCommandLine The command line. |
|
88 @param aThreadId On return, the id of the main thread started. |
|
89 @param aRequestStatusForRendezvous If not NULL, the asynchronous RProcess::Rendezvous() |
|
90 function is called (being passed this TRequestStatus object) before RProcess::Resume() is called on |
|
91 the new application process. If this function does not return KErrNone, RProcess::Rendezvous() will |
|
92 not be called passing aRequestStatusForRendezvous, so in this case the caller must not wait |
|
93 on aRequestStatusForRendezvous. |
|
94 @return KErrNone, if successful; KErrNotFound, if the application cannot be |
|
95 found; otherwise one of the other system-wide error codes. |
|
96 @see CCoeAppUi::ActivateViewL() |
|
97 */ |
|
98 EXPORT_C TInt RApaLsSession::StartApp(const CApaCommandLine& aCommandLine,TThreadId& aThreadId,TRequestStatus* aRequestStatusForRendezvous ) |
|
99 { |
|
100 return DoStartApp(aCommandLine, &aThreadId,aRequestStatusForRendezvous); |
|
101 } |
|
102 |
|
103 |
|
104 TInt RApaLsSession::DoStartApp(const CApaCommandLine& aCommandLine, TThreadId* aThreadId,TRequestStatus* aRequestStatusForRendezvous) |
|
105 { |
|
106 TRAPD(error, DoStartAppL(aCommandLine, aThreadId, aRequestStatusForRendezvous)); |
|
107 return error; |
|
108 } |
|
109 |
|
110 void RApaLsSession::DoStartAppL(const CApaCommandLine& aCommandLine, TThreadId* aThreadId,TRequestStatus* aRequestStatusForRendezvous) |
|
111 { |
|
112 // This function does not require "this" object to be connected to the Apparc server, |
|
113 // but if not, it works with some limitations (see the following document for a list |
|
114 // of these limitations: |
|
115 // generic/app-framework/Documentation/PREQ967_solution_constraints.doc). |
|
116 |
|
117 #if defined(USE_IH_RAISE_EVENT) |
|
118 const TInt appStartupInstrumentationEventIdBase=aCommandLine.AppStartupInstrumentationEventIdBase(); |
|
119 if (appStartupInstrumentationEventIdBase!=0) |
|
120 { |
|
121 IH_DECLARE( lInstrumentationHandler ); |
|
122 IH_CREATE( lInstrumentationHandler ); |
|
123 IH_RAISE_EVENT( lInstrumentationHandler, appStartupInstrumentationEventIdBase+MTestInstrumentation::TIDOffsetBeginApplicationFirstRedraw ); |
|
124 IH_RAISE_EVENT( lInstrumentationHandler, appStartupInstrumentationEventIdBase+MTestInstrumentation::TIDOffsetBeginApplicationReadyForInput ); |
|
125 IH_DELETE( lInstrumentationHandler ); |
|
126 } |
|
127 #endif |
|
128 |
|
129 // Retrieve the executable name from the CApaCommandLine object passed in. |
|
130 const TPtrC logicalExecutableName(aCommandLine.ExecutableName()); |
|
131 // Rule-based app launching is not allowed unless there is a connected RApaLsSession object. |
|
132 if(Handle() != KNullHandle) |
|
133 { |
|
134 // requesting from rule-based plug-ins if we can run an application |
|
135 // if server fails while requested rule-based plug-ins it returns a negative value - proceed with launching the application in this case |
|
136 const TBool okayToRun = SendReceiveWithReconnect(EAppListServRuleBasedLaunching, TIpcArgs(&logicalExecutableName)); |
|
137 User::LeaveIfError(!okayToRun ? KErrCancel : okayToRun); // May leave with KErrNotFound if exe not found |
|
138 } |
|
139 |
|
140 TFileName nativeExecutableNameOfNonNativeApplication; |
|
141 RProcess process; |
|
142 HBufC8* opaqueData = NULL; |
|
143 CleanupStack::PushL(TCleanupItem(DeletePointerToPointerToTAny, &opaqueData)); |
|
144 |
|
145 // if we're connected to the Apparc server, try to get the opaque-data and native-executable name |
|
146 // (the latter is only if it's a non-native application that we're launching) |
|
147 if (Handle()!=KNullHandle) |
|
148 { |
|
149 const TInt lengthOfOpaqueData=User::LeaveIfError(SendReceiveWithReconnect(EAppListServGetNativeExecutableNameIfNonNative, TIpcArgs(&nativeExecutableNameOfNonNativeApplication, &logicalExecutableName))); |
|
150 User::LeaveIfError(GetNewOpaqueData(opaqueData, lengthOfOpaqueData)); |
|
151 } |
|
152 |
|
153 // try first to create the application process without interacting with the Apparc server at all - |
|
154 // assumes "logicalExecutableName" is itself a native executable |
|
155 TUidType uidType(KNullUid, KNullUid, KNullUid); |
|
156 TInt err = process.CreateWithStackOverride(logicalExecutableName, KNullDesC, uidType, MinApplicationStackSize(), EOwnerProcess); |
|
157 |
|
158 // If we haven't been able to create the process using the native executable name from the command line |
|
159 // object, instead try to create it using the native executable name of the non-native application. |
|
160 // Can only do this if apparc is connected and thus this name has been retrieved above and |
|
161 // nativeExecutableNameOfNonNativeApplication populated. |
|
162 if (err && nativeExecutableNameOfNonNativeApplication.Length() > 0) |
|
163 err = process.CreateWithStackOverride(nativeExecutableNameOfNonNativeApplication, KNullDesC, uidType, MinApplicationStackSize(), EOwnerProcess); |
|
164 |
|
165 // if we managed to create the process via either of the two methods attempted above (with the native |
|
166 // name or the native name of the non-native app), finish setting it up and "resume" it |
|
167 if (!err) |
|
168 { |
|
169 CleanupStack::PushL(TCleanupItem(CleanupOperation, &process)); |
|
170 |
|
171 if(opaqueData) |
|
172 const_cast<CApaCommandLine&>(aCommandLine).SetOpaqueDataL(*opaqueData); |
|
173 |
|
174 aCommandLine.SetProcessEnvironmentL(process); |
|
175 |
|
176 if (aThreadId) |
|
177 GetMainThreadIdL(*aThreadId, process); |
|
178 |
|
179 if (aRequestStatusForRendezvous) |
|
180 process.Rendezvous(*aRequestStatusForRendezvous); |
|
181 |
|
182 // Note - must not leave between here and the end of this method because we only expect |
|
183 // the caller to wait on aRequestStatusForRendezvous if this method does not leave. |
|
184 if(aRequestStatusForRendezvous != NULL && *aRequestStatusForRendezvous != KRequestPending) |
|
185 { |
|
186 User::WaitForRequest(*aRequestStatusForRendezvous); |
|
187 User::Leave(aRequestStatusForRendezvous->Int()); // item on cleanupstack terminates and closes the process |
|
188 } |
|
189 else |
|
190 { |
|
191 process.Resume(); |
|
192 } |
|
193 CleanupStack::Pop(&process); |
|
194 process.Close(); |
|
195 } |
|
196 |
|
197 CleanupStack::PopAndDestroy(&opaqueData); |
|
198 User::LeaveIfError(err); |
|
199 } //lint !e1762 Suppress member function could be made const |
|
200 |
|
201 void RApaLsSession::CleanupOperation(TAny* aAny) |
|
202 { |
|
203 RProcess* activeProcess = reinterpret_cast<RProcess*>(aAny); |
|
204 activeProcess->Terminate(KErrGeneral); |
|
205 activeProcess->Close(); |
|
206 } |
|
207 |
|
208 |
|
209 /** |
|
210 Get the ID of the process's main thread. |
|
211 */ |
|
212 void RApaLsSession::GetMainThreadIdL(TThreadId& aThreadId, const RProcess& aProcess) |
|
213 { // static |
|
214 TFullName fullName(aProcess.Name()); |
|
215 _LIT(KCCMain,"::Main"); |
|
216 fullName.Append(KCCMain); |
|
217 RThread thread; |
|
218 User::LeaveIfError(thread.Open(fullName, EOwnerThread)); |
|
219 aThreadId = thread.Id(); |
|
220 thread.Close(); |
|
221 } |
|
222 |
|
223 void RApaLsSession::DeletePointerToPointerToTAny(TAny* aPointerToPointerToTAny) |
|
224 { // static |
|
225 __ASSERT_ALWAYS(aPointerToPointerToTAny, Panic(EPanicNullPointer)); |
|
226 delete *static_cast<TAny**>(aPointerToPointerToTAny); //lint !e613 Suppress possible use of null pointer |
|
227 } //lint !e818 Suppress pointer parameter could be declared as pointing to const |
|
228 |
|
229 /** |
|
230 Gets the executable's file name and a new buffer containing its opaque data. |
|
231 |
|
232 Sets up slots 0 and 1 in aIpcArgs - assumes that slots 2 and 3 have already been set up; |
|
233 it then invokes aOpcode |
|
234 */ |
|
235 TInt RApaLsSession::GetExecutableNameAndNewOpaqueData(TDes& aNativeExecutableName, TDes& aLogicalExecutableName, HBufC8*& aOpaqueData, TIpcArgs& aIpcArgs, TInt aOpcode) const |
|
236 { |
|
237 aNativeExecutableName.SetLength(0); // if this comes out zero-length from EAppListServExecutableNameForXxx below then use the logicalExecutableName in RProcess::Create (in this case it's a native C++ application) |
|
238 aIpcArgs.Set(0, &aNativeExecutableName); |
|
239 aIpcArgs.Set(1, &aLogicalExecutableName); |
|
240 |
|
241 const TInt lengthOfOpaqueData = SendReceiveWithReconnect(aOpcode, aIpcArgs); |
|
242 if (lengthOfOpaqueData < 0) |
|
243 return lengthOfOpaqueData; // it's an error code |
|
244 |
|
245 return GetNewOpaqueData(aOpaqueData, lengthOfOpaqueData); |
|
246 } |
|
247 |
|
248 /** |
|
249 Allocated a new buffer for aOpaqueData containing data fetched fronm AppArc server. |
|
250 Returns an error code if no opaque data could be allocated or fetched. |
|
251 */ |
|
252 TInt RApaLsSession::GetNewOpaqueData(HBufC8*& aOpaqueData, TInt aLengthOfOpaqueData) const |
|
253 { |
|
254 aOpaqueData = NULL; |
|
255 if(!aLengthOfOpaqueData) |
|
256 return KErrNone; // Nothing to get |
|
257 |
|
258 // Make sure it's not a negative error code |
|
259 ASSERT(aLengthOfOpaqueData > 0); |
|
260 |
|
261 // Allocate a buffer for the opaque data |
|
262 HBufC8* const opaqueData = HBufC8::New(aLengthOfOpaqueData); |
|
263 if (!opaqueData) |
|
264 return KErrNoMemory; |
|
265 |
|
266 // Get the opaque data from the AppArc server |
|
267 TPtr8 opaqueData_asWritable(opaqueData->Des()); |
|
268 const TInt error = SendReceiveWithReconnect(EAppListServGetOpaqueData, TIpcArgs(&opaqueData_asWritable)); |
|
269 if(error) |
|
270 delete opaqueData; |
|
271 else |
|
272 aOpaqueData = opaqueData; |
|
273 |
|
274 return error; |
|
275 } |
|
276 |
|
277 TInt RApaLsSession::StartApplicationPassingFileHandle(const TDesC& aNativeExecutableName, const TDesC& aLogicalExecutableName, const TDesC8* aOpaqueData, const RFile& aFile, TThreadId& aThreadId, TRequestStatus* aRequestStatusForRendezvous) |
|
278 { |
|
279 TFileName documentName; |
|
280 aFile.FullName(documentName); |
|
281 CApaCommandLine* commandLine=NULL; |
|
282 TRAPD(error, commandLine=CApaCommandLine::NewLC(); |
|
283 commandLine->SetCommandL(EApaCommandOpen); |
|
284 commandLine->SetExecutableNameL(aLogicalExecutableName); |
|
285 commandLine->SetFileByHandleL(aFile); |
|
286 commandLine->SetDocumentNameL(documentName); |
|
287 if (aOpaqueData) |
|
288 commandLine->SetOpaqueDataL(*aOpaqueData); |
|
289 |
|
290 DoStartApplicationL(aNativeExecutableName, *commandLine, aThreadId, aRequestStatusForRendezvous); |
|
291 CleanupStack::PopAndDestroy(commandLine)); |
|
292 |
|
293 return error; |
|
294 } |
|
295 |
|
296 TInt RApaLsSession::StartApplicationPassingDocumentName(const TDesC& aNativeExecutableName, const TDesC& aLogicalExecutableName, const TDesC8* aOpaqueData, const TDesC& aDocumentName, TThreadId& aThreadId,TApaCommand aCommand, TRequestStatus* aRequestStatusForRendezvous) |
|
297 { |
|
298 CApaCommandLine* commandLine=NULL; |
|
299 TRAPD(error, commandLine=CApaCommandLine::NewLC(); |
|
300 commandLine->SetCommandL(aCommand); |
|
301 commandLine->SetExecutableNameL(aLogicalExecutableName); |
|
302 commandLine->SetDocumentNameL(aDocumentName); |
|
303 if (aOpaqueData) |
|
304 commandLine->SetOpaqueDataL(*aOpaqueData); |
|
305 |
|
306 DoStartApplicationL(aNativeExecutableName, *commandLine, aThreadId, aRequestStatusForRendezvous); |
|
307 CleanupStack::PopAndDestroy(commandLine)); |
|
308 |
|
309 return error; |
|
310 } |
|
311 |
|
312 /** |
|
313 */ |
|
314 void RApaLsSession::DoStartApplicationL(const TDesC& aNativeExecutableName, const CApaCommandLine& aCommandLine, TThreadId& aThreadId, TRequestStatus* aRequestStatusForRendezvous) |
|
315 { |
|
316 TPtrC actualNativeExecutableName(aNativeExecutableName); |
|
317 if(!actualNativeExecutableName.Length()) |
|
318 actualNativeExecutableName.Set(aCommandLine.ExecutableName()); // it's a native C++ application, rather than a MIDlet, Python script, etc |
|
319 |
|
320 // Aquire permission to start the app from "application start rule" plug-ins |
|
321 if(Handle() != KNullHandle) // Connected to AppArc server? |
|
322 { |
|
323 const TBool okayToRun = SendReceiveWithReconnect(EAppListServRuleBasedLaunching, TIpcArgs(&actualNativeExecutableName)); |
|
324 // If server fails while requested rule-based plug-ins it returns a negative value. |
|
325 // We shall proceed with launching an application in this case. |
|
326 User::LeaveIfError(!okayToRun ? KErrCancel : okayToRun); // May leave with KErrNotFound if exe is not found or KErrNotSupported if embeddable only |
|
327 } |
|
328 |
|
329 // Start the application |
|
330 |
|
331 // Create a new process |
|
332 RProcess process; |
|
333 TUidType uidType(KNullUid, KNullUid, KNullUid); |
|
334 User::LeaveIfError(process.CreateWithStackOverride(actualNativeExecutableName, KNullDesC, uidType, MinApplicationStackSize(), EOwnerProcess)); // RProcess::CreateWithStackOveride - TESTED |
|
335 CleanupClosePushL(process); |
|
336 |
|
337 // Write the command line data to the process environment |
|
338 // This is used inside the new process to resume the execution |
|
339 aCommandLine.SetProcessEnvironmentL(process); |
|
340 |
|
341 // Find the ID of the new process's main thread |
|
342 GetMainThreadIdL(aThreadId, process); |
|
343 |
|
344 // Rendezvous with the new process, if required |
|
345 if (aRequestStatusForRendezvous) |
|
346 process.Rendezvous(*aRequestStatusForRendezvous); |
|
347 |
|
348 process.Resume(); |
|
349 CleanupStack::PopAndDestroy(&process); |
|
350 } //lint !e1762 Suppress member function could be made const |
|
351 |
|
352 |
|
353 |
|
354 /** Finds and launches an application to handle the document contained in the specified |
|
355 file. |
|
356 |
|
357 @param aDocFileName The document name. |
|
358 @param aThreadId On return, the id of the main thread started. |
|
359 @param aLaunchType Not used. Deprecated. |
|
360 @return KErrNone, if successful; EAppListInvalid, if the server's initial population of |
|
361 the list has not completed; KErrNotFound, if a matching entry could not be found; otherwise |
|
362 one of the other system-wide error codes. |
|
363 */ |
|
364 EXPORT_C TInt RApaLsSession::StartDocument(const TDesC& aDocFileName, TThreadId& aThreadId, TLaunchType /*aLaunchType*/) |
|
365 { |
|
366 HBufC8* buffer = NULL; |
|
367 TInt error = GetNewBufferFromFile(buffer, aDocFileName); |
|
368 if (error) |
|
369 return error; |
|
370 |
|
371 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
372 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
373 HBufC8* opaqueData = NULL; |
|
374 TIpcArgs ipcArgs; |
|
375 ipcArgs.Set(2, &aDocFileName); |
|
376 ipcArgs.Set(3, buffer); |
|
377 error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenDocument); |
|
378 if (error) |
|
379 { |
|
380 delete buffer; |
|
381 return error; |
|
382 } |
|
383 |
|
384 error = StartApplicationPassingDocumentName(nativeExecutableName, logicalExecutableName, opaqueData, aDocFileName, aThreadId, EApaCommandOpen, NULL); |
|
385 delete opaqueData; |
|
386 |
|
387 delete buffer; |
|
388 return error; |
|
389 } |
|
390 |
|
391 /** Finds and launches an application to handle the document contained in the specified file |
|
392 |
|
393 @param aFile The file handle. Before this function can be called, |
|
394 the file server session which owns this file handle must first be marked as shareable by |
|
395 calling RFs::ShareProtected(). |
|
396 @param aThreadId On return, the id of the main thread started. |
|
397 @param aRequestStatusForRendezvous If not NULL, the asynchronous RProcess::Rendezvous() |
|
398 function is called (being passed this TRequestStatus object) before RProcess::Resume() is called on |
|
399 the new application process. |
|
400 @return KErrNone, if successful; KErrNotFound, if no suitable application can |
|
401 be found; otherwise one of the other system-wide error codes. |
|
402 */ |
|
403 EXPORT_C TInt RApaLsSession::StartDocument(RFile& aDocFile, TThreadId& aThreadId, TRequestStatus* aRequestStatusForRendezvous/*=NULL*/) |
|
404 { |
|
405 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
406 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
407 HBufC8* opaqueData = NULL; |
|
408 TIpcArgs ipcArgs; |
|
409 TInt error = aDocFile.TransferToServer(ipcArgs, 2, 3); |
|
410 if (!error) |
|
411 error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenDocumentPassedByFileHandle); |
|
412 |
|
413 if (error) |
|
414 return error; |
|
415 |
|
416 error = StartApplicationPassingFileHandle(nativeExecutableName, logicalExecutableName, opaqueData, aDocFile, aThreadId, aRequestStatusForRendezvous); |
|
417 delete opaqueData; |
|
418 return error; |
|
419 } //lint !e1764 Suppress reference parameter could be declared const ref |
|
420 |
|
421 |
|
422 /** Launches an application that can handle the specified data (MIME) type. |
|
423 |
|
424 The application handles the document contained in the specified file. |
|
425 |
|
426 @param aDocFileName The document name. |
|
427 @param aDataType The data (MIME) type. |
|
428 @param aThreadId On return, the id of the main thread started. |
|
429 @param aLaunchType Not used. Deprecated. |
|
430 @return KErrNone, if successful; EAppListInvalid if the server's initial population of |
|
431 the list has not completed; KErrNotFound, if no suitable application can |
|
432 be found; otherwise one of the other system-wide error codes. |
|
433 */ |
|
434 EXPORT_C TInt RApaLsSession::StartDocument(const TDesC& aDocFileName, const TDataType& aDataType, TThreadId& aThreadId, TLaunchType /*aLaunchType*/) |
|
435 { |
|
436 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
437 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
438 HBufC8* opaqueData=NULL; |
|
439 const TPckgC<TDataType> dataType(aDataType); |
|
440 TIpcArgs ipcArgs; |
|
441 ipcArgs.Set(2, &dataType); |
|
442 TInt error=GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenDataType); |
|
443 if (error) |
|
444 return error; |
|
445 |
|
446 error = StartApplicationPassingDocumentName(nativeExecutableName, logicalExecutableName, opaqueData, aDocFileName, aThreadId,EApaCommandOpen,NULL); |
|
447 delete opaqueData; |
|
448 |
|
449 return error; |
|
450 } |
|
451 |
|
452 /** Finds and launches an application to handle the document contained in the specified file |
|
453 |
|
454 @param aDocFile The file handle. |
|
455 @param aDataType The data (MIME) type. |
|
456 @param aThreadId On return, the id of the main thread started. |
|
457 @param aRequestStatusForRendezvous If not NULL, the asynchronous RProcess::Rendezvous() |
|
458 function is called (being passed this TRequestStatus object) before RProcess::Resume() is called on |
|
459 the new application process. |
|
460 @return KErrNone, if successful; KErrNotFound, if no suitable application can |
|
461 be found; otherwise one of the other system-wide error codes. |
|
462 */ |
|
463 EXPORT_C TInt RApaLsSession::StartDocument(RFile& aDocFile, const TDataType& aDataType, TThreadId& aThreadId, TRequestStatus* aRequestStatusForRendezvous/*=NULL*/) |
|
464 { |
|
465 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
466 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
467 HBufC8* opaqueData = NULL; |
|
468 const TPckgC<TDataType> dataType(aDataType); |
|
469 TIpcArgs ipcArgs; |
|
470 ipcArgs.Set(2, &dataType); |
|
471 TInt error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenDataType); |
|
472 if (error) |
|
473 return error; |
|
474 |
|
475 error = StartApplicationPassingFileHandle(nativeExecutableName, logicalExecutableName, opaqueData, aDocFile, aThreadId, aRequestStatusForRendezvous); |
|
476 delete opaqueData; |
|
477 return error; |
|
478 } //lint !e1764 Suppress reference parameter could be declared const ref |
|
479 |
|
480 |
|
481 /** Launches the application identified by the specified UID. |
|
482 |
|
483 The application handles the document contained in the specified file. |
|
484 |
|
485 @param aDocFileName The document name. |
|
486 @param aAppUid The application specific UID. |
|
487 @param aThreadId On return, the id of the main thread started. |
|
488 @param aLaunchType Not used. Deorecated. |
|
489 @return KErrNone, if successful; EAppListInvalid if the server's initial population of |
|
490 the list has not completed; KErrNotFound, if no suitable application can |
|
491 be found; otherwise one of the other system-wide error codes. */ |
|
492 EXPORT_C TInt RApaLsSession::StartDocument(const TDesC& aDocFileName, TUid aAppUid, TThreadId& aThreadId, TLaunchType /*aLaunchType*/) |
|
493 { |
|
494 // Get the executable file name and "opaque" app meta-data from AppArc server |
|
495 |
|
496 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
497 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
498 HBufC8* opaqueData = NULL; |
|
499 |
|
500 TIpcArgs ipcArgs; |
|
501 ipcArgs.Set(2, aAppUid.iUid); |
|
502 |
|
503 TInt error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenAppUid); |
|
504 if (error) |
|
505 return error; |
|
506 |
|
507 // Start the application, passing it the document file name |
|
508 |
|
509 error = StartApplicationPassingDocumentName(nativeExecutableName, logicalExecutableName, opaqueData, aDocFileName, aThreadId, EApaCommandOpen, NULL); |
|
510 delete opaqueData; |
|
511 |
|
512 return error; |
|
513 } |
|
514 |
|
515 /** Finds and launches an application to handle the document contained in the specified file |
|
516 |
|
517 @param aDocFile The file handle. |
|
518 @param aAppUid The application specific UID. |
|
519 @param aThreadId On return, the id of the main thread started. |
|
520 @param aRequestStatusForRendezvous If not NULL, the asynchronous RProcess::Rendezvous() |
|
521 function is called (being passed this TRequestStatus object) before RProcess::Resume() is called on |
|
522 the new application process. |
|
523 @return KErrNone, if successful; KErrNotFound, if no suitable application can |
|
524 be found; otherwise one of the other system-wide error codes. */ |
|
525 EXPORT_C TInt RApaLsSession::StartDocument(RFile& aDocFile, TUid aAppUid, TThreadId& aThreadId, TRequestStatus* aRequestStatusForRendezvous/*=NULL*/) |
|
526 { |
|
527 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
528 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
529 HBufC8* opaqueData=NULL; |
|
530 TIpcArgs ipcArgs; |
|
531 ipcArgs.Set(2, aAppUid.iUid); |
|
532 TInt error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenAppUid); |
|
533 if (error) |
|
534 return error; |
|
535 |
|
536 error = StartApplicationPassingFileHandle(nativeExecutableName, logicalExecutableName, opaqueData, aDocFile, aThreadId, aRequestStatusForRendezvous); |
|
537 delete opaqueData; |
|
538 return error; |
|
539 } //lint !e1764 Suppress reference parameter could be declared const ref |
|
540 |
|
541 |
|
542 /** Launches the application identified by the specified UID and creates a new document. |
|
543 |
|
544 To create a document file with the passed document name, the application needs to override the 3-parameter |
|
545 overload of ProcessCommandParametersL() to call the 2-parameter overload. |
|
546 |
|
547 Otherwise, a document will be created with the default document name present in the application resource file. |
|
548 If default document name is empty or not provided, no document is created. |
|
549 |
|
550 If the application resource file is not present, a document with application caption name is created. |
|
551 |
|
552 @param aDocFileName The document name. |
|
553 @param aAppUid The application specific UID. |
|
554 @param aThreadId On return, the id of the main thread started. |
|
555 @param aLaunchType Not used. Deprecated. |
|
556 @return KErrNone, if successful; EAppListInvalid if the server's initial population of |
|
557 the list has not completed; KErrNotFound, if no suitable application can |
|
558 be found; otherwise one of the other system-wide error codes. |
|
559 @see CEikAppUi::ProcessCommandParametersL(). |
|
560 */ |
|
561 EXPORT_C TInt RApaLsSession::CreateDocument(const TDesC& aDocFileName, TUid aAppUid, TThreadId& aThreadId, TLaunchType /*aLaunchType*/) |
|
562 { |
|
563 TFileName nativeExecutableName; // the name of the EXE that we pass to RProcess::Create |
|
564 TFileName logicalExecutableName; // the name of the MIDlet, Python script, etc |
|
565 HBufC8* opaqueData=NULL; |
|
566 TIpcArgs ipcArgs; |
|
567 ipcArgs.Set(2, aAppUid.iUid); |
|
568 TInt error = GetExecutableNameAndNewOpaqueData(nativeExecutableName, logicalExecutableName, opaqueData, ipcArgs, EAppListServGetExecutableNameGivenAppUid); |
|
569 if (error) |
|
570 return error; |
|
571 |
|
572 error = StartApplicationPassingDocumentName(nativeExecutableName, logicalExecutableName, opaqueData, aDocFileName, aThreadId,EApaCommandCreate,NULL); |
|
573 delete opaqueData; |
|
574 |
|
575 return error; |
|
576 } |
|
577 |
|
578 |
|
579 |