|
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 // |
|
15 |
|
16 #include "EIKBAKSV.H" |
|
17 #include <babackup.h> |
|
18 #include <basched.h> |
|
19 |
|
20 #include <e32base.h> |
|
21 #include <w32std.h> |
|
22 #include <apaid.h> |
|
23 #include <apacmdln.h> |
|
24 #include <apgcli.h> |
|
25 #include <apgtask.h> |
|
26 #include <apgwgnam.h> |
|
27 #include <coemain.h> // for TActivePriority only |
|
28 #include <uikon/patchdata.h> |
|
29 |
|
30 class RFindLib : public RLibrary |
|
31 { |
|
32 public: |
|
33 inline TInt Open(const TFindLibrary& aFind,TOwnerType aType=EOwnerProcess); |
|
34 }; |
|
35 |
|
36 inline TInt RFindLib::Open(const TFindLibrary& aFind,TOwnerType aType) |
|
37 {return(RHandleBase::Open(aFind,aType));} |
|
38 |
|
39 |
|
40 // |
|
41 // class CEikServBackupServer |
|
42 // |
|
43 |
|
44 |
|
45 /** |
|
46 Creates a CEikServBackupServer. |
|
47 Static factory function. |
|
48 Does not call ConstructL (BUT ConstructL is not EXPORTed !?!?) |
|
49 @return Instantiated object |
|
50 @publishedAll |
|
51 @released |
|
52 */ |
|
53 EXPORT_C CEikServBackupServer* CEikServBackupServer::NewL() |
|
54 { // static |
|
55 CEikServBackupServer* self=new(ELeave) CEikServBackupServer(EActivePriorityIpcEventsHigh); |
|
56 return self; |
|
57 } |
|
58 |
|
59 /** |
|
60 Constructor |
|
61 @internalComponent |
|
62 */ |
|
63 CEikServBackupServer::CEikServBackupServer(TInt aPriority) |
|
64 : CBaBackupServer(aPriority) |
|
65 {} |
|
66 |
|
67 /** |
|
68 2nd phase constructor. Opens connection to Window Server |
|
69 Framework function |
|
70 @see CBaBackupServer::ConstructL() |
|
71 */ |
|
72 void CEikServBackupServer::ConstructL() |
|
73 { |
|
74 CBaBackupServer::ConstructL(); |
|
75 } |
|
76 |
|
77 /** |
|
78 Destructor |
|
79 */ |
|
80 CEikServBackupServer::~CEikServBackupServer() |
|
81 { |
|
82 delete iAppStarter; |
|
83 } |
|
84 |
|
85 |
|
86 /** |
|
87 Framework function |
|
88 @see CBaBackupServer::IsOtherClientBusy(TUint32 aUniqueClientId) |
|
89 */ |
|
90 TBool CEikServBackupServer::IsOtherClientBusy(TUint32 aUniqueClientId) const |
|
91 { |
|
92 return (iAppStarter || CBaBackupServer::IsOtherClientBusy(aUniqueClientId)); |
|
93 } |
|
94 |
|
95 /** |
|
96 Framework function |
|
97 @see CBaBackupServer::CompleteClosingFiles(CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles) |
|
98 */ |
|
99 void CEikServBackupServer::CompleteClosingFiles(CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles) |
|
100 { |
|
101 delete iAppStarter; |
|
102 iAppStarter=NULL; |
|
103 TRAPD(err,iAppStarter=CAppStarter::NewL(*this,aClosedFiles)); |
|
104 if (err!=KErrNone) |
|
105 { |
|
106 SetBusy(0); |
|
107 } |
|
108 } |
|
109 |
|
110 /** |
|
111 Framework function |
|
112 @see CServer2:;::NewSessionL(const TVersion &aVersion, const RMessage2&) |
|
113 */ |
|
114 CSession2* CEikServBackupServer::NewSessionL(const TVersion &aVersion, const RMessage2&) const |
|
115 { |
|
116 const TVersion version(KBakServMajorVN,KBakServMinorVN,KBakServBuildVN); |
|
117 if (!User::QueryVersionSupported(version,aVersion)) |
|
118 { |
|
119 User::Leave(KErrNotSupported); |
|
120 } |
|
121 return CEikServBackupSession::NewL(); |
|
122 } |
|
123 |
|
124 /** |
|
125 Framework Function |
|
126 @see MAppStarterObserver::HandleAppsStarted() |
|
127 */ |
|
128 void CEikServBackupServer::HandleAppsStarted() |
|
129 { |
|
130 SetBusy(0); |
|
131 delete iAppStarter; |
|
132 iAppStarter=NULL; |
|
133 } |
|
134 |
|
135 |
|
136 |
|
137 // |
|
138 // class CAppWatcher |
|
139 // |
|
140 |
|
141 |
|
142 /** |
|
143 Static factory function |
|
144 @param aThreadId - Of application to watch |
|
145 @param aAppShutter - Called when watcher (this) sees app close. |
|
146 @param aClosedFile - file that will need restarting |
|
147 @return Instantiated and constructed object |
|
148 @internalTechnology |
|
149 */ |
|
150 CAppWatcher* CAppWatcher::NewL(TThreadId aThreadId,CAppShutter& aAppShutter, |
|
151 const CEikServBackupSession::TClosedFile& aClosedFile) |
|
152 { // static |
|
153 CAppWatcher* self=new(ELeave) CAppWatcher(aAppShutter,aClosedFile); |
|
154 CleanupStack::PushL(self); |
|
155 self->ConstructL(aThreadId); |
|
156 CleanupStack::Pop(); // self |
|
157 return self; |
|
158 } |
|
159 |
|
160 /** |
|
161 Destructor |
|
162 */ |
|
163 CAppWatcher::~CAppWatcher() |
|
164 { |
|
165 Cancel(); |
|
166 iThread.Close(); |
|
167 } |
|
168 |
|
169 /** |
|
170 @return Copy of the closed file |
|
171 @internalTechnology |
|
172 @see CEikServBackupSession::TClosedFile |
|
173 */ |
|
174 const CEikServBackupSession::TClosedFile& CAppWatcher::Info() const |
|
175 { |
|
176 return iClosedFile; |
|
177 } |
|
178 |
|
179 /** |
|
180 Private constructor |
|
181 @param aAppShutter - called when watcher (this) sees app close. |
|
182 @param aClosedFile- the file that will need restarting |
|
183 @internalComponent |
|
184 */ |
|
185 CAppWatcher::CAppWatcher(CAppShutter& aAppShutter,const CEikServBackupSession::TClosedFile& aClosedFile) |
|
186 : CActive(CActive::EPriorityStandard), iAppShutter(aAppShutter), iClosedFile(aClosedFile) |
|
187 {} |
|
188 |
|
189 |
|
190 /** |
|
191 Second phase constructor |
|
192 Logs on to thread to wait for application to close. |
|
193 @param aThreadId |
|
194 @internalComponent |
|
195 */ |
|
196 void CAppWatcher::ConstructL(TThreadId aThreadId) |
|
197 { |
|
198 CActiveScheduler::Add(this); |
|
199 iStatus=KRequestPending; |
|
200 SetActive(); |
|
201 User::LeaveIfError(iThread.Open(aThreadId)); |
|
202 iThread.Logon(iStatus); |
|
203 } |
|
204 |
|
205 /** |
|
206 CActive framework function |
|
207 Cancels thread logon |
|
208 */ |
|
209 void CAppWatcher::DoCancel() |
|
210 { |
|
211 if (iThread.Id() && iStatus==KRequestPending) |
|
212 { |
|
213 iThread.LogonCancel(iStatus); |
|
214 } |
|
215 } |
|
216 |
|
217 /** |
|
218 CActive framework function |
|
219 Handles application closure. Calls App shutter |
|
220 */ |
|
221 void CAppWatcher::RunL() |
|
222 { |
|
223 iAppShutter.HandleAppClosedL(iClosedFile); |
|
224 } |
|
225 |
|
226 /** |
|
227 CActive framework function |
|
228 */ |
|
229 TInt CAppWatcher::RunError(TInt /*aError*/) |
|
230 { |
|
231 delete this; |
|
232 return KErrNone; |
|
233 } |
|
234 |
|
235 // |
|
236 // class CAppShutter |
|
237 // |
|
238 |
|
239 /** |
|
240 @internalComponent |
|
241 */ |
|
242 CAppShutter::CShutterTimer* CAppShutter::CShutterTimer::NewL(TInt aPriority) |
|
243 { // static |
|
244 CShutterTimer* self=new(ELeave) CShutterTimer(aPriority); |
|
245 CleanupStack::PushL(self); |
|
246 self->ConstructL(); |
|
247 CleanupStack::Pop(); // self |
|
248 CActiveScheduler::Add(self); |
|
249 return self; |
|
250 } |
|
251 /** |
|
252 @internalComponent |
|
253 */ |
|
254 TInt CAppShutter::CShutterTimer::RunError(TInt aError) |
|
255 { |
|
256 if (aError==KLeaveWithoutAlert) |
|
257 { |
|
258 return KErrNone; |
|
259 } |
|
260 return aError; |
|
261 } |
|
262 |
|
263 /** |
|
264 @internalComponent |
|
265 */ |
|
266 CAppShutter::CShutterTimer::CShutterTimer(TInt aPriority) |
|
267 : CPeriodic(aPriority) |
|
268 {} |
|
269 |
|
270 /** |
|
271 @internalTechnology |
|
272 */ |
|
273 CAppShutter* CAppShutter::StartL(MAppShutterObserver& aObserver, |
|
274 CArrayFix<CEikServBackupSession::TClosedFile>& aClosedFiles, |
|
275 CBaBackupServer& aBackupServer) |
|
276 { // static |
|
277 CAppShutter* self=new(ELeave) CAppShutter(aObserver,aClosedFiles, aBackupServer); |
|
278 CleanupStack::PushL(self); |
|
279 self->ConstructL(); |
|
280 CleanupStack::Pop(); // self |
|
281 return self; |
|
282 } |
|
283 |
|
284 /** |
|
285 @internalComponent |
|
286 */ |
|
287 CAppShutter::~CAppShutter() |
|
288 { |
|
289 if (iAppWatchers) |
|
290 { |
|
291 iAppWatchers->ResetAndDestroy(); |
|
292 delete iAppWatchers; |
|
293 } |
|
294 delete iTimer; |
|
295 delete iWgIds; |
|
296 iWsSession.Close(); |
|
297 } |
|
298 |
|
299 |
|
300 /** |
|
301 @internalComponent |
|
302 */ |
|
303 CAppShutter::CAppShutter(MAppShutterObserver& aObserver, |
|
304 CArrayFix<CEikServBackupSession::TClosedFile>& aClosedFiles, |
|
305 CBaBackupServer& aBackupServer) |
|
306 : iObserver(aObserver),iClosedFiles(aClosedFiles), iBackupServer(aBackupServer) |
|
307 |
|
308 |
|
309 {} |
|
310 |
|
311 /** |
|
312 @internalComponent |
|
313 */ |
|
314 void CAppShutter::ConstructL() |
|
315 { |
|
316 iTimer=CShutterTimer::NewL(CActive::EPriorityStandard); |
|
317 iTimer->Start(0,1,TCallBack(TimerCallBackL,this)); |
|
318 iAppWatchers=new(ELeave) CArrayPtrFlat<CAppWatcher>(1); |
|
319 User::LeaveIfError(iWsSession.Connect()); |
|
320 const TInt wgCount=iWsSession.NumWindowGroups(0); |
|
321 iWgIds=new(ELeave) RArray<RWsSession::TWindowGroupChainInfo>(wgCount); |
|
322 User::LeaveIfError(iWsSession.WindowGroupList(0,iWgIds)); |
|
323 } |
|
324 |
|
325 /** |
|
326 @internalTechnology |
|
327 */ |
|
328 void CAppShutter::HandleAppClosedL(const CEikServBackupSession::TClosedFile& aClosedFile) |
|
329 { |
|
330 const TInt count=iAppWatchers->Count(); |
|
331 for (TInt ii=0;ii<count;ii++) |
|
332 { |
|
333 CAppWatcher* watcher=(*iAppWatchers)[ii]; |
|
334 if (watcher->Info()==aClosedFile) |
|
335 { |
|
336 iAppWatchers->Delete(ii); |
|
337 NextL(); |
|
338 delete watcher; |
|
339 break; |
|
340 } |
|
341 } |
|
342 } |
|
343 |
|
344 /** |
|
345 @internalComponent |
|
346 */ |
|
347 TInt CAppShutter::TimerCallBackL(TAny* aPtr) |
|
348 { // static |
|
349 REINTERPRET_CAST(CAppShutter*,aPtr)->HandleTimerCallBackL(); |
|
350 return 0; |
|
351 } |
|
352 |
|
353 /** |
|
354 @internalComponent |
|
355 */ |
|
356 void CAppShutter::HandleTimerCallBackL() |
|
357 { |
|
358 NextL(); |
|
359 } |
|
360 |
|
361 /** |
|
362 @internalComponent |
|
363 */ |
|
364 void CAppShutter::NextL() |
|
365 { |
|
366 if (iNextWgIndex==iWgIds->Count()) |
|
367 { |
|
368 CheckCompleteL(); |
|
369 } |
|
370 else |
|
371 { |
|
372 const RWsSession::TWindowGroupChainInfo wgId=(*iWgIds)[iNextWgIndex++]; |
|
373 CApaWindowGroupName* wgName=CApaWindowGroupName::NewLC(iWsSession,wgId.iId); |
|
374 if (!IsWgIdValid(wgId.iId) || wgName->IsSystem() || wgName->Hidden()) |
|
375 { |
|
376 NextL(); |
|
377 } |
|
378 else |
|
379 { |
|
380 TPtrC docName=wgName->DocName(); |
|
381 CEikServBackupSession::TClosedFile data; |
|
382 if (docName.Length()) |
|
383 { |
|
384 data.iDocName=docName; |
|
385 } |
|
386 data.iUid=wgName->AppUid(); |
|
387 // We don't want to restart server apps |
|
388 if (wgId.iParentId <= 0) |
|
389 { |
|
390 iClosedFiles.AppendL(data); |
|
391 } |
|
392 TThreadId threadId; |
|
393 User::LeaveIfError(iWsSession.GetWindowGroupClientThreadId(wgId.iId,threadId)); |
|
394 CAppWatcher* watcher=CAppWatcher::NewL(threadId,*this,data); |
|
395 CleanupStack::PushL(watcher); |
|
396 iAppWatchers->AppendL(watcher); |
|
397 CleanupStack::Pop(); // watcher |
|
398 TApaTask task(iWsSession); |
|
399 task.SetWgId(wgId.iId); |
|
400 task.SendSystemEvent(EApaSystemEventShutdown); |
|
401 if (iTimer->IsActive()) |
|
402 { |
|
403 iTimer->Cancel(); |
|
404 } |
|
405 // If hardware use patchable constant if not default to 5 seconds |
|
406 iTimer->Start(KUIKONBackupCloseAllFilesTimeout,KUIKONBackupCloseAllFilesTimeout,TCallBack(TimerCallBackL,this)); |
|
407 } |
|
408 CleanupStack::PopAndDestroy(); // wgName |
|
409 } |
|
410 } |
|
411 |
|
412 /** |
|
413 @internalComponent |
|
414 */ |
|
415 TBool CAppShutter::IsWgIdValid(TInt aWgId) |
|
416 { |
|
417 TBuf<600> name; |
|
418 const TInt r=iWsSession.GetWindowGroupNameFromIdentifier(aWgId,name); |
|
419 return r==KErrNone; |
|
420 } |
|
421 |
|
422 /** |
|
423 @internalComponent |
|
424 */ |
|
425 void CAppShutter::CheckCompleteL() |
|
426 { |
|
427 // see if any new window groups exist. If they do, add them to the end of iWgIds and go back to NextL |
|
428 const TInt wgCount=iWsSession.NumWindowGroups(0); |
|
429 RArray<RWsSession::TWindowGroupChainInfo>* wgIds=new(ELeave) RArray<RWsSession::TWindowGroupChainInfo>(wgCount); |
|
430 CleanupStack::PushL(wgIds); |
|
431 User::LeaveIfError(iWsSession.WindowGroupList(0,wgIds)); |
|
432 TBool foundNewWg=EFalse; |
|
433 for (TInt ii=0;ii<wgCount;ii++) |
|
434 { |
|
435 if (iWgIds->Find((*wgIds)[ii])<0) |
|
436 { |
|
437 iWgIds->AppendL((*wgIds)[ii]); |
|
438 foundNewWg=ETrue; |
|
439 } |
|
440 } |
|
441 CleanupStack::PopAndDestroy(); // wgIds |
|
442 if (foundNewWg) |
|
443 { |
|
444 NextL(); |
|
445 } |
|
446 else // if iAppWatchers is non-empty then some tasks are still closing. Give them up to 5 seconds to terminate |
|
447 { |
|
448 // Check all files that have been registered for file lock notifications have been updated |
|
449 TBool filesAllLocked = iBackupServer.HaveAllCloseAllFilesClientsReRegistered(); |
|
450 |
|
451 // If all registered files are locked and all app watchers are done we can proceed |
|
452 if ((filesAllLocked && (iAppWatchers->Count() == 0)) || (iCheckCount == 3)) |
|
453 { |
|
454 const TBool allAppsClosed=(iAppWatchers->Count()==0); |
|
455 iObserver.HandleAppsClosedL(allAppsClosed); |
|
456 } |
|
457 else |
|
458 { |
|
459 iCheckCount++; |
|
460 if (iTimer->IsActive()) |
|
461 { |
|
462 iTimer->Cancel(); |
|
463 } |
|
464 // If hardware use patchable constant if not default to 5 seconds |
|
465 iTimer->Start(KUIKONBackupCloseAllFilesTimeout,KUIKONBackupCloseAllFilesTimeout,TCallBack(TimerCallBackL,this)); |
|
466 |
|
467 } |
|
468 } |
|
469 } |
|
470 |
|
471 // |
|
472 // class CEikServAppShutter |
|
473 // |
|
474 |
|
475 /** |
|
476 @internalTechnology |
|
477 */ |
|
478 CEikServAppShutter::CEikServAppShutter(const RMessage2& aMessage) |
|
479 : iMessage(aMessage) |
|
480 {} |
|
481 |
|
482 /** |
|
483 @internalTechnology |
|
484 */ |
|
485 void CEikServAppShutter::ConstructL(MAppShutterObserver& aObserver, |
|
486 CArrayFix<CEikServBackupSession::TClosedFile>& aClosedFiles, |
|
487 CBaBackupServer* aBackupServer) |
|
488 { |
|
489 iShutter=CAppShutter::StartL(aObserver,aClosedFiles, *aBackupServer); |
|
490 } |
|
491 /** |
|
492 @internalTechnology |
|
493 */ |
|
494 CEikServAppShutter::~CEikServAppShutter() |
|
495 { |
|
496 delete iShutter; |
|
497 } |
|
498 |
|
499 /** |
|
500 @internalTechnology |
|
501 */ |
|
502 const RMessage2& CEikServAppShutter::Message() const |
|
503 { |
|
504 return iMessage; |
|
505 } |
|
506 |
|
507 |
|
508 // |
|
509 // class CEikServBackupSession |
|
510 // |
|
511 |
|
512 |
|
513 /** |
|
514 Static factory function |
|
515 @return Instantiated and constructed object. |
|
516 @internalTechnology |
|
517 */ |
|
518 CEikServBackupSession* CEikServBackupSession::NewL() |
|
519 { // static |
|
520 CEikServBackupSession* self=new(ELeave) CEikServBackupSession(); |
|
521 CleanupStack::PushL(self); |
|
522 self->ConstructL(); |
|
523 CleanupStack::Pop(self); |
|
524 return self; |
|
525 } |
|
526 |
|
527 /** |
|
528 @internalTechnology |
|
529 */ |
|
530 CEikServBackupSession::~CEikServBackupSession() |
|
531 { |
|
532 } |
|
533 |
|
534 /** |
|
535 Framework function |
|
536 @see CBaBackupServerSession::HandleError( Tint aError ) |
|
537 */ |
|
538 void CEikServBackupSession::HandleError(TInt aError) |
|
539 { |
|
540 if (iAppShutter) |
|
541 { |
|
542 BackupServer()->SetCloseAllOperationRunningState(EFalse); |
|
543 iAppShutter->Message().Complete(aError); |
|
544 delete iAppShutter; |
|
545 iAppShutter=NULL; |
|
546 CBaServBackupScheduler::Current()->SetErrorHandler(NULL); |
|
547 } |
|
548 else |
|
549 { |
|
550 CBaServBackupSession::HandleError(aError); |
|
551 } |
|
552 } |
|
553 |
|
554 /** |
|
555 @internalComponent |
|
556 */ |
|
557 void CEikServBackupSession::ServiceL(const RMessage2& aMessage) |
|
558 { |
|
559 CBaServBackupSession::ServiceL(aMessage); |
|
560 } |
|
561 |
|
562 /** |
|
563 @internalComponent |
|
564 */ |
|
565 void CEikServBackupSession::ServiceError(const RMessage2& aMessage,TInt aError) |
|
566 { |
|
567 if (!aMessage.IsNull()) |
|
568 { |
|
569 aMessage.Complete(aError); |
|
570 } |
|
571 } |
|
572 |
|
573 /** |
|
574 Framework function |
|
575 @see MAppShutterObserver::HandleAppsClosedL(TBool aAllAppsClosed) |
|
576 */ |
|
577 void CEikServBackupSession::HandleAppsClosedL(TBool aAllAppsClosed) |
|
578 { |
|
579 if (iAppShutter) |
|
580 { |
|
581 // End the CloseAll period |
|
582 BackupServer()->SetCloseAllOperationRunningState(EFalse); |
|
583 const TInt err=(aAllAppsClosed? KErrNone : KErrInUse); |
|
584 iAppShutter->Message().Complete(err); |
|
585 delete iAppShutter; |
|
586 iAppShutter=NULL; |
|
587 } |
|
588 } |
|
589 |
|
590 /** |
|
591 Used as TCleanupItem. |
|
592 @internalComponent |
|
593 */ |
|
594 void CEikServBackupSession::CleanupCloseAllFiles(TAny* aPtr) |
|
595 { // static |
|
596 CEikServBackupSession* self=REINTERPRET_CAST(CEikServBackupSession*,aPtr); |
|
597 delete self->iAppShutter; |
|
598 self->iAppShutter=NULL; |
|
599 } |
|
600 |
|
601 |
|
602 /** |
|
603 Framework function |
|
604 @see CBaBackupServerSession::CloseAllFilesL(const RMessage2& aMessage) |
|
605 */ |
|
606 TCompletionType CEikServBackupSession::CloseAllFilesL(const RMessage2& aMessage) |
|
607 { |
|
608 CBaServBackupSession::DoCloseAllFilesL(aMessage); |
|
609 CEikServBackupServer* server=static_cast<CEikServBackupServer*>(BackupServer()); |
|
610 CleanupStack::PushL(TCleanupItem(CleanupCloseAllFiles,this)); |
|
611 __ASSERT_DEBUG(iAppShutter == NULL, PanicClientL(aMessage,EBadInternalState)); |
|
612 iAppShutter=new(ELeave) CEikServAppShutter(aMessage); |
|
613 if(!ClosedFiles()) |
|
614 { |
|
615 CArrayFixSeg<CBaServBackupSession::TClosedFile>* closedFiles=new(ELeave) CArrayFixSeg<CBaServBackupSession::TClosedFile>(1); |
|
616 SetClosedFiles(closedFiles); |
|
617 } |
|
618 iAppShutter->ConstructL(*this,*ClosedFiles(), (CBaBackupServer*)BackupServer() ); |
|
619 CleanupStack::Pop(); // CleanupCloseAllFiles |
|
620 return ECompleteAsync; |
|
621 } |
|
622 |
|
623 /** |
|
624 Framework function |
|
625 @see CBaBackupServerSession::RestartAll() |
|
626 */ |
|
627 void CEikServBackupSession::RestartAll() |
|
628 { |
|
629 CBaBackupServer* server=BackupServer(); |
|
630 if (server->IsClientBusy(UniqueClientId())) |
|
631 { |
|
632 if (iAppShutter) |
|
633 { |
|
634 BackupServer()->SetCloseAllOperationRunningState(EFalse); |
|
635 iAppShutter->Message().Complete(KErrCancel); |
|
636 delete iAppShutter; |
|
637 iAppShutter=NULL; |
|
638 } |
|
639 CBaServBackupSession::RestartAll(); |
|
640 } |
|
641 } |
|
642 |
|
643 |
|
644 /** |
|
645 @internalComponent |
|
646 */ |
|
647 void CEikServBackupSession::PanicClientL(const RMessage2& aMessage, TEikBackupServPanic aCode) |
|
648 { |
|
649 _LIT(KPanicCat,"BackupSrv"); |
|
650 aMessage.Panic(KPanicCat,aCode); |
|
651 User::Leave(KLeaveWithoutAlert); |
|
652 } |
|
653 |
|
654 |
|
655 |
|
656 // |
|
657 // class CAppStarter |
|
658 // |
|
659 |
|
660 const TInt KAppStarterTimerGranularity=100000; // 0.1s |
|
661 _LIT(KThreadName,"AppStarterThread"); |
|
662 |
|
663 /** |
|
664 Static factory function |
|
665 @param aObserver Applications starter observer |
|
666 @param aClosedFiles A list of the files closed for backing up (i.e. which need re-starting) |
|
667 @return instantiated and constructed App Starter |
|
668 @internalTechnology |
|
669 */ |
|
670 CAppStarter* CAppStarter::NewL(MAppStarterObserver& aObserver,CArrayFix<CEikServBackupSession::TClosedFile>* aClosedFiles) |
|
671 { // static |
|
672 CleanupStack::PushL(aClosedFiles); |
|
673 CAppStarter* self=new(ELeave) CAppStarter(aObserver,aClosedFiles); |
|
674 CleanupStack::Pop(); // aClosedFiles |
|
675 CleanupStack::PushL(self); |
|
676 self->ConstructL(); |
|
677 CleanupStack::Pop(); // self |
|
678 return self; |
|
679 } |
|
680 |
|
681 /** |
|
682 destructor |
|
683 */ |
|
684 CAppStarter::~CAppStarter() |
|
685 {// Cancel any outstanding request before cleanup |
|
686 Cancel(); // Calls DoCancel() |
|
687 delete iClosedFiles; |
|
688 } |
|
689 |
|
690 /** |
|
691 Constructor |
|
692 @param aObserver Startup observer |
|
693 @param aClosedFiles A list of the files closed for backing up (i.e. which need re-starting) |
|
694 @internalComponent |
|
695 */ |
|
696 CAppStarter::CAppStarter(MAppStarterObserver& aObserver, CArrayFix<CEikServBackupSession::TClosedFile>* aClosedFiles) |
|
697 : CActive(EPriorityStandard), iObserver(aObserver), iClosedFiles(aClosedFiles) |
|
698 { |
|
699 CActiveScheduler::Add(this); |
|
700 } |
|
701 |
|
702 /** |
|
703 2nd phase constructor. |
|
704 This function creates a separate thread which is used to run StartAppsL() synchronously. |
|
705 A static fuction - ThreadEntryPoint() - is called to call StartAppsL() on 'this'. |
|
706 @internalComponent |
|
707 */ |
|
708 void CAppStarter::ConstructL() |
|
709 { |
|
710 if (IsActive()) |
|
711 { |
|
712 return; |
|
713 } |
|
714 |
|
715 TInt res = iThread.Create(KThreadName, |
|
716 ThreadEntryPoint, |
|
717 KDefaultStackSize, |
|
718 NULL, |
|
719 this); |
|
720 |
|
721 if(KErrNone==res) |
|
722 {// set ourselves to KRequestPending, set active, resume new thread (to make synchronous call) |
|
723 iStatus = KRequestPending; |
|
724 SetActive(); |
|
725 iThread.Logon(iStatus); // Request notification when thread dies |
|
726 iThread.Resume(); // Start the thread |
|
727 } |
|
728 } |
|
729 |
|
730 /** |
|
731 This function is excuted synchronously in a separate thread |
|
732 Each of the closed files passed in during construction is restarted. |
|
733 @internalComponent |
|
734 */ |
|
735 void CAppStarter::StartAppsL() |
|
736 {// synchronous call executed in thread |
|
737 |
|
738 RApaLsSession apaSession; |
|
739 User::LeaveIfError(apaSession.Connect()); |
|
740 CleanupClosePushL(apaSession); |
|
741 RWsSession wsSession; |
|
742 User::LeaveIfError(wsSession.Connect()); |
|
743 CleanupClosePushL(wsSession); |
|
744 |
|
745 |
|
746 do { |
|
747 const TInt count=iClosedFiles->Count(); |
|
748 if (count!=0) |
|
749 { |
|
750 CEikServBackupSession::TClosedFile& item=(*iClosedFiles)[count-1]; |
|
751 TInt wgId=0; |
|
752 CApaCommandLine* cmdLine=CApaCommandLine::NewLC(); |
|
753 if (item.iDocName.Length()>0) |
|
754 { |
|
755 CApaWindowGroupName::FindByDocName(item.iDocName,wsSession,wgId); |
|
756 cmdLine->SetDocumentNameL(item.iDocName); |
|
757 } |
|
758 else |
|
759 { |
|
760 CApaWindowGroupName::FindByAppUid(item.iUid,wsSession,wgId); |
|
761 } |
|
762 |
|
763 if (wgId==KErrNotFound) |
|
764 { |
|
765 cmdLine->SetCommandL(EApaCommandBackground); |
|
766 TApaAppInfo info; |
|
767 User::LeaveIfError(apaSession.GetAppInfo(info, item.iUid)); |
|
768 cmdLine->SetExecutableNameL(info.iFullName); |
|
769 apaSession.StartApp(*cmdLine); // ignore the error, we can't do anything useful in response |
|
770 } |
|
771 CleanupStack::PopAndDestroy(1); // cmdLine |
|
772 } |
|
773 |
|
774 if (count<=1) |
|
775 { |
|
776 break;//loop termination condition |
|
777 } |
|
778 else |
|
779 { |
|
780 iClosedFiles->Delete(count-1); |
|
781 User::After(KAppStarterTimerGranularity);// force thread to sleep |
|
782 } |
|
783 |
|
784 } while(1); |
|
785 |
|
786 CleanupStack::PopAndDestroy(2); // apaSession & wsSession |
|
787 } |
|
788 |
|
789 /** |
|
790 Static function used to run StartAppsL() in separate thread. |
|
791 Thread is terminated on completion |
|
792 @param aParams 'this' pointer to CAppStarter |
|
793 @return Is ignored |
|
794 */ |
|
795 TInt CAppStarter::ThreadEntryPoint(TAny* aParams) |
|
796 {// perform apps startup |
|
797 |
|
798 //CleanupStack for this thread |
|
799 CTrapCleanup* theCleanupStack = CTrapCleanup::New(); |
|
800 CAppStarter* appStarter = NULL; |
|
801 appStarter = static_cast<CAppStarter*>(aParams); |
|
802 TInt err = KErrNone; |
|
803 if(appStarter) |
|
804 { |
|
805 TRAP(err, appStarter->StartAppsL());//synchronous call |
|
806 } |
|
807 delete theCleanupStack; |
|
808 |
|
809 // Task complete so end this thread |
|
810 RThread().Kill(err);// err value can be retrieved via 'ExitReason()' in CAppStarter::RunL() |
|
811 return (KErrNone); //value discarded |
|
812 } |
|
813 |
|
814 /** |
|
815 Kills (other) thread if necessary |
|
816 CActive framework function |
|
817 */ |
|
818 void CAppStarter::DoCancel() |
|
819 { |
|
820 TExitType threadExitType = iThread.ExitType(); |
|
821 if(EExitPending==threadExitType) |
|
822 {//thread still running |
|
823 iThread.LogonCancel(iStatus);//cancel outstanding notification request |
|
824 iThread.Kill(KErrCancel); |
|
825 iThread.Close(); |
|
826 } |
|
827 } |
|
828 |
|
829 /** |
|
830 Closes (other) thread. Kills it if necessary. |
|
831 Signals to observer that task is complete. |
|
832 CActive framework function. |
|
833 */ |
|
834 void CAppStarter::RunL() |
|
835 {// check in case thread is still running e.g. if Logon() failed |
|
836 TExitType threadExitType = iThread.ExitType(); |
|
837 if(EExitPending==threadExitType) // Thread still running - kill it |
|
838 { |
|
839 iThread.Kill(KErrNone); |
|
840 } |
|
841 |
|
842 iThread.Close();// close thread handle |
|
843 iObserver.HandleAppsStarted();// calls delete on this active object |
|
844 } |
|
845 |
|
846 // |
|
847 // Main |
|
848 // |
|
849 |