memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp
branchRCL_3
changeset 21 52e343bb8f80
parent 20 ca8a1b6995f6
equal deleted inserted replaced
20:ca8a1b6995f6 21:52e343bb8f80
    17 
    17 
    18 #include "MemSpyEngineServer.h"
    18 #include "MemSpyEngineServer.h"
    19 
    19 
    20 // System includes
    20 // System includes
    21 #include <e32svr.h>
    21 #include <e32svr.h>
    22 #include <w32std.h>
       
    23 #include <APGTASK.H>
       
    24 #include <APGWGNAM.H>  
       
    25 
    22 
    26 // User includes
    23 // User includes
    27 #include <memspy/engine/memspyengine.h>
    24 #include <memspy/engine/memspyengine.h>
    28 #include <memspy/engine/memspyenginelogger.h>
    25 #include <memspy/engine/memspyenginelogger.h>
    29 #include <memspyengineclientinterface.h>
    26 #include <memspyengineclientinterface.h>
    39 #include <memspy/engine/memspyenginehelperfilesystem.h>
    36 #include <memspy/engine/memspyenginehelperfilesystem.h>
    40 #include <memspy/engine/memspyenginehelperram.h>
    37 #include <memspy/engine/memspyenginehelperram.h>
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    38 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    42 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    39 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    43 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    40 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    44 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
    41 
    45 #include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
       
    46 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
       
    47 
       
    48 #include <memspy/engine/memspyprocessdata.h>
       
    49 #include <memspy/engine/memspythreaddata.h>
       
    50 #include <memspy/engine/memspykernelobjectdata.h>
       
    51 #include <memspy/engine/memspythreadinfoitemdata.h>
       
    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     }
       
    78 
    42 
    79 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    43 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    80 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    44 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    81     {
    45     {
    82     }
    46     }
    88 
    52 
    89 
    53 
    90 void CMemSpyEngineServer::ConstructL()
    54 void CMemSpyEngineServer::ConstructL()
    91     {
    55     {
    92     StartL( KMemSpyServerName );
    56     StartL( KMemSpyServerName );
    93     
       
    94     iShutdown.ConstructL();
       
    95     // ensure that the server still exits even if the 1st client fails to connect
       
    96     iShutdown.Start();
       
    97     }
    57     }
    98 
    58 
    99 
    59 
   100 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
    60 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
   101     {
    61     {
   117     //
    77     //
   118     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
    78     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
   119 	return session;
    79 	return session;
   120     }
    80     }
   121 
    81 
   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 
       
   150 
    82 
   151 
    83 
   152 
    84 
   153 
    85 
   154 
    86 
   186 
   118 
   187     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   119     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   188 #endif
   120 #endif
   189 
   121 
   190     delete iClientThreadName;
   122     delete iClientThreadName;
   191     
       
   192     Server().DropSession(iIsCliRequest);
       
   193     }
   123     }
   194 
   124 
   195 
   125 
   196 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   126 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   197     {
   127     {
   206     const TFullName threadName( thread.FullName() );
   136     const TFullName threadName( thread.FullName() );
   207     iClientThreadName = threadName.AllocL();
   137     iClientThreadName = threadName.AllocL();
   208     iClientThreadId = thread.Id();
   138     iClientThreadId = thread.Id();
   209 
   139 
   210     CleanupStack::PopAndDestroy( &thread );
   140     CleanupStack::PopAndDestroy( &thread );
   211     
   141 
   212     const TUid KCliUid3 = { 0x2002129D };
       
   213     iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3);
       
   214     
       
   215     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   142     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   216     }
   143     }
   217 
   144 
   218 void CMemSpyEngineSession::CreateL()
       
   219     {   
       
   220     Server().AddSession(iIsCliRequest);
       
   221     }
       
   222 
   145 
   223 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   146 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   224     {
   147     {
   225     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   148     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   226     CleanupStack::PushL( self );
   149     CleanupStack::PushL( self );
   237     TRAPD( error, DoServiceL( aMessage ) );
   160     TRAPD( error, DoServiceL( aMessage ) );
   238     if  ( error != KErrNone )
   161     if  ( error != KErrNone )
   239         {
   162         {
   240         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   163         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   241         }
   164         }
   242     
   165     aMessage.Complete( error );
   243     if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone)
       
   244     	{
       
   245 		aMessage.Complete( error );
       
   246     	}
       
   247 
   166 
   248     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   167     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   249 	}
   168 	}
   250 
   169 
   251 // ---------------------------------------------------------
   170 
   252 // DoServiceL( const RMessage2& aMessage )
       
   253 // ---------------------------------------------------------
       
   254 //
       
   255 void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
   171 void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
   256 	{
       
   257 	TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
       
   258 	if (function >= EMemSpyClientServerOpMarkerUiFirst && 
       
   259 		function < EMemSpyClientServerOpMarkerUiLast)
       
   260 		
       
   261 		DoUiServiceL(aMessage);
       
   262 	else
       
   263 		DoCmdServiceL(aMessage);
       
   264 	}
       
   265 // ---------------------------------------------------------
       
   266 // DoUiServiceL( const RMessage2& aMessage )
       
   267 // ---------------------------------------------------------
       
   268 //
       
   269 void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
       
   270     {
       
   271 	switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
       
   272 		{
       
   273 		case EMemSpyClientServerOpGetProcessCount:
       
   274 			{
       
   275 			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
       
   276 			break;
       
   277 			}
       
   278 		case EMemSpyClientServerOpGetProcesses:
       
   279 			{
       
   280 			CMemSpyEngineObjectContainer& list = iEngine.Container();
       
   281 			
       
   282 			TPckgBuf<TInt> a0;
       
   283 			aMessage.ReadL(0, a0);
       
   284 			TInt realCount = Min(a0(), list.Count());
       
   285 			
       
   286 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
       
   287 				{
       
   288 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   289 				TMemSpyProcessData data;
       
   290 				data.iIsDead = process.IsDead();
       
   291 				data.iId = process.Id();
       
   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();
       
   299 				
       
   300 				TPckgBuf<TMemSpyProcessData> buffer(data);
       
   301 				aMessage.WriteL(1, buffer, offset);
       
   302 				}
       
   303 			
       
   304 			a0 = list.Count();
       
   305 			aMessage.WriteL(0, a0);
       
   306 
       
   307 			break;
       
   308 			}
       
   309 		case EMemSpyClienServerOpGetProcessIdByName:
       
   310 			{
       
   311 			TFullName processName;
       
   312 			aMessage.ReadL(0, processName);
       
   313 			
       
   314 			TBool found(EFalse);
       
   315 			
       
   316 			for (TInt i=0; i<iEngine.Container().Count(); i++)
       
   317 				{
       
   318 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   319 				if (process.Name().FindF(processName) >= 0)
       
   320 					{
       
   321 					found = ETrue;
       
   322 					TPckgBuf<TProcessId> procId(process.Id());
       
   323 					aMessage.WriteL(1, procId);
       
   324 					}
       
   325 				}
       
   326 			
       
   327 			if (!found)
       
   328 				{
       
   329 				User::Leave(KErrNotFound);
       
   330 				}
       
   331 			
       
   332 			break;
       
   333 			}
       
   334 		case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
       
   335 			{
       
   336 			TBool ret = EFalse;
       
   337 			TPckgBuf<TProcessId> id;
       
   338 			aMessage.ReadL( 0, id );
       
   339 			
       
   340 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   341 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   342 			
       
   343 			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
       
   344 				{
       
   345 				ret = ETrue;
       
   346 				}
       
   347 			TPckgBuf<TBool> retBuf( ret );
       
   348 			aMessage.WriteL( 1, retBuf );
       
   349 			
       
   350 			break;
       
   351 			}
       
   352 		case EMemSpyClientServerOpEndProcess:
       
   353 			{
       
   354 			TPckgBuf<TProcessId> id;
       
   355 			aMessage.ReadL( 0, id );
       
   356 			TPckgBuf<TMemSpyEndType> type;
       
   357 			aMessage.ReadL( 1, type );
       
   358 					
       
   359 			CMemSpyEngineObjectContainer& container = iEngine.Container();			
       
   360 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   361 									
       
   362 			switch ( type() )
       
   363 				{
       
   364 				case ETerminate:
       
   365 					{
       
   366 					process.TerminateL();
       
   367 					break;
       
   368 					}
       
   369 				case EPanic:
       
   370 					{
       
   371 					process.PanicL();
       
   372 					break;
       
   373 					}
       
   374 				case EKill:
       
   375 					{
       
   376 					process.KillL();
       
   377 					break;
       
   378 					}
       
   379 				}																
       
   380 			break;
       
   381 			}
       
   382 		case EMemSpyClientServerOpSwitchToProcess:
       
   383 			{/*
       
   384 			TInt wgCount;
       
   385 			RWsSession wsSession;
       
   386 			User::LeaveIfError( wsSession.Connect() );
       
   387 			CleanupClosePushL( wsSession );
       
   388 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   389 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   390 			CleanupClosePushL( wgArray );
       
   391 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   392 			TApaTask task( wsSession );
       
   393 			TBool brought( EFalse );
       
   394 			TInt wgId( KErrNotFound );
       
   395 			TThreadId threadId;
       
   396 			
       
   397 			TPckgBuf<TProcessId> id;
       
   398 			aMessage.ReadL( 0, id );
       
   399 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   400 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   401 			
       
   402 			// loop trough threads in a process
       
   403 			for ( TInt i = 0; i < process.MdcaCount(); i++ )
       
   404 				{
       
   405 				TInt wgCountLocal = wgCount;
       
   406 							
       
   407 				// loop trough all window groups and see if a thread id matches
       
   408 				while( !brought && wgCountLocal-- )
       
   409 					{
       
   410 					wgId = wgArray[wgCountLocal].iId;
       
   411 					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   412 					if ( threadId == process.At( i ).Id() )
       
   413 						{
       
   414 						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   415 						task.SetWgId( wgId );
       
   416 						if ( !wgName->Hidden() && task.Exists() )
       
   417 							{
       
   418 							task.BringToForeground();
       
   419 							brought = ETrue;                        
       
   420 							}
       
   421 						CleanupStack::PopAndDestroy( wgName );
       
   422 						}
       
   423 					}
       
   424 				}
       
   425 			
       
   426 			TPckgBuf<TBool> ret( brought );
       
   427 			aMessage.WriteL( 1, ret );
       
   428 			
       
   429 			break;*/
       
   430 			}
       
   431 		case EMemSpyClientServerOpGetThreadCount:
       
   432 			{
       
   433 			TPckgBuf<TProcessId> pid;
       
   434 			aMessage.ReadL(1, pid);
       
   435 			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
       
   436 			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
       
   437 			break;
       
   438 			}
       
   439 		case EMemSpyClientServerOpGetThreads:
       
   440 			{
       
   441 			TPckgBuf<TProcessId> pid;
       
   442 			aMessage.ReadL(2, pid);
       
   443 			
       
   444 			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
       
   445 			
       
   446 			TPckgBuf<TInt> a0;
       
   447 			aMessage.ReadL(0, a0);
       
   448 			TInt realCount = Min(a0(), list.Count());
       
   449 						
       
   450 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
       
   451 				{
       
   452 				CMemSpyThread& thread = list.At(i);
       
   453 				
       
   454 				TMemSpyThreadData data;
       
   455 				data.iId = thread.Id();
       
   456 				data.iName.Copy(thread.Name().Left(KMaxFullName));
       
   457 				data.iThreadPriority = thread.Priority();
       
   458 				
       
   459 				TPckgBuf<TMemSpyThreadData> buffer(data);
       
   460 				aMessage.WriteL(1, buffer, offset);
       
   461 				}
       
   462 			
       
   463 			a0 = list.Count();
       
   464 			aMessage.WriteL(0, a0);
       
   465 
       
   466 			break;
       
   467 			}
       
   468 		case EMemSpyClientServerOpSetThreadPriority:
       
   469 			{
       
   470 			TPckgBuf<TThreadId> tid;
       
   471 			TPckgBuf<TInt> priority;
       
   472 			aMessage.ReadL(0, tid);
       
   473 			aMessage.ReadL(1, priority);
       
   474 			
       
   475 			CMemSpyProcess* process = NULL;
       
   476 			CMemSpyThread* thread = NULL; 
       
   477 			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
       
   478 			
       
   479 			if (thread)
       
   480 				{				
       
   481 				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
       
   482 				}					
       
   483 			break;
       
   484 			}
       
   485 		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
       
   486 			{
       
   487 			TPckgBuf<TThreadId> id;
       
   488 			aMessage.ReadL( 0, id );
       
   489 			
       
   490 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   491 			CMemSpyProcess* process = NULL;
       
   492 			CMemSpyThread* thread = NULL; 
       
   493 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   494 			
       
   495 			TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() );
       
   496 			
       
   497 			TPckgBuf<TBool> retBuf( ret );
       
   498 			aMessage.WriteL( 1, retBuf );
       
   499 							
       
   500 			break;
       
   501 			}
       
   502 		case EMemSpyClientServerOpEndThread:
       
   503 			{
       
   504 			TPckgBuf<TThreadId> id;
       
   505 			aMessage.ReadL( 0, id );
       
   506 			TPckgBuf<TMemSpyEndType> type;
       
   507 			aMessage.ReadL( 1, type );
       
   508 			
       
   509 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   510 			CMemSpyProcess* process = NULL;
       
   511 			CMemSpyThread* thread = NULL; 
       
   512 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   513 			
       
   514 			if( thread )
       
   515 				{
       
   516 				switch ( type() )
       
   517 					{
       
   518 					case ETerminate:
       
   519 						{
       
   520 						thread->TerminateL();
       
   521 						break;
       
   522 						}
       
   523 					case EPanic:
       
   524 						{
       
   525 						thread->PanicL();
       
   526 						break;
       
   527 						}
       
   528 					case EKill:
       
   529 						{
       
   530 						thread->KillL();
       
   531 						break;
       
   532 						}
       
   533 					}				
       
   534 				}			
       
   535 			break;
       
   536 			}
       
   537 		case EMemSpyClientServerOpSwitchToThread:
       
   538 			{
       
   539 			TInt wgCount;
       
   540 			RWsSession wsSession;
       
   541 			User::LeaveIfError( wsSession.Connect() );
       
   542 			CleanupClosePushL( wsSession );
       
   543 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   544 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   545 			CleanupClosePushL( wgArray );
       
   546 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   547 			TApaTask task( wsSession );
       
   548 			TBool brought( EFalse );
       
   549 			TInt wgId( KErrNotFound );
       
   550 			TThreadId threadId;
       
   551 					
       
   552 			TPckgBuf<TThreadId> id;
       
   553 			aMessage.ReadL( 0, id );
       
   554 					
       
   555 			// loop trough all window groups and see if a thread id matches
       
   556 			while( !brought && wgCount-- )
       
   557 				{
       
   558 				wgId = wgArray[wgCount].iId;
       
   559 				User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   560 				if ( threadId == id() )
       
   561 					{
       
   562 					CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   563 					task.SetWgId( wgId );
       
   564 					if ( !wgName->Hidden() && task.Exists() )
       
   565 						{
       
   566 						task.BringToForeground();
       
   567 						brought = ETrue;                        
       
   568 						}
       
   569 					CleanupStack::PopAndDestroy( wgName );
       
   570 					}
       
   571 				}			
       
   572 			TPckgBuf<TBool> ret( brought );
       
   573 			aMessage.WriteL( 1, ret );															
       
   574 					
       
   575 			break;
       
   576 			}		
       
   577 		case EMemSpyClientServerOpGetInfoItemType:
       
   578 			{
       
   579 			
       
   580 			TPckgBuf<TInt> index;
       
   581 			aMessage.ReadL( 0, index );			
       
   582 			TPckgBuf<TThreadId> id;
       
   583 			aMessage.ReadL( 1, id);
       
   584 								
       
   585 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   586 			CMemSpyProcess* process = NULL; //not needed
       
   587 			CMemSpyThread* thread = NULL; 
       
   588 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   589 		            
       
   590 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
       
   591 			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
       
   592 			
       
   593 			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
       
   594 			aMessage.WriteL( 2, ret );			
       
   595 			
       
   596 			break;
       
   597 			}
       
   598 		case EMemSpyClientServerOpGetThreadInfoItemsCount:
       
   599 			{
       
   600 			TPckgBuf<TThreadId> id;
       
   601 			aMessage.ReadL( 0, id );
       
   602 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   603 			aMessage.ReadL( 1, type );					 
       
   604 			
       
   605 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   606 			CMemSpyProcess* process = NULL;
       
   607 			CMemSpyThread* thread = NULL; 
       
   608 			
       
   609 			container.ProcessAndThreadByThreadId( id(), process, thread );
       
   610 			
       
   611 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
       
   612 								
       
   613 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
       
   614 				    
       
   615 			TInt count = threadInfoItemBase.MdcaCount();		    
       
   616 			TPckgBuf<TInt> tempret( count );
       
   617 			aMessage.WriteL( 2, tempret );
       
   618 		
       
   619 			break;
       
   620 			}		
       
   621 		case EMemSpyClientServerOpGetThreadInfoItems:
       
   622 			{
       
   623 			TPckgBuf<TInt> count;
       
   624 			aMessage.ReadL( 0, count );						
       
   625 			TPckgBuf<TThreadId> id;
       
   626 			aMessage.ReadL( 1, id );
       
   627 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   628 			aMessage.ReadL( 2, type );			
       
   629 			
       
   630 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   631 			CMemSpyProcess* process = NULL;
       
   632 			CMemSpyThread* thread = NULL; 
       
   633 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   634 							  
       
   635 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   636 
       
   637 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
       
   638 			
       
   639 			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
       
   640 								
       
   641 			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
       
   642 				{
       
   643 				TMemSpyThreadInfoItemData data;
       
   644 				
       
   645 				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
       
   646 				TInt tabPos = caption.Locate('\t');
       
   647 				if (tabPos != KErrNotFound)
       
   648 					caption.Set(caption.Left(tabPos));
       
   649 				
       
   650 				TPtrC value(threadInfoItemBase.MdcaPoint(i));
       
   651 				tabPos = value.LocateReverse('\t');
       
   652 				if (tabPos != KErrNotFound)
       
   653 					value.Set(value.Mid(tabPos + 1));
       
   654 												
       
   655 				data.iCaption.Copy( caption.Left(64) );
       
   656 				data.iValue.Copy( value.Left(32) );
       
   657 							
       
   658 				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
       
   659 				aMessage.WriteL(3, buffer, offset);				
       
   660 				}			
       
   661 			aMessage.WriteL(0, count);
       
   662 					
       
   663 			break;
       
   664 			}
       
   665 		// --- KernelObjects related functions ---
       
   666 		case EMemSpyClientServerOpGetKernelObjectCount:
       
   667 			{
       
   668 			TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
       
   669 			TPckgBuf<TInt> ret( iCount );
       
   670 			aMessage.WriteL(0, ret);			
       
   671 			break;
       
   672 			}
       
   673 		case EMemSpyClientServerOpGetKernelObjects:
       
   674 			{
       
   675 			TPckgBuf<TInt> count;
       
   676 			aMessage.ReadL(0, count);
       
   677 			
       
   678 			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
       
   679 			CleanupStack::PushL( model );
       
   680 			
       
   681 			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
       
   682 				{
       
   683 				TMemSpyKernelObjectData data;
       
   684 				
       
   685 				TPtrC name(model->At(i).Name().Mid(1));
       
   686 				TInt tabPos = name.Locate('\t');
       
   687 				if (tabPos != KErrNotFound)
       
   688 					name.Set(name.Left(tabPos));
       
   689 												
       
   690 				data.iName.Copy(name);
       
   691 				data.iType = model->At(i).Type();
       
   692 				data.iCount = model->At(i).Count();											
       
   693 				data.iSize = model->At(i).Count() * model->At(i).Count();
       
   694 
       
   695 				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
       
   696 				aMessage.WriteL(1, buffer, offset);
       
   697 				}			
       
   698 			aMessage.WriteL(0, count);
       
   699 			CleanupStack::PopAndDestroy( model );
       
   700 			break;
       
   701 			}
       
   702 		case EMemSpyClientServerOpGetKernelObjectItemCount:
       
   703 			{
       
   704 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   705 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   706 			TMemSpyDriverContainerType type = tempType();
       
   707 			
       
   708 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   709 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
       
   710 			CleanupStack::PushL( iObjectList );
       
   711 			
       
   712 			TInt count = iObjectList->Count();
       
   713 			TPckgBuf<TInt> ret( count );
       
   714 			aMessage.WriteL( 0, ret );
       
   715 			
       
   716 			CleanupStack::PopAndDestroy( iObjectList );
       
   717 			break;
       
   718 			}
       
   719 		case EMemSpyClientServerOpGetKernelObjectItems:
       
   720 			{
       
   721 			TPckgBuf<TInt> count;
       
   722 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   723 			aMessage.ReadL( 0, count ); //get count of items
       
   724 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   725 			TInt c = count();
       
   726 						
       
   727 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   728 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
       
   729 			CleanupStack::PushL( iObjectList );
       
   730 			
       
   731 			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
       
   732 				{
       
   733 				TMemSpyDriverHandleInfoGeneric data;								
       
   734 															
       
   735 				data = iObjectList->At( i );
       
   736 				
       
   737 				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
       
   738 				aMessage.WriteL(2, buffer, offset);
       
   739 				}			
       
   740 			
       
   741 			CleanupStack::PopAndDestroy( iObjectList );			
       
   742 			break;
       
   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 			
       
   825 		// --- Kernel Heap related functions ---
       
   826 		case EMemSpyClientServerOpGetHeap:
       
   827 			{
       
   828 			TMemSpyHeapInfo heapInfo;			
       
   829 			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
       
   830 			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
       
   831 			
       
   832 			TPckgBuf<TMemSpyHeapData> buffer(data);
       
   833 			aMessage.WriteL(0, buffer);
       
   834 			
       
   835 			break;
       
   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;
       
   897 		}
       
   898     }
       
   899 
       
   900 // ---------------------------------------------------------
       
   901 // DoCmdServiceL( const RMessage2& aMessage )
       
   902 // ---------------------------------------------------------
       
   903 //
       
   904 void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
       
   905     {
   172     {
   906     TInt error = KErrNone;
   173     TInt error = KErrNone;
   907 
   174 
   908     // Check function attributes
   175     // Check function attributes
   909     const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
   176     const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
  1113 
   380 
  1114 
   381 
  1115 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
   382 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
  1116     {
   383     {
  1117     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
   384     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
  1118     
       
  1119     //
   385     //
  1120     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
   386     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
  1121         {
   387         {
  1122         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
   388         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
  1123         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
   389         iEngine.HelperHeap().OutputHeapInfoForDeviceL();
  1124         	{
       
  1125 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage);
       
  1126         	}
       
  1127         else
       
  1128         	{
       
  1129 			iEngine.HelperHeap().OutputHeapInfoForDeviceL();
       
  1130         	}
       
  1131         }
   390         }
  1132     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
   391     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
  1133         {
   392         {
  1134         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
   393         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
  1135         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
   394         iEngine.HelperStack().OutputStackInfoForDeviceL();
  1136 			{
       
  1137 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage);
       
  1138 			}
       
  1139 		else
       
  1140 			{
       
  1141 			iEngine.HelperStack().OutputStackInfoForDeviceL();
       
  1142 			}
       
  1143         }
   395         }
  1144     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
   396     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
  1145         {
   397         {
  1146         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
   398         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
  1147         iEngine.HelperSysMemTracker().StartL();
   399         iEngine.HelperSysMemTracker().StartL();
  1227         iEngine.HelperSysMemTracker().SetConfigL( config );
   479         iEngine.HelperSysMemTracker().SetConfigL( config );
  1228         }
   480         }
  1229     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
   481     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
  1230         {
   482         {
  1231         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
   483         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
  1232         iEngine.InstallDebugSinkL();
   484         iEngine.InstallSinkL( ESinkTypeDebug );
  1233         }
   485         }
  1234     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
   486     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
  1235         {
   487         {
  1236         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
   488         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
  1237         // Read file name from message.
   489         iEngine.InstallSinkL( ESinkTypeFile );
  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         
       
  1257         }
   490         }
  1258     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
   491     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
  1259         {
   492         {
  1260         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
   493         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
  1261 
   494 
  1282     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
   515     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
  1283         {
   516         {
  1284         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
   517         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
  1285         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
   518         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
  1286         }
   519         }
  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 		}
       
  1327     else
   520     else
  1328         {
   521         {
  1329         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
   522         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
  1330         iEngine.NotifyClientServerOperationRequestL( aFunction );
   523         iEngine.NotifyClientServerOperationRequestL( aFunction );
  1331         }
   524         }
  1332     //
   525     //
  1333     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
   526     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
  1334     }
   527     }
  1335 
   528 
  1336 void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage)
   529 
  1337 	{
   530 
  1338 	if (Server().CurrentOperationTracker())
   531 
  1339 		{
   532 
  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 	}