commonuisupport/uikon/srvsrc/EIKBAKSV.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     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