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: AppLauncherForCSXH class definition |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "AppLauncherForCSXH.h" |
|
20 #include "CSXHAppUi.h" |
|
21 #include <cshelp.rsg> |
|
22 |
|
23 #include <e32std.h> |
|
24 #include <apgtask.h> |
|
25 #include <apgcli.h> |
|
26 #include <utf.h> |
|
27 #include <aknnotewrappers.h> |
|
28 #include <AknGlobalNote.h> |
|
29 #include "csxhconstants.h" |
|
30 #include <e32std.h> |
|
31 |
|
32 |
|
33 const TInt KBackSlashesInPrefix = 3; |
|
34 #ifndef __SERIES60_30__ |
|
35 const TUid KUidBrowserApplication = { 0x10008D39 }; |
|
36 #else |
|
37 const TUid KUidBrowserApplication = { 0x1020724D }; |
|
38 #endif |
|
39 |
|
40 const TInt KKeyBlockTime = 100000; |
|
41 |
|
42 enum TAppLaunchMode |
|
43 { |
|
44 ENoAppLaunch = 0, |
|
45 EVSAMode = 1, |
|
46 ECmdMode = 2, |
|
47 EAppLaunchFromInternet = 3, |
|
48 }; |
|
49 enum TAppLauchParams |
|
50 { |
|
51 EParamsInvalid = 0, |
|
52 EParamsNoMsg, |
|
53 EParamsWithMsg, |
|
54 }; |
|
55 |
|
56 |
|
57 AppLauncherForCSXH* AppLauncherForCSXH::NewL() |
|
58 { |
|
59 AppLauncherForCSXH* self = new(ELeave) AppLauncherForCSXH(); |
|
60 self->ConstructL(); |
|
61 return self; |
|
62 } |
|
63 |
|
64 AppLauncherForCSXH::AppLauncherForCSXH() |
|
65 {} |
|
66 |
|
67 void AppLauncherForCSXH::ConstructL() |
|
68 { |
|
69 iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
70 } |
|
71 |
|
72 AppLauncherForCSXH::~AppLauncherForCSXH() |
|
73 { |
|
74 if(iTimer) |
|
75 delete iTimer; |
|
76 } |
|
77 |
|
78 // -------------------------------------------------------------------------- |
|
79 // Launches an application based on the Application Launch Link URL |
|
80 // -------------------------------------------------------------------------- |
|
81 TBool AppLauncherForCSXH::LaunchAppL(const TDesC& aUrl,const TDesC& aCurrentUrl) |
|
82 { |
|
83 switch(GetAppLaunchModeL(aUrl,aCurrentUrl)) |
|
84 { |
|
85 case ENoAppLaunch: |
|
86 return EFalse; |
|
87 case EAppLaunchFromInternet: |
|
88 HandleAppLauchFromInternetL(); |
|
89 return ETrue; |
|
90 case EVSAMode: |
|
91 { |
|
92 if(!LaunchApp(aUrl,ETrue)) |
|
93 HandleFailedAppLauchL(); |
|
94 return ETrue; |
|
95 } |
|
96 case ECmdMode: |
|
97 { |
|
98 if(!LaunchApp(aUrl,EFalse)) |
|
99 HandleFailedAppLauchL(); |
|
100 return ETrue; |
|
101 } |
|
102 default: |
|
103 return EFalse; |
|
104 } |
|
105 } |
|
106 |
|
107 TInt AppLauncherForCSXH::GetAppLaunchModeL(const TDesC& aUrl,const TDesC& aCurrentUrl) |
|
108 { |
|
109 TInt Position = aUrl.Find(_L("app://vsa@localhost/")); |
|
110 if(KErrNotFound != Position && 0 == Position) |
|
111 { |
|
112 return CheckAppLaunchFromInternetL(EVSAMode,aCurrentUrl); |
|
113 } |
|
114 |
|
115 Position = aUrl.Find(_L("app://cmd@localhost/")); |
|
116 if(KErrNotFound != Position && 0 == Position) |
|
117 { |
|
118 return CheckAppLaunchFromInternetL(ECmdMode,aCurrentUrl); |
|
119 } |
|
120 |
|
121 return ENoAppLaunch; |
|
122 } |
|
123 |
|
124 TBool AppLauncherForCSXH::LaunchApp(const TDesC& aUrl, TBool aVSAMode) |
|
125 { |
|
126 iParam1.Copy(KEmptyString); |
|
127 iParam2.Copy(KEmptyString); |
|
128 iParam3.Copy(KEmptyString); |
|
129 iParam4.Copy(KEmptyString); |
|
130 |
|
131 switch(CheckMsgParams(aUrl)) |
|
132 { |
|
133 case EParamsInvalid: |
|
134 return EFalse; |
|
135 case EParamsNoMsg: |
|
136 { |
|
137 ExtractTwoParams(aUrl); |
|
138 if(aVSAMode) |
|
139 { |
|
140 TInt32 AId,VId; |
|
141 GetUid(iParam1,AId); |
|
142 GetUid(iParam2,VId); |
|
143 TRAPD(res,CCSXHAppUi::GetInstance()->AppLaunchL(AId,VId)); |
|
144 return (res == KErrNone) ? ETrue : EFalse; |
|
145 } |
|
146 else |
|
147 { |
|
148 return LaunchCmdApp(EFalse); |
|
149 } |
|
150 } |
|
151 case EParamsWithMsg: |
|
152 { |
|
153 ExtractFourParams(aUrl); |
|
154 if(aVSAMode) |
|
155 { |
|
156 TInt32 AId,VId,MId; |
|
157 GetUid(iParam1,AId); |
|
158 GetUid(iParam2,VId); |
|
159 GetUid(iParam3,MId); |
|
160 TRAPD(res,CCSXHAppUi::GetInstance()->AppLaunchL(AId,VId,MId,iParam4)); |
|
161 return (res == KErrNone) ? ETrue : EFalse; |
|
162 } |
|
163 else |
|
164 { |
|
165 return LaunchCmdApp(ETrue); |
|
166 } |
|
167 } |
|
168 default: |
|
169 return EFalse; |
|
170 } |
|
171 } |
|
172 TBool AppLauncherForCSXH::LaunchCmdApp(TBool aParamsMode) |
|
173 { |
|
174 TRAPD(res,LaunchCmdAppL(aParamsMode)); |
|
175 if(res != KErrNone) |
|
176 return EFalse; |
|
177 return ETrue; |
|
178 } |
|
179 TBool AppLauncherForCSXH::LaunchCmdAppL(TBool aParamsMode) |
|
180 { |
|
181 /*valid cases |
|
182 app://cmd@localhost/APP_NAME/APP_UID |
|
183 app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters |
|
184 */ |
|
185 TApaTask task = GetCmdAppTask(); |
|
186 if (task.Exists()) |
|
187 {//App is already running |
|
188 if(aParamsMode) |
|
189 SendMsgToCmdAppTaskL(task); |
|
190 |
|
191 task.BringToForeground(); |
|
192 return ETrue; |
|
193 } |
|
194 //Application has to be started |
|
195 CApaCommandLine* cmdLine=CApaCommandLine::NewLC(); |
|
196 cmdLine->SetExecutableNameL(iParam1); |
|
197 cmdLine->SetCommandL(EApaCommandRun); |
|
198 |
|
199 RApaLsSession lsSession; |
|
200 User::LeaveIfError(lsSession.Connect()); |
|
201 CleanupClosePushL(lsSession); |
|
202 User::LeaveIfError(lsSession.StartApp(*cmdLine)); |
|
203 CleanupStack::PopAndDestroy(&lsSession); |
|
204 CleanupStack::PopAndDestroy(cmdLine); |
|
205 if(aParamsMode) |
|
206 { |
|
207 iCount = 0; |
|
208 TCallBack timer_Callback_to_terminateApp( Timer_Callback_to_TerminateApp,this ); |
|
209 StartTimer(timer_Callback_to_terminateApp); |
|
210 } |
|
211 |
|
212 return ETrue; |
|
213 } |
|
214 |
|
215 TInt AppLauncherForCSXH::Timer_Callback_to_TerminateApp(TAny* aPtr) |
|
216 { |
|
217 return static_cast<AppLauncherForCSXH*>( aPtr )->SendMsgToApplication(); |
|
218 } |
|
219 |
|
220 TInt AppLauncherForCSXH::SendMsgToApplication() |
|
221 { |
|
222 //If parameters has to be passed then the following is required |
|
223 TApaTask cmdTask = GetCmdAppTask(); |
|
224 if (cmdTask.Exists()) |
|
225 { |
|
226 TRAPD(res,SendMsgToCmdAppTaskL(cmdTask)); |
|
227 if(res != KErrNone) |
|
228 return 0; |
|
229 cmdTask.BringToForeground(); |
|
230 iTimer->Cancel(); |
|
231 } |
|
232 else if(++iCount > 20) |
|
233 { |
|
234 iTimer->Cancel(); |
|
235 } |
|
236 return 0; |
|
237 } |
|
238 |
|
239 TApaTask AppLauncherForCSXH::GetCmdAppTask() |
|
240 { |
|
241 TInt32 AId; |
|
242 GetUid(iParam2,AId); |
|
243 TApaTaskList taskList(CCSXHAppUi::GetInstance()->GetWsSession()); |
|
244 TUid KtestAppUid( TUid::Uid( AId ) ); |
|
245 return taskList.FindApp(KtestAppUid); |
|
246 } |
|
247 void AppLauncherForCSXH::SendMsgToCmdAppTaskL(TApaTask& aTask) |
|
248 { |
|
249 |
|
250 TInt32 MId; |
|
251 GetUid(iParam3,MId); |
|
252 TUid KtestMsgUid( TUid::Uid( MId ) ); |
|
253 HBufC8* params = CnvUtfConverter::ConvertFromUnicodeToUtf8L(iParam4); |
|
254 CleanupStack::PushL(params); |
|
255 aTask.SendMessage (KtestMsgUid, *params); |
|
256 CleanupStack::PopAndDestroy(params); |
|
257 } |
|
258 |
|
259 void AppLauncherForCSXH::HandleFailedAppLauchL() |
|
260 { |
|
261 HBufC* ErrorMessage = CCSXHAppUi::GetCoeEnv()->AllocReadResourceLC( |
|
262 R_QTN_HELP_NOTE_UNABLE_TO_LAUNCH_APP); |
|
263 CAknGlobalNote* note = CAknGlobalNote::NewLC(); |
|
264 note->ShowNoteL(EAknGlobalInformationNote, *ErrorMessage); |
|
265 CleanupStack::PopAndDestroy(note); |
|
266 CleanupStack::PopAndDestroy(ErrorMessage); |
|
267 } |
|
268 void AppLauncherForCSXH::HandleAppLauchFromInternetL() |
|
269 { |
|
270 HBufC* ErrorMessage = CCSXHAppUi::GetCoeEnv()->AllocReadResourceLC( |
|
271 R_QTN_HELP_NOTE_APP_LAUNCH_NOT_ALLOWED); |
|
272 CAknGlobalNote* note = CAknGlobalNote::NewLC(); |
|
273 note->ShowNoteL(EAknGlobalInformationNote, *ErrorMessage); |
|
274 CleanupStack::PopAndDestroy(note); |
|
275 CleanupStack::PopAndDestroy(ErrorMessage); |
|
276 } |
|
277 |
|
278 TInt AppLauncherForCSXH::CheckAppLaunchFromInternetL(TInt aCurrentMode,const TDesC& /*aCurrentUrl*/ ) |
|
279 { |
|
280 |
|
281 return aCurrentMode; |
|
282 //BrowserNG is lauched for Externalhyperlinks, |
|
283 //All the security issues are addresed by BrowserNG, |
|
284 |
|
285 /*(0 == aCurrentUrl.Find(KFileUrlPrefix) ) ? |
|
286 aCurrentMode : EAppLaunchFromInternet;*/ |
|
287 } |
|
288 |
|
289 TInt AppLauncherForCSXH::CheckMsgParams(const TDesC& aUrl) |
|
290 { |
|
291 /* |
|
292 The following are valid cases |
|
293 app://vsa@localhost/APP_UID/VIEW_UID |
|
294 app://vsa@localhost/APP_UID/VIEW_UID/MSG_UID/Parameters |
|
295 app://cmd@localhost/APP_NAME/APP_UID |
|
296 app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters |
|
297 |
|
298 That is, it should have exactly 4 backslashes or |
|
299 >= 6 backslashes (considering the possibility that parameters |
|
300 can have embedded backslashes) |
|
301 */ |
|
302 TBuf<KBackSlashLength> backSlash(KBackSlash); |
|
303 TInt count = 0; |
|
304 |
|
305 for(TInt i = 0 ; i < aUrl.Length() ; ++i) |
|
306 { |
|
307 if(KErrNotFound != backSlash.Find(&aUrl[i],KBackSlashLength)) |
|
308 ++count; |
|
309 } |
|
310 |
|
311 if(count == 4) |
|
312 return EParamsNoMsg; |
|
313 else if (count >=6) |
|
314 return EParamsWithMsg; |
|
315 else |
|
316 return EParamsInvalid; |
|
317 } |
|
318 |
|
319 void AppLauncherForCSXH::ExtractTwoParams(const TDesC& aUrl) |
|
320 { |
|
321 /*Will be called for the following cases |
|
322 app://vsa@localhost/APP_UID/VIEW_UID |
|
323 app://cmd@localhost/APP_NAME/APP_UID |
|
324 */ |
|
325 iParam1.Copy(KEmptyString); |
|
326 iParam2.Copy(KEmptyString); |
|
327 |
|
328 TBuf<KBackSlashLength> backSlash(KBackSlash); |
|
329 TInt count = 0; |
|
330 TInt pos; |
|
331 |
|
332 for(pos = 0; pos < aUrl.Length() ; ++pos) |
|
333 { |
|
334 if(KErrNotFound != backSlash.Find(&aUrl[pos],KBackSlashLength)) |
|
335 ++count; |
|
336 if(count == KBackSlashesInPrefix) |
|
337 break; |
|
338 } |
|
339 TPtrC16 url = aUrl.Mid(pos + 1); |
|
340 pos = url.Find(KBackSlash); |
|
341 iParam1 = url.Left(pos); |
|
342 iParam2 = url.Mid(pos + 1); |
|
343 } |
|
344 |
|
345 void AppLauncherForCSXH::ExtractFourParams(const TDesC& aUrl) |
|
346 { |
|
347 /*Will be called for the following cases |
|
348 app://vsa@localhost/APP_UID/VIEW_UID/MSG_UID/Parameters |
|
349 app://cmd@localhost/APP_NAME/APP_UID/MSG_UID/Parameters |
|
350 */ |
|
351 iParam1.Copy(KEmptyString); |
|
352 iParam2.Copy(KEmptyString); |
|
353 iParam3.Copy(KEmptyString); |
|
354 iParam4.Copy(KEmptyString); |
|
355 |
|
356 TBuf<KBackSlashLength> backSlash(KBackSlash); |
|
357 TInt count = 0; |
|
358 TInt pos; |
|
359 |
|
360 for(pos = 0; pos < aUrl.Length() ; ++pos) |
|
361 { |
|
362 if(KErrNotFound != backSlash.Find(&aUrl[pos],KBackSlashLength)) |
|
363 ++count; |
|
364 if(count == KBackSlashesInPrefix) |
|
365 break; |
|
366 } |
|
367 |
|
368 TPtrC16 url = aUrl.Mid(pos + 1); |
|
369 pos = url.Find(KBackSlash); |
|
370 iParam1 = url.Left(pos); |
|
371 |
|
372 TPtrC16 url2 = url.Mid(pos + 1); |
|
373 pos = url2.Find(KBackSlash); |
|
374 iParam2 = url2.Left(pos); |
|
375 |
|
376 TPtrC16 url3 = url2.Mid(pos + 1); |
|
377 pos = url3.Find(KBackSlash); |
|
378 iParam3 = url3.Left(pos); |
|
379 |
|
380 iParam4 = url3.Mid(pos+1); |
|
381 } |
|
382 |
|
383 void AppLauncherForCSXH::GetUid(TPtrC aUid, TInt32& aResult) |
|
384 { |
|
385 TInt hexPos = aUid.Find(_L("x")); |
|
386 if(KErrNotFound == hexPos) |
|
387 TLex(aUid).Val(aResult); |
|
388 else |
|
389 { |
|
390 TPtrC16 uidt = aUid.Mid(hexPos+1); |
|
391 TInt64 res; |
|
392 //During this operation sometimes values exceed TInt32, but the end result is always |
|
393 //fits into TInt32 |
|
394 TLex(uidt).Val(res,EHex); |
|
395 aResult = res; |
|
396 } |
|
397 } |
|
398 |
|
399 void AppLauncherForCSXH::LaunchBrowserNGL(const TDesC& aUrl) |
|
400 { |
|
401 _LIT( KBrowserCmdFetchUrl, "4 " ); |
|
402 HBufC* param = HBufC::NewLC( KBrowserCmdFetchUrl().Length() + |
|
403 aUrl.Length() ); |
|
404 TPtr paramPtr = param->Des(); |
|
405 paramPtr.Copy( KBrowserCmdFetchUrl ); |
|
406 paramPtr.Append( aUrl ); |
|
407 |
|
408 if(!SendMsgToBrowserNGL(param)) |
|
409 { |
|
410 RApaLsSession appArcSession; |
|
411 User::LeaveIfError( appArcSession.Connect() ); |
|
412 CleanupClosePushL<RApaLsSession>( appArcSession ); |
|
413 |
|
414 TThreadId id; |
|
415 User::LeaveIfError |
|
416 ( |
|
417 appArcSession.StartDocument(*param,KUidBrowserApplication,id ) |
|
418 ); |
|
419 CleanupStack::PopAndDestroy( &appArcSession ); |
|
420 } |
|
421 |
|
422 CleanupStack::PopAndDestroy( param ); |
|
423 } |
|
424 |
|
425 TBool AppLauncherForCSXH::SendMsgToBrowserNGL(const HBufC* aUrl) |
|
426 { |
|
427 TApaTaskList taskList(CCSXHAppUi::GetInstance()->GetWsSession()); |
|
428 TApaTask task = taskList.FindApp(KUidBrowserApplication); |
|
429 if(task.Exists()) |
|
430 { |
|
431 // 8-bit buffer is required. |
|
432 HBufC8* param8 = HBufC8::NewLC( aUrl->Length() ); |
|
433 param8->Des().Copy( *aUrl ); |
|
434 task.SendMessage( TUid::Uid( 0 ), *param8 ); // Uid is not used |
|
435 CleanupStack::PopAndDestroy( param8 ); |
|
436 return ETrue; |
|
437 } |
|
438 else |
|
439 return EFalse; |
|
440 } |
|
441 |
|
442 void AppLauncherForCSXH::StartTimer(TCallBack aCallBack) |
|
443 { |
|
444 if( iTimer->IsActive() ) |
|
445 { |
|
446 iTimer->Cancel(); |
|
447 } |
|
448 |
|
449 iTimer->Start( |
|
450 TTimeIntervalMicroSeconds32( KKeyBlockTime ), |
|
451 TTimeIntervalMicroSeconds32( KKeyBlockTime ), |
|
452 aCallBack ); |
|
453 } |
|