1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "MemSpyViewThreadInfoItemList.h" |
|
19 |
|
20 // Engine includes |
|
21 #include <memspy/engine/memspyengine.h> |
|
22 #include <memspy/engine/memspyengineobjectprocess.h> |
|
23 #include <memspy/engine/memspyengineobjectthread.h> |
|
24 #include <memspy/engine/memspyengineobjectcontainer.h> |
|
25 #include <memspy/engine/memspyengineobjectthreadinfoobjects.h> |
|
26 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h> |
|
27 #include <memspy/engine/memspyenginehelperprocess.h> |
|
28 |
|
29 // User includes |
|
30 #include "MemSpyContainerObserver.h" |
|
31 #include "MemSpyViewThreads.h" |
|
32 #include "MemSpyViewThreadInfoItemHeap.h" |
|
33 #include "MemSpyViewThreadInfoItemStack.h" |
|
34 #include "MemSpyViewThreadInfoItemChunk.h" |
|
35 #include "MemSpyViewThreadInfoItemCodeSeg.h" |
|
36 #include "MemSpyViewThreadInfoItemServer.h" |
|
37 #include "MemSpyViewThreadInfoItemActiveObject.h" |
|
38 #include "MemSpyViewThreadInfoItemGeneralInfo.h" |
|
39 #include "MemSpyViewThreadInfoItemMemoryTracking.h" |
|
40 |
|
41 // Constants |
|
42 const TInt KMemSpyIdleResetListboxTimerPeriod = 250000; |
|
43 |
|
44 |
|
45 CMemSpyViewThreadInfoItemList::CMemSpyViewThreadInfoItemList( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver, CMemSpyThread& aThread ) |
|
46 : CMemSpyViewBase( aEngine, aObserver ), iThread( aThread ) |
|
47 { |
|
48 iThread.Process().Open(); |
|
49 iThread.Open(); |
|
50 } |
|
51 |
|
52 |
|
53 CMemSpyViewThreadInfoItemList::~CMemSpyViewThreadInfoItemList() |
|
54 { |
|
55 delete iIdleResetListboxTimer; |
|
56 |
|
57 TRAP_IGNORE( |
|
58 CMemSpyThreadInfoContainer& container = iThread.InfoContainerL(); |
|
59 container.ObserverRemove( *this ); |
|
60 ); |
|
61 |
|
62 if ( iCurrentInfoItem ) |
|
63 { |
|
64 iCurrentInfoItem->Close(); |
|
65 } |
|
66 |
|
67 iThread.Process().Close(); |
|
68 iThread.Close(); |
|
69 } |
|
70 |
|
71 |
|
72 |
|
73 void CMemSpyViewThreadInfoItemList::ConstructL( const TRect& aRect, CCoeControl& aContainer, TAny* aSelectionRune ) |
|
74 { |
|
75 _LIT( KTitle, "Thread Objects" ); |
|
76 SetTitleL( KTitle ); |
|
77 // |
|
78 iIdleResetListboxTimer = CPeriodic::NewL( CActive::EPriorityIdle ); |
|
79 // |
|
80 CMemSpyThreadInfoContainer& container = iThread.InfoContainerL(); |
|
81 container.ObserverAddL( *this ); |
|
82 // |
|
83 CMemSpyViewBase::ConstructL( aRect, aContainer, aSelectionRune ); |
|
84 // |
|
85 if ( aSelectionRune ) |
|
86 { |
|
87 CMemSpyThreadInfoItemBase* selectedItem = reinterpret_cast< CMemSpyThreadInfoItemBase* >( aSelectionRune ); |
|
88 const TInt index = container.InfoItemIndexByType( selectedItem->Type() ); |
|
89 if ( index >= 0 && index < iListBox->Model()->NumberOfItems() ) |
|
90 { |
|
91 iListBox->SetCurrentItemIndex( index ); |
|
92 HandleListBoxItemSelectedL( index ); |
|
93 } |
|
94 } |
|
95 else if ( container.MdcaCount() > 0 ) |
|
96 { |
|
97 iListBox->SetCurrentItemIndex( 0 ); |
|
98 HandleListBoxItemSelectedL( 0 ); |
|
99 } |
|
100 } |
|
101 |
|
102 |
|
103 const CMemSpyProcess& CMemSpyViewThreadInfoItemList::Process() const |
|
104 { |
|
105 return iThread.Process(); |
|
106 } |
|
107 |
|
108 |
|
109 const CMemSpyThread& CMemSpyViewThreadInfoItemList::Thread() const |
|
110 { |
|
111 return iThread; |
|
112 } |
|
113 |
|
114 |
|
115 const CMemSpyThreadInfoItemBase& CMemSpyViewThreadInfoItemList::CurrentInfoItem() const |
|
116 { |
|
117 __ASSERT_ALWAYS( iCurrentInfoItem != NULL, User::Invariant() ); |
|
118 return *iCurrentInfoItem; |
|
119 } |
|
120 |
|
121 |
|
122 void CMemSpyViewThreadInfoItemList::RefreshL() |
|
123 { |
|
124 SetListBoxModelL(); |
|
125 CMemSpyViewBase::RefreshL(); |
|
126 } |
|
127 |
|
128 |
|
129 TMemSpyViewType CMemSpyViewThreadInfoItemList::ViewType() const |
|
130 { |
|
131 return EMemSpyViewTypeThreadInfoItemList; |
|
132 } |
|
133 |
|
134 |
|
135 CMemSpyViewBase* CMemSpyViewThreadInfoItemList::PrepareParentViewL() |
|
136 { |
|
137 CMemSpyViewBase* parent = new(ELeave) CMemSpyViewThreads( iEngine, iObserver, iThread.Process() ); |
|
138 CleanupStack::PushL( parent ); |
|
139 parent->ConstructL( Rect(), *Parent(), &iThread ); |
|
140 CleanupStack::Pop( parent ); |
|
141 return parent; |
|
142 } |
|
143 |
|
144 |
|
145 CMemSpyViewBase* CMemSpyViewThreadInfoItemList::PrepareChildViewL() |
|
146 { |
|
147 __ASSERT_ALWAYS( iCurrentInfoItem != NULL, User::Invariant() ); |
|
148 CMemSpyViewBase* child = NULL; |
|
149 |
|
150 // Decide what type of child view to create... |
|
151 const TMemSpyThreadInfoItemType type = iCurrentInfoItem->Type(); |
|
152 // |
|
153 switch( type ) |
|
154 { |
|
155 case EMemSpyThreadInfoItemTypeHeap: |
|
156 child = new(ELeave) CMemSpyViewThreadInfoItemHeap( iEngine, iObserver, iThread.InfoContainerL() ); |
|
157 break; |
|
158 case EMemSpyThreadInfoItemTypeStack: |
|
159 child = new(ELeave) CMemSpyViewThreadInfoItemStack( iEngine, iObserver, iThread.InfoContainerL() ); |
|
160 break; |
|
161 case EMemSpyThreadInfoItemTypeChunk: |
|
162 child = new(ELeave) CMemSpyViewThreadInfoItemChunk( iEngine, iObserver, iThread.InfoContainerL() ); |
|
163 break; |
|
164 case EMemSpyThreadInfoItemTypeCodeSeg: |
|
165 child = new(ELeave) CMemSpyViewThreadInfoItemCodeSeg( iEngine, iObserver, iThread.InfoContainerL() ); |
|
166 break; |
|
167 case EMemSpyThreadInfoItemTypeServer: |
|
168 child = new(ELeave) CMemSpyViewThreadInfoItemServer( iEngine, iObserver, iThread.InfoContainerL() ); |
|
169 break; |
|
170 case EMemSpyThreadInfoItemTypeActiveObject: |
|
171 child = new(ELeave) CMemSpyViewThreadInfoItemActiveObject( iEngine, iObserver, iThread.InfoContainerL() ); |
|
172 break; |
|
173 case EMemSpyThreadInfoItemTypeGeneralInfo: |
|
174 child = new(ELeave) CMemSpyViewThreadInfoItemGeneralInfo( iEngine, iObserver, iThread.InfoContainerL() ); |
|
175 break; |
|
176 case EMemSpyThreadInfoItemTypeMemoryTracking: |
|
177 child = new(ELeave) CMemSpyViewThreadInfoItemMemoryTracking( iEngine, iObserver, iThread.InfoContainerL() ); |
|
178 break; |
|
179 case EMemSpyThreadInfoItemTypeSession: |
|
180 case EMemSpyThreadInfoItemTypeSemaphore: |
|
181 case EMemSpyThreadInfoItemTypeMutex: |
|
182 case EMemSpyThreadInfoItemTypeTimer: |
|
183 case EMemSpyThreadInfoItemTypeLDD: |
|
184 case EMemSpyThreadInfoItemTypePDD: |
|
185 case EMemSpyThreadInfoItemTypeLogicalChannel: |
|
186 case EMemSpyThreadInfoItemTypeChangeNotifier: |
|
187 case EMemSpyThreadInfoItemTypeUndertaker: |
|
188 case EMemSpyThreadInfoItemTypeMessageQueue: |
|
189 case EMemSpyThreadInfoItemTypeConditionalVariable: |
|
190 case EMemSpyThreadInfoItemTypeOpenFiles: |
|
191 case EMemSpyThreadInfoItemTypeOtherThreads: |
|
192 case EMemSpyThreadInfoItemTypeOtherProcesses: |
|
193 case EMemSpyThreadInfoItemTypeOwnedThreadHandles: |
|
194 case EMemSpyThreadInfoItemTypeOwnedProcessHandles: |
|
195 child = new(ELeave) CMemSpyViewThreadInfoItemGeneric( iEngine, iObserver, iThread.InfoContainerL(), type ); |
|
196 break; |
|
197 |
|
198 default: |
|
199 __ASSERT_ALWAYS( EFalse, User::Panic( _L("MemSpy-View"), 0) ); |
|
200 break; |
|
201 } |
|
202 // |
|
203 CleanupStack::PushL( child ); |
|
204 child->ConstructL( Rect(), *Parent() ); |
|
205 CleanupStack::Pop( child ); |
|
206 return child; |
|
207 } |
|
208 |
|
209 |
|
210 TBool CMemSpyViewThreadInfoItemList::HandleCommandL( TInt aCommand ) |
|
211 { |
|
212 TBool handled = ETrue; |
|
213 // |
|
214 switch ( aCommand ) |
|
215 { |
|
216 case EMemSpyCmdThreadInfoHandles: |
|
217 OnCmdInfoHandlesL(); |
|
218 break; |
|
219 |
|
220 default: |
|
221 handled = CMemSpyViewBase::HandleCommandL( aCommand ); |
|
222 break; |
|
223 } |
|
224 // |
|
225 return handled; |
|
226 } |
|
227 |
|
228 |
|
229 void CMemSpyViewThreadInfoItemList::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ) |
|
230 { |
|
231 if ( aResourceId == R_MEMSPY_MENUPANE ) |
|
232 { |
|
233 aMenuPane->SetItemDimmed( EMemSpyCmdThread, iThread.IsDead() ); |
|
234 } |
|
235 else if ( aResourceId == MenuCascadeResourceId() ) |
|
236 { |
|
237 // Always remove these items - they are only shown in the master thread view |
|
238 aMenuPane->SetItemDimmed( EMemSpyCmdThreadSetPriority, ETrue ); |
|
239 aMenuPane->SetItemDimmed( EMemSpyCmdThreadEnd, ETrue ); |
|
240 } |
|
241 } |
|
242 |
|
243 |
|
244 void CMemSpyViewThreadInfoItemList::OnCmdInfoHandlesL() |
|
245 { |
|
246 iThread.InfoContainerForceSyncronousConstructionL().PrintL(); |
|
247 } |
|
248 |
|
249 |
|
250 void CMemSpyViewThreadInfoItemList::HandleMemSpyEngineInfoContainerEventL( TEvent aEvent, TMemSpyThreadInfoItemType aType ) |
|
251 { |
|
252 if ( aEvent == EInfoItemChanged ) |
|
253 { |
|
254 } |
|
255 else if ( aEvent == EInfoItemDestroyed ) |
|
256 { |
|
257 if ( iCurrentInfoItem && iCurrentInfoItem->Type() == aType ) |
|
258 { |
|
259 iCurrentInfoItem->Close(); |
|
260 iCurrentInfoItem = NULL; |
|
261 } |
|
262 } |
|
263 |
|
264 iIdleResetListboxTimer->Cancel(); |
|
265 iIdleResetListboxTimer->Start( KMemSpyIdleResetListboxTimerPeriod, KMemSpyIdleResetListboxTimerPeriod, TCallBack( IdleUpdateListBoxModel, this ) ); |
|
266 } |
|
267 |
|
268 |
|
269 void CMemSpyViewThreadInfoItemList::SetListBoxModelL() |
|
270 { |
|
271 CAknSettingStyleListBox* listbox = static_cast< CAknSettingStyleListBox* >( iListBox ); |
|
272 listbox->Model()->SetItemTextArray( &iThread.InfoContainerL() ); |
|
273 listbox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); |
|
274 } |
|
275 |
|
276 |
|
277 void CMemSpyViewThreadInfoItemList::HandleListBoxItemActionedL( TInt /*aIndex*/ ) |
|
278 { |
|
279 // Notify observer about an item being 'fired' |
|
280 ReportEventL( MMemSpyViewObserver::EEventItemActioned ); |
|
281 } |
|
282 |
|
283 |
|
284 void CMemSpyViewThreadInfoItemList::HandleListBoxItemSelectedL( TInt aIndex ) |
|
285 { |
|
286 if ( iCurrentInfoItem ) |
|
287 { |
|
288 CMemSpyThreadInfoItemBase* item = iCurrentInfoItem; |
|
289 iCurrentInfoItem = NULL; |
|
290 item->Close(); |
|
291 } |
|
292 |
|
293 // Identify the type of item to display... |
|
294 iCurrentInfoItem = &iThread.InfoContainerL().Item( aIndex ); |
|
295 iCurrentInfoItem->Open(); |
|
296 |
|
297 // Notify observer about item selection |
|
298 ReportEventL( MMemSpyViewObserver::EEventItemSelected ); |
|
299 } |
|
300 |
|
301 |
|
302 TInt CMemSpyViewThreadInfoItemList::IdleUpdateListBoxModel( TAny* aSelf ) |
|
303 { |
|
304 CMemSpyViewThreadInfoItemList* self = reinterpret_cast< CMemSpyViewThreadInfoItemList* >( aSelf ); |
|
305 TRAP_IGNORE( self->DoIdleUpdateListBoxModelL() ); |
|
306 return EFalse; |
|
307 } |
|
308 |
|
309 |
|
310 void CMemSpyViewThreadInfoItemList::DoIdleUpdateListBoxModelL() |
|
311 { |
|
312 CMemSpyThreadInfoContainer& container = iThread.InfoContainerL(); |
|
313 |
|
314 // Try to maintain current item selection if at all possible. |
|
315 TMemSpyThreadInfoItemType type = EMemSpyThreadInfoItemTypeHeap; |
|
316 if ( iCurrentInfoItem ) |
|
317 { |
|
318 type = iCurrentInfoItem->Type(); |
|
319 } |
|
320 |
|
321 // Update list box & model |
|
322 SetListBoxModelL(); |
|
323 iListBox->HandleItemAdditionL(); |
|
324 RefreshL(); |
|
325 |
|
326 // Try to select previous item if it is still available |
|
327 const TInt index = container.InfoItemIndexByType( type ); |
|
328 if ( index >= 0 && index < container.MdcaCount() ) |
|
329 { |
|
330 iListBox->SetCurrentItemIndex( index ); |
|
331 HandleListBoxItemSelectedL( index ); |
|
332 } |
|
333 |
|
334 iIdleResetListboxTimer->Cancel(); |
|
335 } |
|
336 |
|