|
1 /* |
|
2 * Copyright (c) 2004-2009 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 the License "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: |
|
15 * Implementation of Swi::CUissClientHandler class which is the client-side |
|
16 * part of the reverse completion mechanism used by SWI to communicate with |
|
17 * the UI |
|
18 * |
|
19 */ |
|
20 |
|
21 |
|
22 /** |
|
23 @file |
|
24 */ |
|
25 #include "uissclienthandler.h" |
|
26 #include "uisscommand.h" |
|
27 #include "uisssession.h" |
|
28 #include "../source/uiss/server/uissserver.h" |
|
29 #include "sishelper.h" |
|
30 #include "sisregistrypackage.h" |
|
31 #include "writestream.h" |
|
32 // UI Support Server Commands |
|
33 #include "commands/installdialog.h" |
|
34 #include "commands/grantcapabilitiesdialog.h" |
|
35 #include "commands/languagedialog.h" |
|
36 #include "commands/applicationsinusedialog.h" |
|
37 #include "commands/drivedialog.h" |
|
38 #include "commands/cannotoverwritefiledialog.h" |
|
39 #include "commands/dependencybreakdialog.h" |
|
40 #include "commands/deviceincompatibility.h" |
|
41 #include "commands/missingdependency.h" |
|
42 #include "commands/errordialog.h" |
|
43 #include "commands/handlecancellableinstallevent.h" |
|
44 #include "commands/handleinstallevent.h" |
|
45 #include "commands/ocspresultdialog.h" |
|
46 #include "commands/optionsdialog.h" |
|
47 #include "commands/questiondialog.h" |
|
48 #include "commands/upgradedialog.h" |
|
49 #include "commands/uninstalldialog.h" |
|
50 #include "commands/securitywarningdialog.h" |
|
51 #include "commands/textdialog.h" |
|
52 #include "log.h" |
|
53 |
|
54 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
55 #include "cleanuputils.h" |
|
56 #include <usif/sif/sifcommon.h> |
|
57 const TInt KCompInfoBufferSize=4*1024; |
|
58 #endif |
|
59 |
|
60 namespace Swi |
|
61 { |
|
62 // |
|
63 // A cancel handler |
|
64 // |
|
65 class InternalCancelHandler : public MCancelHandler |
|
66 { |
|
67 public: |
|
68 InternalCancelHandler(CUissClientHandler& aUissClientHandler); |
|
69 void HandleCancel(); |
|
70 private: |
|
71 CUissClientHandler& iUissClientHandler; |
|
72 }; |
|
73 |
|
74 InternalCancelHandler::InternalCancelHandler( |
|
75 CUissClientHandler& aUissClientHandler) |
|
76 : iUissClientHandler(aUissClientHandler) |
|
77 { |
|
78 } |
|
79 |
|
80 void InternalCancelHandler::HandleCancel() |
|
81 { |
|
82 iUissClientHandler.CancelOperation(); |
|
83 } |
|
84 |
|
85 CUissClientHandler* CUissClientHandler::NewLC(MUiHandler& aUiHandler, TBool aActiveObjectMode) |
|
86 { |
|
87 CUissClientHandler* self=new(ELeave) CUissClientHandler(aUiHandler, aActiveObjectMode); |
|
88 CleanupStack::PushL(self); |
|
89 self->ConstructL(); |
|
90 return self; |
|
91 } |
|
92 |
|
93 CUissClientHandler* CUissClientHandler::NewL(MUiHandler& aUiHandler, TBool aActiveObjectMode) |
|
94 { |
|
95 CUissClientHandler* self=NewLC(aUiHandler, aActiveObjectMode); |
|
96 CleanupStack::Pop(self); |
|
97 return self; |
|
98 } |
|
99 |
|
100 CUissClientHandler::CUissClientHandler(MUiHandler& aUiHandler, TBool aActiveObjectMode) |
|
101 : CActive(EPriorityStandard), |
|
102 iUiHandler(aUiHandler), |
|
103 iPtrIntoBuf(0,0), |
|
104 iActiveObjectMode(aActiveObjectMode), |
|
105 iPtrIntoArgsStream(0,0) |
|
106 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
107 ,iCompInfoBufPtr(0,0) |
|
108 #endif |
|
109 { |
|
110 if (iActiveObjectMode) |
|
111 { |
|
112 CActiveScheduler::Add(this); |
|
113 } |
|
114 } |
|
115 |
|
116 void CUissClientHandler::WaitForSisHelperShutdown() |
|
117 { |
|
118 if(iSisHelper.Handle() > 0) |
|
119 { |
|
120 TRequestStatus reqStatus; |
|
121 iSisHelper.Logon(reqStatus); |
|
122 User::WaitForRequest(reqStatus); |
|
123 iSisHelper.Close(); |
|
124 } |
|
125 } |
|
126 |
|
127 CUissClientHandler::~CUissClientHandler() |
|
128 { |
|
129 //Cancel any outstanding request |
|
130 CancelOperation(); |
|
131 |
|
132 WaitForSisHelperShutdown(); |
|
133 if (iActiveObjectMode) |
|
134 { |
|
135 CActive::Cancel(); // Make sure we are cancelled before deletion |
|
136 } |
|
137 |
|
138 delete iCancelHandler; |
|
139 delete iArgsStream; |
|
140 iUissSession.Close(); |
|
141 delete iBuf; |
|
142 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
143 delete iCompInfoBuffer; |
|
144 #endif |
|
145 } |
|
146 |
|
147 /** |
|
148 * Allocates a buffer for reverse-completion commands. The buffer is going to |
|
149 * be resized in case it is not sufficient for a dialog command. |
|
150 */ |
|
151 void CUissClientHandler::ConstructL() |
|
152 { |
|
153 iCancelHandler=new(ELeave) InternalCancelHandler(*this); |
|
154 AllocBufL(KBufSize);// Allocate the initial r/c buffer |
|
155 User::LeaveIfError(StartUiss()); // Start UISS |
|
156 User::LeaveIfError(iUissSession.Connect()); // Connect to UISS |
|
157 } |
|
158 |
|
159 void CUissClientHandler::AllocBufL(TInt aSize) |
|
160 { |
|
161 HBufC8* buf=HBufC8::NewL(aSize); |
|
162 delete iBuf; |
|
163 iBuf=buf; |
|
164 } |
|
165 |
|
166 void CUissClientHandler::HandleOverflowL() |
|
167 { |
|
168 // Reallocate the buffer to the size received in parameter 1 |
|
169 TInt size=0; |
|
170 TPckg<TInt> theSize(size); |
|
171 theSize.Copy(iBuf->Left(sizeof(TInt))); |
|
172 AllocBufL(size); |
|
173 } |
|
174 |
|
175 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
176 void CUissClientHandler::AllocCompInfoBufL(TInt aSize) |
|
177 { |
|
178 HBufC8* buf = HBufC8::NewL(aSize); |
|
179 delete iCompInfoBuffer; |
|
180 iCompInfoBuffer = buf; |
|
181 } |
|
182 #endif |
|
183 |
|
184 ///\short Creates a command handler object for the specified dialog request |
|
185 CUissCmdHandler* CUissClientHandler::UissCmdHandlerFactoryL(TInt aCommand) const |
|
186 { |
|
187 switch (aCommand) |
|
188 { |
|
189 case CUissSession::KMessageApplicationsInUseDialog: |
|
190 return new(ELeave) CApplicationsInUseDialogCmdHandler(iUiHandler); |
|
191 case CUissSession::KMessageCannotOverwriteFileDialog: |
|
192 return new(ELeave) CCannotOverwriteFileDialogCmdHandler(iUiHandler); |
|
193 |
|
194 case CUissSession::KMessageDependencyBreakDialog: |
|
195 return new(ELeave) CDependencyBreakDialogCmdHandler(iUiHandler); |
|
196 case CUissSession::KMessageDeviceIncompatibility: |
|
197 return new(ELeave) CDeviceIncompatibilityDialogCmdHandler(iUiHandler); |
|
198 case CUissSession::KMessageMissingDependency: |
|
199 return new(ELeave) CMissingDependencyDialogCmdHandler(iUiHandler); |
|
200 case CUissSession::KMessageDriveDialog: |
|
201 return new(ELeave) CDriveDialogCmdHandler(iUiHandler); |
|
202 case CUissSession::KMessageErrorDialog: |
|
203 return new(ELeave) CErrorDialogCmdHandler(iUiHandler); |
|
204 case CUissSession::KMessageGrantCapabilitiesDialog: |
|
205 return new(ELeave) CGrantCapabilitiesDialogCmdHandler(iUiHandler); |
|
206 case CUissSession::KMessageHandleCancellableInstallEvent: |
|
207 return new(ELeave) CHandleCancellableInstallEventCmdHandler(iUiHandler, |
|
208 *iCancelHandler); |
|
209 case CUissSession::KMessageHandleInstallEvent: |
|
210 return new(ELeave) CHandleInstallEventCmdHandler(iUiHandler); |
|
211 case CUissSession::KMessageInstallDialog: |
|
212 return new(ELeave) CInstallDialogCmdHandler(iUiHandler); |
|
213 case CUissSession::KMessageLanguageDialog: |
|
214 return new(ELeave) CLanguageDialogCmdHandler(iUiHandler); |
|
215 case CUissSession::KMessageOcspResultDialog: |
|
216 return new(ELeave) COcspResultDialogCmdHandler(iUiHandler); |
|
217 case CUissSession::KMessageOptionsDialog: |
|
218 return new(ELeave) COptionsDialogCmdHandler(iUiHandler); |
|
219 case CUissSession::KMessageQuestionDialog: |
|
220 return new(ELeave) CQuestionDialogCmdHandler(iUiHandler); |
|
221 case CUissSession::KMessageSecurityWarningDialog: |
|
222 return new(ELeave) CSecurityWarningDialogCmdHandler(iUiHandler); |
|
223 case CUissSession::KMessageUninstallDialog: |
|
224 return new(ELeave) CUninstallDialogCmdHandler(iUiHandler); |
|
225 |
|
226 case CUissSession::KMessageUpgradeDialog: |
|
227 return new(ELeave) CUpgradeDialogCmdHandler(iUiHandler); |
|
228 |
|
229 case CUissSession::KMessageTextDialog: |
|
230 return new(ELeave) CTextDialogCmdHandler(iUiHandler); |
|
231 |
|
232 default: |
|
233 return NULL; |
|
234 } |
|
235 } |
|
236 |
|
237 void CUissClientHandler::InitializeArgStreamL(const CInstallPrefs& aInstallPrefs) |
|
238 { |
|
239 // Stream out install parameters. Cannot do this in UISSCLIENT because |
|
240 // the code is in LAUNCHER which depends on UISSCLIENT. |
|
241 delete iArgsStream; |
|
242 iArgsStream = 0; |
|
243 iArgsStream = CWriteStream::NewL(); |
|
244 *iArgsStream << aInstallPrefs; |
|
245 // Save ptr for args (must persist whilst server is processing) |
|
246 iPtrIntoArgsStream.Set(iArgsStream->Ptr()); |
|
247 } |
|
248 |
|
249 void CUissClientHandler::InstallL(const CInstallPrefs& aInstallPrefs, const RArray<TInt>& aDeviceSupportedLanguages, TRequestStatus& aRequestStatus, RThread& aServer) |
|
250 { |
|
251 iState = KUissClientInstalling; |
|
252 iClientStatus = &aRequestStatus; |
|
253 |
|
254 // Save ptr for data returned by request (must persist whilst server is processing) |
|
255 iPtrIntoBuf.Set(iBuf->Des()); |
|
256 |
|
257 InitializeArgStreamL(aInstallPrefs); |
|
258 iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages.Count()); |
|
259 //Streaming set of languages that device supports |
|
260 TInt noOfDeviceSupportedLanguages = aDeviceSupportedLanguages.Count(); |
|
261 for(TInt i=0;i<noOfDeviceSupportedLanguages;i++) |
|
262 { |
|
263 iArgsStream->Stream().WriteInt32L(aDeviceSupportedLanguages[i]); |
|
264 } |
|
265 // Save ptr for args (must persist whilst server is processing) |
|
266 iPtrIntoArgsStream.Set(iArgsStream->Ptr()); |
|
267 |
|
268 // Issue initial request |
|
269 iUissSession.Install(iPtrIntoArgsStream, iPtrIntoBuf, iStatus); |
|
270 if (iActiveObjectMode) |
|
271 { |
|
272 SetActive(); |
|
273 } |
|
274 |
|
275 // Update client's TRequestStatus object |
|
276 *iClientStatus = KRequestPending; |
|
277 iSisHelper = aServer; |
|
278 } |
|
279 |
|
280 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
281 void CUissClientHandler::GetComponentInfoL(const CInstallPrefs& aInstallPrefs, Usif::CComponentInfo& aComponentInfo, TRequestStatus& aRequestStatus, RThread& aServer) |
|
282 { |
|
283 iState = KUissClientGettingCompInfo; |
|
284 iClientStatus = &aRequestStatus; |
|
285 |
|
286 // Store the component info reference to the class reference. So that, the same will be |
|
287 // populated after getting the asynchronous method completed. |
|
288 iComponentInfo = &aComponentInfo; |
|
289 |
|
290 InitializeArgStreamL(aInstallPrefs); |
|
291 |
|
292 AllocCompInfoBufL(KCompInfoBufferSize); |
|
293 |
|
294 // Save the pointer for component info collection buffer |
|
295 iCompInfoBufPtr.Set(iCompInfoBuffer->Des()); |
|
296 |
|
297 // Issue get component info request |
|
298 iUissSession.GetComponentInfo(iPtrIntoArgsStream, iCompInfoBufPtr, iStatus); |
|
299 |
|
300 // There is no synchronous API for GetComponentInfo |
|
301 __ASSERT_ALWAYS(iActiveObjectMode, User::Invariant()); |
|
302 SetActive(); |
|
303 |
|
304 // Update client's TRequestStatus object |
|
305 *iClientStatus = KRequestPending; |
|
306 iSisHelper = aServer; |
|
307 } |
|
308 #endif |
|
309 |
|
310 void CUissClientHandler::UninstallL(const CSisRegistryPackage& aPackage, TRequestStatus& aRequestStatus) |
|
311 { |
|
312 iState = KUissClientUninstalling; |
|
313 iClientStatus = &aRequestStatus; |
|
314 |
|
315 // Save ptr for data returned by request (must persist whilst server is processing) |
|
316 iPtrIntoBuf.Set(iBuf->Des()); |
|
317 |
|
318 delete iArgsStream; |
|
319 iArgsStream = 0; |
|
320 iArgsStream = CWriteStream::NewL(); |
|
321 *iArgsStream << aPackage; |
|
322 // Save ptr for args (must persist whilst server is processing) |
|
323 iPtrIntoArgsStream.Set(iArgsStream->Ptr()); |
|
324 |
|
325 // Issue initial request |
|
326 iUissSession.Uninstall(iPtrIntoArgsStream, iPtrIntoBuf, iStatus); |
|
327 if (iActiveObjectMode) |
|
328 { |
|
329 SetActive(); |
|
330 } |
|
331 |
|
332 // Update client's TRequestStatus object |
|
333 *iClientStatus = KRequestPending; |
|
334 } |
|
335 |
|
336 void CUissClientHandler::CancelOperation() |
|
337 { |
|
338 if (iState == KUissClientIdle) |
|
339 { |
|
340 return; |
|
341 } |
|
342 |
|
343 // User called this so must have an outstanding request with us. |
|
344 |
|
345 // First tell the Uiss that we want to cancel the current |
|
346 // operation. |
|
347 // |
|
348 // If we have an outstanding Uiss request, this will complete (with |
|
349 // KErrCancel) when the operation has terminated. |
|
350 // |
|
351 // If we are called inside a dialog callback, then there is no |
|
352 // outstanding Uiss request at the moment. When the dialog |
|
353 // returns, we will issue a request, which will complete (with |
|
354 // KErrCancel) when the operation has terminated. |
|
355 (void)iUissSession.Cancel(); |
|
356 } |
|
357 |
|
358 void CUissClientHandler::WorkUntilCompleteL() |
|
359 { |
|
360 // Keep processing UISS responses and issuing new requests |
|
361 // until we update the client status to non-pending. |
|
362 while(iClientStatus && *iClientStatus == KRequestPending) |
|
363 { |
|
364 User::WaitForRequest(iStatus); |
|
365 TRAPD(err,RunL()); |
|
366 if(err != KErrNone) |
|
367 { |
|
368 RunError(err); |
|
369 } |
|
370 } |
|
371 } |
|
372 |
|
373 TBool CUissClientHandler::IsBusy() |
|
374 { |
|
375 return iState != KUissClientIdle; |
|
376 } |
|
377 |
|
378 |
|
379 // |
|
380 // Code necessary to run UISS in the same process but in a different thread |
|
381 // |
|
382 TInt CUissClientHandler::StartUiss() |
|
383 { |
|
384 const TInt KUissServerStackSize=0x2000; |
|
385 const TInt KUissServerInitHeapSize=0x1000; |
|
386 const TInt KUissServerMaxHeapSize=0x1000000; |
|
387 |
|
388 |
|
389 TThreadFunction entryPoint=UissThreadFunction; |
|
390 //TUiSupportStartParams uiSupportParams(aUiHandler); |
|
391 // The owner of the new thread will be the process, otherwise if the |
|
392 // current thread dies, the server thread will die, too. |
|
393 RThread server; |
|
394 TInt err = KErrNone; |
|
395 |
|
396 for (TInt retry=0; retry < 2; ++retry) |
|
397 { |
|
398 err = server.Create(KUissServerName, entryPoint, |
|
399 KUissServerStackSize, KUissServerInitHeapSize, KUissServerMaxHeapSize, |
|
400 NULL, EOwnerThread); |
|
401 |
|
402 if (err == KErrAlreadyExists) |
|
403 { |
|
404 User::After(30000); |
|
405 } |
|
406 else |
|
407 { |
|
408 break; |
|
409 } |
|
410 } |
|
411 |
|
412 if (err==KErrAlreadyExists) |
|
413 { |
|
414 return KErrServerBusy; |
|
415 } |
|
416 if (err != KErrNone) |
|
417 { |
|
418 return err; |
|
419 } |
|
420 |
|
421 // Synchronise with the process to make sure it hasn't died straight away |
|
422 TRequestStatus stat; |
|
423 server.Rendezvous(stat); |
|
424 if (stat != KRequestPending) |
|
425 { |
|
426 // logon failed - server is not yet running, so cannot have terminated |
|
427 server.Kill(0); // Abort startup |
|
428 } |
|
429 else |
|
430 { |
|
431 // logon OK - start the server |
|
432 server.Resume(); |
|
433 } |
|
434 // Wait to synchronise with server - if it dies in the meantime, it |
|
435 // also gets completed |
|
436 User::WaitForRequest(stat); |
|
437 // We can't use the 'exit reason' if the server panicked as this |
|
438 // is the panic 'reason' and may be '0' which cannot be distinguished |
|
439 // from KErrNone |
|
440 TInt r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); |
|
441 server.Close(); |
|
442 return r; |
|
443 } |
|
444 |
|
445 // Entry point for the thread the UISS runs in |
|
446 TInt CUissClientHandler::UissThreadFunction(TAny *) |
|
447 { |
|
448 __UHEAP_MARK; |
|
449 CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack |
|
450 |
|
451 CActiveScheduler* scheduler=new(ELeave) CActiveScheduler; |
|
452 CActiveScheduler::Install(scheduler); |
|
453 CUissServer* server=NULL; |
|
454 |
|
455 TRAPD(err, server=CUissServer::NewL()); |
|
456 if (err==KErrNone) |
|
457 { |
|
458 RThread::Rendezvous(KErrNone); |
|
459 scheduler->Start(); |
|
460 } |
|
461 |
|
462 delete server; |
|
463 |
|
464 CActiveScheduler::Install(NULL); |
|
465 delete scheduler; |
|
466 delete cleanup; // destroy clean-up stack |
|
467 __UHEAP_MARKEND; |
|
468 return KErrNone; |
|
469 } |
|
470 |
|
471 void CUissClientHandler::RunL() |
|
472 { |
|
473 TInt err = iStatus.Int(); |
|
474 iPtrIntoBuf.Set(iBuf->Des()); // Get ptr to our return buffer |
|
475 |
|
476 DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunL(). Status: %d."), err); |
|
477 |
|
478 |
|
479 if (err==KErrOverflow |
|
480 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
481 && iState != KUissClientGettingCompInfo // We don't support overflow management for component info |
|
482 #endif |
|
483 ) |
|
484 { |
|
485 // Grow the respective buffer buffer and re-issue "request". |
|
486 // There should now be space for the UISS server to copy in its dialogue message. |
|
487 HandleOverflowL(); |
|
488 iPtrIntoBuf.Set(iBuf->Des()); |
|
489 iUissSession.BufferReallocated(iPtrIntoBuf, iStatus); |
|
490 |
|
491 if (iActiveObjectMode) |
|
492 { |
|
493 SetActive(); |
|
494 } |
|
495 return; |
|
496 } |
|
497 else |
|
498 { |
|
499 if (err>CUissSession::KMsgSeparatorMinimumSwisMessage && |
|
500 err<CUissSession::KMsgSeparatorMaximumSwisMessage) |
|
501 { |
|
502 // this is a dialog request, unmarshal parameters and display |
|
503 // the dialog |
|
504 CUissCmdHandler* cmdHandler=UissCmdHandlerFactoryL(err); |
|
505 if (!cmdHandler) |
|
506 { |
|
507 User::Leave(KErrNotSupported); |
|
508 } |
|
509 |
|
510 CleanupStack::PushL(cmdHandler); |
|
511 // Note that the callback might call CancelOperation which |
|
512 // would update iState... |
|
513 cmdHandler->HandleMessageL(iPtrIntoBuf, iPtrIntoBuf); |
|
514 CleanupStack::PopAndDestroy(cmdHandler); |
|
515 } |
|
516 else |
|
517 { |
|
518 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
519 // Request has been completed successfully. So, now construct the |
|
520 // component info from the buffer which is populated from the SWI server. |
|
521 if (err == KErrNone && iState == KUissClientGettingCompInfo) |
|
522 { |
|
523 ConstructCompInfoFromBufferL(); |
|
524 } |
|
525 #endif |
|
526 // Either KErrNone or some sort of error status - in any case the processing has finished |
|
527 iState = KUissClientIdle; |
|
528 } |
|
529 } |
|
530 |
|
531 // Re-issue request, if we are still installing/uninstalling |
|
532 switch(iState) |
|
533 { |
|
534 case KUissClientInstalling: |
|
535 case KUissClientUninstalling: |
|
536 iUissSession.CompleteDialog(KErrNone, iPtrIntoBuf, iStatus); |
|
537 if (iActiveObjectMode) |
|
538 { |
|
539 SetActive(); |
|
540 } |
|
541 return; |
|
542 |
|
543 case KUissClientIdle: |
|
544 // All done, or failed... |
|
545 delete iArgsStream; |
|
546 iArgsStream = 0; |
|
547 //Wait for the death of SisHelper |
|
548 WaitForSisHelperShutdown(); |
|
549 // Complete user request (also sets iClientStatus to 0) |
|
550 ASSERT(iClientStatus); |
|
551 User::RequestComplete(iClientStatus, err); |
|
552 return; |
|
553 } |
|
554 ASSERT(false); |
|
555 } |
|
556 |
|
557 |
|
558 TInt CUissClientHandler::RunError(TInt aError) |
|
559 { |
|
560 DEBUG_PRINTF2(_L8("Sis Helper - UISS Client Handler, RunError. Error: %d."), aError); |
|
561 // Pass failure code on to our client. |
|
562 iPtrIntoBuf.Zero(); |
|
563 iUissSession.CompleteDialog(aError, iPtrIntoBuf, iStatus); |
|
564 if (iActiveObjectMode) |
|
565 { |
|
566 SetActive(); |
|
567 } |
|
568 return KErrNone; // Do not crash the CActiveScheduler. |
|
569 } |
|
570 |
|
571 void CUissClientHandler::DoCancel() |
|
572 { |
|
573 DEBUG_PRINTF(_L8("Sis Helper - UISS Client Handler, Cancelling.")); |
|
574 |
|
575 // Normally NEVER called because the application should have |
|
576 // waited for the original request to complete! |
|
577 |
|
578 // We can NOT simply call CancelOperation, because when we return |
|
579 // into the framework Cancel function it will block on our |
|
580 // iStatus, which would stop the active scheduler and hence stop |
|
581 // the CancelOperation from being actioned. |
|
582 |
|
583 // Do an emergency abort..... |
|
584 |
|
585 // First kill our helper threads |
|
586 |
|
587 // SIS helper thread/server |
|
588 CSisHelperServer::Abort(); |
|
589 |
|
590 // UI helper thread/server |
|
591 TFullName fullName = RProcess().FullName(); |
|
592 fullName.Append(':'); |
|
593 fullName.Append(':'); |
|
594 fullName.Append(KUissServerName); |
|
595 |
|
596 RThread server; |
|
597 TInt err = server.Open(fullName); |
|
598 if (err == KErrNone) |
|
599 { |
|
600 server.Terminate(KErrAbort); |
|
601 server.Close(); |
|
602 } |
|
603 |
|
604 // Now complete any client request |
|
605 if (iClientStatus) |
|
606 { |
|
607 User::RequestComplete(iClientStatus, err); |
|
608 } |
|
609 } |
|
610 |
|
611 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK |
|
612 void CUissClientHandler::ConstructCompInfoFromBufferL() |
|
613 { |
|
614 // create a stream based on the buffer |
|
615 RDesReadStream stream(*iCompInfoBuffer); |
|
616 CleanupClosePushL(stream); |
|
617 |
|
618 CNativeComponentInfo* nativeCompInfo = CNativeComponentInfo::NewLC(); |
|
619 nativeCompInfo->InternalizeL(stream); |
|
620 |
|
621 // UISS and SWI cannot use Usif::CComponentInfo directly, as it is implemented in a non-TCB DLL. For this reason, a private structure maintained (CNativeComponentInfo), |
|
622 // which is returned by SWI and is converted here to the CComponentInfo according to the USIF interface |
|
623 Usif::CComponentInfo::CNode* rootNode = MapToComponentInfoL(*nativeCompInfo); |
|
624 iComponentInfo->SetRootNodeL(rootNode); |
|
625 |
|
626 CleanupStack::PopAndDestroy(nativeCompInfo); |
|
627 CleanupStack::PopAndDestroy(&stream); |
|
628 } |
|
629 |
|
630 Usif::CComponentInfo::CNode* CUissClientHandler::MapToComponentInfoL(CNativeComponentInfo& aNativeComponentInfo) |
|
631 { |
|
632 // Create the array to store the children nodes. |
|
633 RPointerArray<Usif::CComponentInfo::CNode> children; |
|
634 CleanupResetAndDestroyPushL(children); |
|
635 |
|
636 // If there is any child for the current node, call this method with that child object. |
|
637 // Continue this (recursively) until we get the leaf node in the embedded tree (with no children) |
|
638 // and add the resultant node as one of the children and pass it to create the parent node further. |
|
639 TInt count = aNativeComponentInfo.iChildren.Count(); |
|
640 for (TInt i = 0; i < count; ++i) |
|
641 { |
|
642 Usif::CComponentInfo::CNode* node = MapToComponentInfoL(*aNativeComponentInfo.iChildren[i]); |
|
643 CleanupStack::PushL(node); |
|
644 children.AppendL(node); |
|
645 CleanupStack::Pop(node); |
|
646 } |
|
647 |
|
648 // Create the CNode object using the appropriate parameters. |
|
649 // children for leaf nodes (bottom most nodes in the embedded tree) will be null. |
|
650 Usif::CComponentInfo::CNode* node = Usif::CComponentInfo::CNode::NewLC( |
|
651 Usif::KSoftwareTypeNative(), |
|
652 *(aNativeComponentInfo.iComponentName), |
|
653 *(aNativeComponentInfo.iVersion), |
|
654 *(aNativeComponentInfo.iVendor), |
|
655 static_cast<Usif::TScomoState>(aNativeComponentInfo.iScomoState), |
|
656 static_cast<Usif::TInstallStatus>(aNativeComponentInfo.iInstallStatus), |
|
657 aNativeComponentInfo.iComponentId, |
|
658 *(aNativeComponentInfo.iGlobalComponentId), |
|
659 static_cast<Usif::TAuthenticity>(aNativeComponentInfo.iAuthenticity), |
|
660 aNativeComponentInfo.iUserGrantableCaps, |
|
661 aNativeComponentInfo.iMaxInstalledSize, |
|
662 aNativeComponentInfo.iHasExe, |
|
663 &children); |
|
664 CleanupStack::Pop(node); |
|
665 CleanupStack::Pop(&children); |
|
666 children.Close(); |
|
667 return (node); |
|
668 } |
|
669 #endif |
|
670 } // namespace Swi |