memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp
changeset 34 7259cf1302ad
parent 22 a009639409f5
equal deleted inserted replaced
33:0d72cc2a29a3 34:7259cf1302ad
    40 #include <memspy/engine/memspyenginehelperram.h>
    40 #include <memspy/engine/memspyenginehelperram.h>
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    42 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    42 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    43 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    43 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    44 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
    44 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
       
    45 #include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
       
    46 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
    45 
    47 
    46 #include <memspy/engine/memspyprocessdata.h>
    48 #include <memspy/engine/memspyprocessdata.h>
    47 #include <memspy/engine/memspythreaddata.h>
    49 #include <memspy/engine/memspythreaddata.h>
    48 #include <memspy/engine/memspykernelobjectdata.h>
    50 #include <memspy/engine/memspykernelobjectdata.h>
    49 #include <memspy/engine/memspythreadinfoitemdata.h>
    51 #include <memspy/engine/memspythreadinfoitemdata.h>
    50 
    52 #include <memspy/engine/memspymemorytrackingcycledata.h>
       
    53 #include <memspy/engine/memspyengineoutputsink.h>
       
    54 #include <memspy/engine/memspyenginehelperactiveobject.h>
       
    55 
       
    56 inline CShutdown::CShutdown() :CTimer(-1)
       
    57     {
       
    58     CActiveScheduler::Add(this);
       
    59     }
       
    60 
       
    61 inline void CShutdown::ConstructL()
       
    62     {
       
    63     CTimer::ConstructL();
       
    64     }
       
    65 
       
    66 inline void CShutdown::Start()
       
    67     {
       
    68     After(KMyShutdownDelay);
       
    69     }
       
    70 
       
    71 void CShutdown::RunL()
       
    72     //
       
    73     // Initiate server exit when the timer expires
       
    74     //
       
    75     {
       
    76     CActiveScheduler::Stop();
       
    77     }
    51 
    78 
    52 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    79 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    53 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    80 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    54     {
    81     {
    55     }
    82     }
    61 
    88 
    62 
    89 
    63 void CMemSpyEngineServer::ConstructL()
    90 void CMemSpyEngineServer::ConstructL()
    64     {
    91     {
    65     StartL( KMemSpyServerName );
    92     StartL( KMemSpyServerName );
       
    93     
       
    94     iShutdown.ConstructL();
       
    95     // ensure that the server still exits even if the 1st client fails to connect
       
    96     iShutdown.Start();
    66     }
    97     }
    67 
    98 
    68 
    99 
    69 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
   100 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
    70     {
   101     {
    86     //
   117     //
    87     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
   118     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
    88 	return session;
   119 	return session;
    89     }
   120     }
    90 
   121 
       
   122 void CMemSpyEngineServer::AddSession(TBool aCliRequest)
       
   123     {
       
   124     if (aCliRequest)
       
   125         {
       
   126         iCliConnected = ETrue;
       
   127         }
       
   128     else
       
   129         {
       
   130         ++iSessionCount;
       
   131         }
       
   132     iShutdown.Cancel();
       
   133     }
       
   134 
       
   135 void CMemSpyEngineServer::DropSession(TBool aCliRequest)
       
   136     {
       
   137     if (!aCliRequest)
       
   138         {
       
   139         --iSessionCount;
       
   140         }
       
   141     
       
   142     if (iSessionCount == 0 && !iCliConnected)
       
   143         {
       
   144         iShutdown.Start();
       
   145         }
       
   146     }
       
   147 
       
   148 
       
   149 
    91 
   150 
    92 
   151 
    93 
   152 
    94 
   153 
    95 
   154 
   127 
   186 
   128     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   187     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   129 #endif
   188 #endif
   130 
   189 
   131     delete iClientThreadName;
   190     delete iClientThreadName;
       
   191     
       
   192     Server().DropSession(iIsCliRequest);
   132     }
   193     }
   133 
   194 
   134 
   195 
   135 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   196 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   136     {
   197     {
   145     const TFullName threadName( thread.FullName() );
   206     const TFullName threadName( thread.FullName() );
   146     iClientThreadName = threadName.AllocL();
   207     iClientThreadName = threadName.AllocL();
   147     iClientThreadId = thread.Id();
   208     iClientThreadId = thread.Id();
   148 
   209 
   149     CleanupStack::PopAndDestroy( &thread );
   210     CleanupStack::PopAndDestroy( &thread );
   150 
   211     
       
   212     const TUid KCliUid3 = { 0x2002129D };
       
   213     iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3);
       
   214     
   151     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   215     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   152     }
   216     }
   153 
   217 
       
   218 void CMemSpyEngineSession::CreateL()
       
   219     {   
       
   220     Server().AddSession(iIsCliRequest);
       
   221     }
   154 
   222 
   155 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   223 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   156     {
   224     {
   157     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   225     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   158     CleanupStack::PushL( self );
   226     CleanupStack::PushL( self );
   169     TRAPD( error, DoServiceL( aMessage ) );
   237     TRAPD( error, DoServiceL( aMessage ) );
   170     if  ( error != KErrNone )
   238     if  ( error != KErrNone )
   171         {
   239         {
   172         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   240         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   173         }
   241         }
   174     aMessage.Complete( error );
   242     
       
   243     if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone)
       
   244     	{
       
   245 		aMessage.Complete( error );
       
   246     	}
   175 
   247 
   176     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   248     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   177 	}
   249 	}
   178 
   250 
   179 // ---------------------------------------------------------
   251 // ---------------------------------------------------------
   188 		
   260 		
   189 		DoUiServiceL(aMessage);
   261 		DoUiServiceL(aMessage);
   190 	else
   262 	else
   191 		DoCmdServiceL(aMessage);
   263 		DoCmdServiceL(aMessage);
   192 	}
   264 	}
   193 
       
   194 // ---------------------------------------------------------
   265 // ---------------------------------------------------------
   195 // DoUiServiceL( const RMessage2& aMessage )
   266 // DoUiServiceL( const RMessage2& aMessage )
   196 // ---------------------------------------------------------
   267 // ---------------------------------------------------------
   197 //
   268 //
   198 void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
   269 void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
   214 			
   285 			
   215 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
   286 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
   216 				{
   287 				{
   217 				CMemSpyProcess& process = iEngine.Container().At(i);
   288 				CMemSpyProcess& process = iEngine.Container().At(i);
   218 				TMemSpyProcessData data;
   289 				TMemSpyProcessData data;
       
   290 				data.iIsDead = process.IsDead();
   219 				data.iId = process.Id();
   291 				data.iId = process.Id();
   220 				data.iName.Copy(process.Name());
   292 				data.iName.Copy(process.Name().Left(KMaxFullName));
       
   293 				data.iThreadCount = process.Count();
       
   294 				data.iPriority = process.Priority();
       
   295 				data.iExitType = process.ExitType();
       
   296 				data.iExitReason = process.ExitReason();
       
   297 				data.iExitCategory = process.ExitCategory();
       
   298 				data.iSID = process.SID();
   221 				
   299 				
   222 				TPckgBuf<TMemSpyProcessData> buffer(data);
   300 				TPckgBuf<TMemSpyProcessData> buffer(data);
   223 				aMessage.WriteL(1, buffer, offset);
   301 				aMessage.WriteL(1, buffer, offset);
   224 				}
   302 				}
   225 			
   303 			
   226 			a0 = list.Count();
   304 			a0 = list.Count();
   227 			aMessage.WriteL(0, a0);
   305 			aMessage.WriteL(0, a0);
   228 	
   306 
   229 			break;
   307 			break;
   230 			}
   308 			}
   231 		case EMemSpyClienServerOpGetProcessIdByName:
   309 		case EMemSpyClienServerOpGetProcessIdByName:
   232 			{
   310 			{
   233 			TFullName processName;
   311 			TFullName processName;
   260 			aMessage.ReadL( 0, id );
   338 			aMessage.ReadL( 0, id );
   261 			
   339 			
   262 			CMemSpyEngineObjectContainer& container = iEngine.Container();
   340 			CMemSpyEngineObjectContainer& container = iEngine.Container();
   263 			CMemSpyProcess& process = container.ProcessByIdL( id() );
   341 			CMemSpyProcess& process = container.ProcessByIdL( id() );
   264 			
   342 			
   265 			process.Open();
       
   266 	
       
   267 			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
   343 			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
   268 				{
   344 				{
   269 				ret = ETrue;
   345 				ret = ETrue;
   270 				}
   346 				}
   271 			TPckgBuf<TBool> retBuf( ret );
   347 			TPckgBuf<TBool> retBuf( ret );
   355 		case EMemSpyClientServerOpGetThreadCount:
   431 		case EMemSpyClientServerOpGetThreadCount:
   356 			{
   432 			{
   357 			TPckgBuf<TProcessId> pid;
   433 			TPckgBuf<TProcessId> pid;
   358 			aMessage.ReadL(1, pid);
   434 			aMessage.ReadL(1, pid);
   359 			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
   435 			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
   360 			process.Open();
       
   361 			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
   436 			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
   362 			process.Close();
       
   363 			break;
   437 			break;
   364 			}
   438 			}
   365 		case EMemSpyClientServerOpGetThreads:
   439 		case EMemSpyClientServerOpGetThreads:
   366 			{
   440 			{
   367 			TPckgBuf<TProcessId> pid;
   441 			TPckgBuf<TProcessId> pid;
   368 			aMessage.ReadL(2, pid);
   442 			aMessage.ReadL(2, pid);
   369 			
   443 			
   370 			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
   444 			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
   371 			list.Open();
       
   372 			
   445 			
   373 			TPckgBuf<TInt> a0;
   446 			TPckgBuf<TInt> a0;
   374 			aMessage.ReadL(0, a0);
   447 			aMessage.ReadL(0, a0);
   375 			TInt realCount = Min(a0(), list.Count());
   448 			TInt realCount = Min(a0(), list.Count());
   376 			
   449 						
   377 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
   450 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
   378 				{
   451 				{
   379 				CMemSpyThread& thread = list.At(i);
   452 				CMemSpyThread& thread = list.At(i);
   380 				thread.Open();
       
   381 				
   453 				
   382 				TMemSpyThreadData data;
   454 				TMemSpyThreadData data;
   383 				data.iId = thread.Id();
   455 				data.iId = thread.Id();
   384 				data.iName.Copy(thread.Name());
   456 				data.iName.Copy(thread.Name().Left(KMaxFullName));
   385 				data.iThreadPriority = thread.Priority();
   457 				data.iThreadPriority = thread.Priority();
   386 				
   458 				
   387 				TPckgBuf<TMemSpyThreadData> buffer(data);
   459 				TPckgBuf<TMemSpyThreadData> buffer(data);
   388 				aMessage.WriteL(1, buffer, offset);
   460 				aMessage.WriteL(1, buffer, offset);
   389 				
       
   390 				thread.Close();
       
   391 				}
   461 				}
   392 			
   462 			
   393 			a0 = list.Count();
   463 			a0 = list.Count();
   394 			aMessage.WriteL(0, a0);
   464 			aMessage.WriteL(0, a0);
   395 			
   465 
   396 			list.Close();
       
   397 	
       
   398 			break;
   466 			break;
   399 			}
   467 			}
   400 		case EMemSpyClientServerOpSetThreadPriority:
   468 		case EMemSpyClientServerOpSetThreadPriority:
   401 			{
   469 			{
   402 			TPckgBuf<TThreadId> tid;
   470 			TPckgBuf<TThreadId> tid;
   408 			CMemSpyThread* thread = NULL; 
   476 			CMemSpyThread* thread = NULL; 
   409 			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
   477 			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
   410 			
   478 			
   411 			if (thread)
   479 			if (thread)
   412 				{				
   480 				{				
   413 				thread->Open();
   481 				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
   414 				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));				
       
   415 				thread->Close();
       
   416 				}					
   482 				}					
   417 			break;
   483 			break;
   418 			}
   484 			}
   419 		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
   485 		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
   420 			{
   486 			{
   421 			TBool ret = EFalse;
       
   422 			TPckgBuf<TThreadId> id;
   487 			TPckgBuf<TThreadId> id;
   423 			aMessage.ReadL( 0, id );
   488 			aMessage.ReadL( 0, id );
   424 			
   489 			
   425 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   490 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   426 			CMemSpyProcess* process = NULL;
   491 			CMemSpyProcess* process = NULL;
   427 			CMemSpyThread* thread = NULL; 
   492 			CMemSpyThread* thread = NULL; 
   428 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
   493 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
   429 			
   494 			
   430 			if ( thread )
   495 			TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() );
   431 				{				
   496 			
   432 				thread->Open();
       
   433 				
       
   434 				if  ( thread->IsSystemPermanent() || thread->IsSystemCritical() )
       
   435 					{			
       
   436 					ret = ETrue;					
       
   437 					}
       
   438 				thread->Close();
       
   439 				}
       
   440 			TPckgBuf<TBool> retBuf( ret );
   497 			TPckgBuf<TBool> retBuf( ret );
   441 			aMessage.WriteL( 1, retBuf );
   498 			aMessage.WriteL( 1, retBuf );
   442 							
   499 							
   443 			break;
   500 			break;
   444 			}
   501 			}
   517 					
   574 					
   518 			break;
   575 			break;
   519 			}		
   576 			}		
   520 		case EMemSpyClientServerOpGetInfoItemType:
   577 		case EMemSpyClientServerOpGetInfoItemType:
   521 			{
   578 			{
       
   579 			
   522 			TPckgBuf<TInt> index;
   580 			TPckgBuf<TInt> index;
   523 			aMessage.ReadL( 0, index );			
   581 			aMessage.ReadL( 0, index );			
   524 			TPckgBuf<TThreadId> id;
   582 			TPckgBuf<TThreadId> id;
   525 			aMessage.ReadL( 1, id);
   583 			aMessage.ReadL( 1, id);
   526 								
   584 								
   527 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   585 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   528 			CMemSpyProcess* process = NULL; //not needed
   586 			CMemSpyProcess* process = NULL; //not needed
   529 			CMemSpyThread* thread = NULL; 
   587 			CMemSpyThread* thread = NULL; 
   530 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
   588 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
   531 		            
   589 		            
   532 			thread->Open();
       
   533 			process->Open();
       
   534 		            
       
   535 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
   590 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
   536 			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
   591 			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
   537 			
   592 			
   538 			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
   593 			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
   539 			aMessage.WriteL( 2, ret );			
   594 			aMessage.WriteL( 2, ret );			
   540 			
   595 			
   541 			thread->Close();
       
   542 			process->Close();			
       
   543 			
       
   544 			break;
   596 			break;
   545 			}
   597 			}
   546 		case EMemSpyClientServerOpGetThreadInfoItemsCount:
   598 		case EMemSpyClientServerOpGetThreadInfoItemsCount:
   547 			{		
   599 			{
   548 			TPckgBuf<TThreadId> id;
   600 			TPckgBuf<TThreadId> id;
   549 			aMessage.ReadL( 0, id );
   601 			aMessage.ReadL( 0, id );
   550 			TPckgBuf<TMemSpyThreadInfoItemType> type;
   602 			TPckgBuf<TMemSpyThreadInfoItemType> type;
   551 			aMessage.ReadL( 1, type );					 
   603 			aMessage.ReadL( 1, type );					 
   552 			
   604 			
   554 			CMemSpyProcess* process = NULL;
   606 			CMemSpyProcess* process = NULL;
   555 			CMemSpyThread* thread = NULL; 
   607 			CMemSpyThread* thread = NULL; 
   556 			
   608 			
   557 			container.ProcessAndThreadByThreadId( id(), process, thread );
   609 			container.ProcessAndThreadByThreadId( id(), process, thread );
   558 			
   610 			
   559 			thread->Open();
       
   560 			process->Open();
       
   561 				    
       
   562 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
   611 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
   563 								
   612 								
   564 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
   613 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
   565 				    
   614 				    
   566 			TInt count = threadInfoItemBase.MdcaCount();		    
   615 			TInt count = threadInfoItemBase.MdcaCount();		    
   567 			TPckgBuf<TInt> tempret( count );
   616 			TPckgBuf<TInt> tempret( count );
   568 			aMessage.WriteL( 2, tempret );
   617 			aMessage.WriteL( 2, tempret );
   569 					
   618 		
   570 			thread->Close();
       
   571 			process->Close();
       
   572 					
       
   573 			break;
   619 			break;
   574 			}		
   620 			}		
   575 		case EMemSpyClientServerOpGetThreadInfoItems:
   621 		case EMemSpyClientServerOpGetThreadInfoItems:
   576 			{
   622 			{
   577 			TPckgBuf<TInt> count;
   623 			TPckgBuf<TInt> count;
   584 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   630 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
   585 			CMemSpyProcess* process = NULL;
   631 			CMemSpyProcess* process = NULL;
   586 			CMemSpyThread* thread = NULL; 
   632 			CMemSpyThread* thread = NULL; 
   587 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
   633 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
   588 							  
   634 							  
   589 			process->Open();
       
   590 			thread->Open();
       
   591 					
       
   592 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
   635 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
   593 					
   636 
   594 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
   637 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
   595 			
   638 			
   596 			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
   639 			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
   597 					
   640 								
   598 			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
   641 			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
   599 				{
   642 				{
   600 				TMemSpyThreadInfoItemData data;
   643 				TMemSpyThreadInfoItemData data;
   601 				
   644 				
   602 				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
   645 				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
   607 				TPtrC value(threadInfoItemBase.MdcaPoint(i));
   650 				TPtrC value(threadInfoItemBase.MdcaPoint(i));
   608 				tabPos = value.LocateReverse('\t');
   651 				tabPos = value.LocateReverse('\t');
   609 				if (tabPos != KErrNotFound)
   652 				if (tabPos != KErrNotFound)
   610 					value.Set(value.Mid(tabPos + 1));
   653 					value.Set(value.Mid(tabPos + 1));
   611 												
   654 												
   612 				data.iCaption.Copy( caption );
   655 				data.iCaption.Copy( caption.Left(64) );
   613 				data.iValue.Copy( value );
   656 				data.iValue.Copy( value.Left(32) );
   614 							
   657 							
   615 				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
   658 				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
   616 				aMessage.WriteL(3, buffer, offset);				
   659 				aMessage.WriteL(3, buffer, offset);				
   617 				}			
   660 				}			
   618 			aMessage.WriteL(0, count);						
   661 			aMessage.WriteL(0, count);
   619 					
       
   620 			thread->Close();
       
   621 			process->Close();
       
   622 					
   662 					
   623 			break;
   663 			break;
   624 			}
   664 			}
   625 		// --- KernelObjects related functions ---
   665 		// --- KernelObjects related functions ---
   626 		case EMemSpyClientServerOpGetKernelObjectCount:
   666 		case EMemSpyClientServerOpGetKernelObjectCount:
   649 												
   689 												
   650 				data.iName.Copy(name);
   690 				data.iName.Copy(name);
   651 				data.iType = model->At(i).Type();
   691 				data.iType = model->At(i).Type();
   652 				data.iCount = model->At(i).Count();											
   692 				data.iCount = model->At(i).Count();											
   653 				data.iSize = model->At(i).Count() * model->At(i).Count();
   693 				data.iSize = model->At(i).Count() * model->At(i).Count();
   654 	
   694 
   655 				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
   695 				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
   656 				aMessage.WriteL(1, buffer, offset);
   696 				aMessage.WriteL(1, buffer, offset);
   657 				}			
   697 				}			
   658 			aMessage.WriteL(0, count);
   698 			aMessage.WriteL(0, count);
   659 			CleanupStack::PopAndDestroy( model );
   699 			CleanupStack::PopAndDestroy( model );
   681 			TPckgBuf<TInt> count;
   721 			TPckgBuf<TInt> count;
   682 			TPckgBuf<TMemSpyDriverContainerType> tempType;
   722 			TPckgBuf<TMemSpyDriverContainerType> tempType;
   683 			aMessage.ReadL( 0, count ); //get count of items
   723 			aMessage.ReadL( 0, count ); //get count of items
   684 			aMessage.ReadL(1, tempType); //get type of kernel object
   724 			aMessage.ReadL(1, tempType); //get type of kernel object
   685 			TInt c = count();
   725 			TInt c = count();
   686 			
   726 						
   687 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
   727 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
   688 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
   728 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
   689 			CleanupStack::PushL( iObjectList );
   729 			CleanupStack::PushL( iObjectList );
   690 			
   730 			
   691 			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
   731 			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
   699 				}			
   739 				}			
   700 			
   740 			
   701 			CleanupStack::PopAndDestroy( iObjectList );			
   741 			CleanupStack::PopAndDestroy( iObjectList );			
   702 			break;
   742 			break;
   703 			}
   743 			}
       
   744 			
       
   745 		case EMemSpyClientServerOpOutputAllContainerContents:
       
   746 			{
       
   747 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   748 			CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
       
   749 			
       
   750 			model->OutputL( iEngine.Sink() );
       
   751 
       
   752 			break;
       
   753 			}
       
   754 			
       
   755 		case EMemSpyClientServerOpDumpKernelHeap:
       
   756 			{
       
   757 		    iEngine.HelperHeap().OutputHeapDataKernelL();
       
   758 			
       
   759 			break;
       
   760 			}
       
   761 			
       
   762 		case EMemSpyClientServerOpOutputInfoHandles:
       
   763 			{
       
   764 			TPckgBuf<TThreadId> id;
       
   765 			aMessage.ReadL(0, id);
       
   766 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   767 			CMemSpyProcess* process = NULL;
       
   768 			CMemSpyThread* thread = NULL; 
       
   769 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   770 										  
       
   771 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
       
   772 			
       
   773 			threadInfoContainer.PrintL();
       
   774 			
       
   775 			break;
       
   776 			}
       
   777 			
       
   778 		case EMemSpyClientServerOpOutputAOList:
       
   779 			{
       
   780 			TPckgBuf<TThreadId> id;
       
   781 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   782 			aMessage.ReadL(0, id);
       
   783 			aMessage.ReadL(1, type);
       
   784 			
       
   785 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   786 			CMemSpyProcess* process = NULL;
       
   787 			CMemSpyThread* thread = NULL; 
       
   788 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   789 										  
       
   790 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   791 
       
   792 			CMemSpyThreadInfoItemBase* threadInfoItem = &threadInfoContainer.Item( type() );
       
   793 						
       
   794 			CMemSpyThreadInfoActiveObjects* activeObjectArray = static_cast< CMemSpyThreadInfoActiveObjects* >( threadInfoItem );			
       
   795 						
       
   796 		    // Begin a new data stream
       
   797 		    _LIT( KMemSpyContext, "Active Object List - " );
       
   798 		    _LIT( KMemSpyFolder, "Active Objects" );
       
   799 		    iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder );
       
   800 		    		    
       
   801 		    // Set prefix for overall listing
       
   802 		    iEngine.Sink().OutputPrefixSetLC( KMemSpyContext );
       
   803 
       
   804 		    // Create header
       
   805 		    CMemSpyEngineActiveObjectArray::OutputDataColumnsL( iEngine );
       
   806 		    
       
   807 		    // List items
       
   808 		    const TInt count = activeObjectArray->Array().Count();
       
   809 		    for(TInt i=0; i<count; i++)
       
   810 		        {
       
   811 		        const CMemSpyEngineActiveObject& object = activeObjectArray->Array().At( i );
       
   812 		        //
       
   813 		        object.OutputDataL( iEngine );
       
   814 		        }
       
   815 
       
   816 		    // Tidy up
       
   817 		    CleanupStack::PopAndDestroy(); // prefix
       
   818 
       
   819 		    // End data stream		    		    
       
   820 		    iEngine.Sink().DataStreamEndL();		    
       
   821 			
       
   822 			break;
       
   823 			}
       
   824 			
   704 		// --- Kernel Heap related functions ---
   825 		// --- Kernel Heap related functions ---
   705 		case EMemSpyClientServerOpGetHeap:
   826 		case EMemSpyClientServerOpGetHeap:
   706 			{
   827 			{
   707 			TMemSpyHeapInfo heapInfo;			
   828 			TMemSpyHeapInfo heapInfo;			
   708 			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
   829 			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
   711 			TPckgBuf<TMemSpyHeapData> buffer(data);
   832 			TPckgBuf<TMemSpyHeapData> buffer(data);
   712 			aMessage.WriteL(0, buffer);
   833 			aMessage.WriteL(0, buffer);
   713 			
   834 			
   714 			break;
   835 			break;
   715 			}
   836 			}
       
   837 		
       
   838 		case EMemSpyClientServerOpGetMemoryTrackingCycleCount:
       
   839 			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.HelperSysMemTracker().CompletedCycles().Count()));
       
   840 			break;
       
   841 			
       
   842 		case EMemSpyClientServerOpGetMemoryTrackingCycles:
       
   843 			{
       
   844 			const RPointerArray<CMemSpyEngineHelperSysMemTrackerCycle>& list = iEngine.HelperSysMemTracker().CompletedCycles();
       
   845 
       
   846 			TPckgBuf<TInt> a0;
       
   847 			aMessage.ReadL(0, a0);
       
   848 			TInt realCount = Min(a0(), list.Count());
       
   849 			
       
   850 			for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyMemoryTrackingCycleData))
       
   851 				{
       
   852 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   853 				TMemSpyMemoryTrackingCycleData data;
       
   854 				data.iCycleNumber = list[i]->CycleNumber();
       
   855 				data.iCaption.Copy(list[i]->Caption().Left(KMaxFullName));
       
   856 				data.iTime = list[i]->Time();
       
   857 				data.iFreeMemory = list[i]->MemoryFree();
       
   858 				data.iMemoryDelta = list[i]->MemoryDelta();
       
   859 				data.iPreviousCycleDiff = list[i]->MemoryFreePreviousCycle();
       
   860 				
       
   861 				TPckgBuf<TMemSpyMemoryTrackingCycleData> buffer(data);
       
   862 				aMessage.WriteL(1, buffer, offset);
       
   863 				}
       
   864 			
       
   865 			a0 = list.Count();
       
   866 			aMessage.WriteL(0, a0);
       
   867 
       
   868 		break;
       
   869 		}
       
   870 	case EMemSpyClientServerOpIsSwmtRunning:
       
   871 		{
       
   872 		TPckgBuf<TBool> running(iEngine.HelperSysMemTracker().IsActive());
       
   873 		aMessage.WriteL(0, running);
       
   874 		break;
       
   875 		}
       
   876 			
       
   877 		
       
   878 	case EMemSpyClientServerOpNotifyDeviceWideOperationProgress:
       
   879 		{
       
   880 		if (!Server().CurrentOperationTracker())
       
   881 			{
       
   882 			User::Leave(KErrNotReady);
       
   883 			}
       
   884 		
       
   885 		Server().CurrentOperationTracker()->AddNotificationL(aMessage);
       
   886 		break;
       
   887 		}
       
   888 		
       
   889 	case EMemSpyClientServerOpCancelDeviceWideOperation:
       
   890 		if (!Server().CurrentOperationTracker())
       
   891 			{
       
   892 			User::Leave(KErrNotReady);
       
   893 			}
       
   894 		
       
   895 		Server().CurrentOperationTracker()->Cancel();
       
   896 		break;
   716 		}
   897 		}
   717     }
   898     }
   718 
   899 
   719 // ---------------------------------------------------------
   900 // ---------------------------------------------------------
   720 // DoCmdServiceL( const RMessage2& aMessage )
   901 // DoCmdServiceL( const RMessage2& aMessage )
   932 
  1113 
   933 
  1114 
   934 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
  1115 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
   935     {
  1116     {
   936     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
  1117     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
       
  1118     
   937     //
  1119     //
   938     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
  1120     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
   939         {
  1121         {
   940         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
  1122         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
   941         iEngine.HelperHeap().OutputHeapInfoForDeviceL();
  1123         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1124         	{
       
  1125 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage);
       
  1126         	}
       
  1127         else
       
  1128         	{
       
  1129 			iEngine.HelperHeap().OutputHeapInfoForDeviceL();
       
  1130         	}
   942         }
  1131         }
   943     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
  1132     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
   944         {
  1133         {
   945         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
  1134         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
   946         iEngine.HelperStack().OutputStackInfoForDeviceL();
  1135         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1136 			{
       
  1137 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage);
       
  1138 			}
       
  1139 		else
       
  1140 			{
       
  1141 			iEngine.HelperStack().OutputStackInfoForDeviceL();
       
  1142 			}
   947         }
  1143         }
   948     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
  1144     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
   949         {
  1145         {
   950         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
  1146         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
   951         iEngine.HelperSysMemTracker().StartL();
  1147         iEngine.HelperSysMemTracker().StartL();
  1031         iEngine.HelperSysMemTracker().SetConfigL( config );
  1227         iEngine.HelperSysMemTracker().SetConfigL( config );
  1032         }
  1228         }
  1033     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
  1229     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
  1034         {
  1230         {
  1035         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
  1231         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
  1036         iEngine.InstallSinkL( ESinkTypeDebug );
  1232         iEngine.InstallDebugSinkL();
  1037         }
  1233         }
  1038     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
  1234     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
  1039         {
  1235         {
  1040         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
  1236         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
  1041         iEngine.InstallSinkL( ESinkTypeFile );
  1237         // Read file name from message.
       
  1238         TFileName fileName;
       
  1239         RBuf buf;
       
  1240 		buf.CleanupClosePushL();
       
  1241 		
       
  1242 		TInt len = aMessage.GetDesLength( 0 );
       
  1243 		if ( len > 0 )
       
  1244 			{
       
  1245 			buf.CreateL( len );
       
  1246 			aMessage.ReadL( 0, buf, 0 );
       
  1247 			
       
  1248 			iEngine.InstallFileSinkL( buf );           
       
  1249 			}
       
  1250 		else
       
  1251 			{
       
  1252 			iEngine.InstallFileSinkL( KNullDesC );
       
  1253 			}
       
  1254 		
       
  1255 		CleanupStack::PopAndDestroy( &buf );
       
  1256         
  1042         }
  1257         }
  1043     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
  1258     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
  1044         {
  1259         {
  1045         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
  1260         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
  1046 
  1261 
  1067     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
  1282     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
  1068         {
  1283         {
  1069         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
  1284         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
  1070         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
  1285         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
  1071         }
  1286         }
       
  1287     else if ( aFunction == EMemSpyClientServerOpSummaryInfo )
       
  1288     	{
       
  1289 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfo") );
       
  1290 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralSummary, aMessage);
       
  1291     	}
       
  1292     else if ( aFunction == EMemSpyClientServerOpSummaryInfoDetailed )
       
  1293 		{
       
  1294 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfoDetailed") );
       
  1295 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed, aMessage);
       
  1296 		}
       
  1297     else if ( aFunction == EMemSpyClientServerOpHeapInfo )
       
  1298 		{
       
  1299 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfo") );
       
  1300 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapInfo, aMessage);
       
  1301 		}
       
  1302     else if ( aFunction == EMemSpyClientServerOpHeapCellListing )
       
  1303 		{
       
  1304 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapCellListing") );
       
  1305 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapCellListing, aMessage);
       
  1306 		}
       
  1307     else if ( aFunction == EMemSpyClientServerOpHeapData )
       
  1308 		{
       
  1309 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapData") );
       
  1310 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapData, aMessage);
       
  1311 		}
       
  1312     else if ( aFunction == EMemSpyClientServerOpStackInfo )
       
  1313 		{
       
  1314 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfo") );
       
  1315 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackInfo, aMessage);
       
  1316 		}
       
  1317     else if ( aFunction == EMemSpyClientServerOpStackDataUser )
       
  1318 		{
       
  1319 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataUser") );
       
  1320 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataUser, aMessage);
       
  1321 		}
       
  1322     else if ( aFunction == EMemSpyClientServerOpStackDataKernel )
       
  1323 		{
       
  1324 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataKernel") );
       
  1325 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataKernel, aMessage);
       
  1326 		}
  1072     else
  1327     else
  1073         {
  1328         {
  1074         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
  1329         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
  1075         iEngine.NotifyClientServerOperationRequestL( aFunction );
  1330         iEngine.NotifyClientServerOperationRequestL( aFunction );
  1076         }
  1331         }
  1077     //
  1332     //
  1078     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
  1333     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
  1079     }
  1334     }
  1080 
  1335 
  1081 
  1336 void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage)
  1082 
  1337 	{
  1083 
  1338 	if (Server().CurrentOperationTracker())
  1084 
  1339 		{
       
  1340 		User::Leave(KErrInUse);
       
  1341 		}
       
  1342 	
       
  1343 	Server().SetCurrentOperationTracker(CMemSpyDwOperationTracker::NewL(aOperation, aMessage, Server()));
       
  1344 	}
       
  1345 
       
  1346 
       
  1347 
       
  1348 
       
  1349 
       
  1350 
       
  1351 
       
  1352 
       
  1353 
       
  1354 CMemSpyDwOperationTracker* CMemSpyDwOperationTracker::NewL(CMemSpyDeviceWideOperations::TOperation aOperation, 
       
  1355 		const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer)
       
  1356 	{
       
  1357 	CMemSpyDwOperationTracker* self = new (ELeave) CMemSpyDwOperationTracker(aOperationMessage, aServer);
       
  1358 	CleanupStack::PushL( self );
       
  1359 	self->ConstructL(aOperation);
       
  1360 	CleanupStack::Pop( self );
       
  1361 	return self;
       
  1362 	}
       
  1363 	
       
  1364 CMemSpyDwOperationTracker::~CMemSpyDwOperationTracker()
       
  1365 	{
       
  1366 	delete iOperation;
       
  1367 	delete iPendingNotifications;
       
  1368 	}
       
  1369 
       
  1370 CMemSpyDwOperationTracker::CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) : 
       
  1371 		iOperationMessage(aOperationMessage),
       
  1372 		iServer(aServer),
       
  1373 		iPendingNotifications(0),
       
  1374 		iOperation(0),
       
  1375 		iProgress(0)
       
  1376 	{
       
  1377 	}
       
  1378 
       
  1379 
       
  1380 void CMemSpyDwOperationTracker::ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation)
       
  1381 	{
       
  1382 	iPendingNotifications = new (ELeave) CArrayFixFlat<RMessage2>(3);
       
  1383 	iOperation = CMemSpyDeviceWideOperations::NewL(iServer.Engine(), *this, aOperation);
       
  1384 	}
       
  1385 
       
  1386 void CMemSpyDwOperationTracker::AddNotificationL(const RMessage2& aMessage)
       
  1387 	{
       
  1388 	iPendingNotifications->AppendL(aMessage);
       
  1389 	}
       
  1390 
       
  1391 void CMemSpyDwOperationTracker::Cancel()
       
  1392 	{
       
  1393 	iOperation->Cancel();
       
  1394 	}
       
  1395 
       
  1396 void CMemSpyDwOperationTracker::HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2)
       
  1397 	{
       
  1398 	switch( aEvent )
       
  1399 		{
       
  1400 	case MMemSpyDeviceWideOperationsObserver::EOperationCompleted:
       
  1401 	case MMemSpyDeviceWideOperationsObserver::EOperationCancelled:
       
  1402 		iServer.SetCurrentOperationTracker(0);
       
  1403 		
       
  1404 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1405 			{
       
  1406 			iPendingNotifications->At(i).Complete(KErrCancel);
       
  1407 			}
       
  1408 		
       
  1409 		if (iOperationMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1410 			{
       
  1411 			iOperationMessage.Complete(
       
  1412 				aEvent == MMemSpyDeviceWideOperationsObserver::EOperationCompleted ? KErrNone : KErrCancel);
       
  1413 			}
       
  1414 		
       
  1415 		iPendingNotifications->Reset();
       
  1416 		
       
  1417 		delete this;
       
  1418 		break;
       
  1419 		
       
  1420 	case MMemSpyDeviceWideOperationsObserver::EOperationProgressEnd:
       
  1421 		{
       
  1422 		iProgress += aParam1;
       
  1423 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1424 			{
       
  1425 			TInt err;
       
  1426 			TRAP(err, iPendingNotifications->At(i).WriteL(0, TPckgBuf<TInt>( iProgress * 100 / iOperation->TotalOperationSize() )));
       
  1427 			TRAP(err, iPendingNotifications->At(i).WriteL(1, aParam2));
       
  1428 			if (err != KErrNone)
       
  1429 				{
       
  1430 				// TODO: iPendingProgressNotifications->At(i).Panic()
       
  1431 				}
       
  1432 			iPendingNotifications->At(i).Complete(KErrNone);
       
  1433 			}
       
  1434 		iPendingNotifications->Reset();
       
  1435 		break;
       
  1436 		}
       
  1437 		
       
  1438 		}
       
  1439 	
       
  1440 	}