18 package com.nokia.carbide.cpp.pi.address; |
18 package com.nokia.carbide.cpp.pi.address; |
19 |
19 |
20 import java.io.File; |
20 import java.io.File; |
21 import java.io.IOException; |
21 import java.io.IOException; |
22 import java.io.Serializable; |
22 import java.io.Serializable; |
|
23 import java.net.URL; |
23 import java.util.ArrayList; |
24 import java.util.ArrayList; |
24 import java.util.Enumeration; |
25 import java.util.Enumeration; |
25 import java.util.Hashtable; |
26 import java.util.Hashtable; |
26 import java.util.Vector; |
27 import java.util.Vector; |
27 |
28 |
|
29 import org.eclipse.core.runtime.FileLocator; |
|
30 import org.eclipse.core.runtime.IPath; |
|
31 import org.eclipse.core.runtime.Path; |
|
32 import org.eclipse.draw2d.FigureCanvas; |
28 import org.eclipse.jface.action.Action; |
33 import org.eclipse.jface.action.Action; |
|
34 import org.eclipse.jface.action.IAction; |
29 import org.eclipse.jface.action.MenuManager; |
35 import org.eclipse.jface.action.MenuManager; |
30 import org.eclipse.jface.action.Separator; |
36 import org.eclipse.jface.action.Separator; |
31 import org.eclipse.jface.resource.ImageDescriptor; |
37 import org.eclipse.jface.resource.ImageDescriptor; |
32 import org.eclipse.swt.SWT; |
38 import org.eclipse.swt.SWT; |
33 import org.eclipse.swt.events.SelectionAdapter; |
39 import org.eclipse.swt.events.SelectionAdapter; |
34 import org.eclipse.swt.events.SelectionEvent; |
40 import org.eclipse.swt.events.SelectionEvent; |
35 import org.eclipse.swt.graphics.Color; |
|
36 import org.eclipse.swt.graphics.RGB; |
|
37 import org.eclipse.swt.layout.FillLayout; |
41 import org.eclipse.swt.layout.FillLayout; |
38 import org.eclipse.swt.widgets.Composite; |
42 import org.eclipse.swt.widgets.Composite; |
39 import org.eclipse.swt.widgets.Display; |
43 import org.eclipse.swt.widgets.Display; |
40 import org.eclipse.swt.widgets.Event; |
44 import org.eclipse.swt.widgets.Event; |
41 import org.eclipse.swt.widgets.FileDialog; |
45 import org.eclipse.swt.widgets.FileDialog; |
42 import org.eclipse.swt.widgets.Shell; |
46 import org.eclipse.swt.widgets.Shell; |
43 import org.eclipse.swt.widgets.Text; |
47 import org.eclipse.swt.widgets.Text; |
44 import org.eclipse.ui.PlatformUI; |
48 import org.eclipse.ui.PlatformUI; |
|
49 import org.osgi.framework.Bundle; |
45 import org.osgi.framework.BundleContext; |
50 import org.osgi.framework.BundleContext; |
46 |
51 |
47 import com.nokia.carbide.cpp.internal.pi.actions.SetThresholdsDialog; |
52 import com.nokia.carbide.cpp.internal.pi.actions.SetThresholdsDialog; |
48 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; |
53 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; |
49 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser; |
54 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser; |
57 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread; |
62 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread; |
58 import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository; |
63 import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository; |
59 import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin; |
64 import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin; |
60 import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer; |
65 import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer; |
61 import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener; |
66 import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener; |
|
67 import com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace; |
62 import com.nokia.carbide.cpp.internal.pi.plugin.model.IRecordable; |
68 import com.nokia.carbide.cpp.internal.pi.plugin.model.IRecordable; |
63 import com.nokia.carbide.cpp.internal.pi.plugin.model.IReportable; |
69 import com.nokia.carbide.cpp.internal.pi.plugin.model.IReportable; |
64 import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace; |
70 import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace; |
|
71 import com.nokia.carbide.cpp.internal.pi.plugin.model.ITraceSMP; |
65 import com.nokia.carbide.cpp.internal.pi.plugin.model.IViewMenu; |
72 import com.nokia.carbide.cpp.internal.pi.plugin.model.IViewMenu; |
66 import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable; |
73 import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable; |
67 import com.nokia.carbide.cpp.internal.pi.resolvers.SymbolFileFunctionResolver; |
74 import com.nokia.carbide.cpp.internal.pi.resolvers.SymbolFileFunctionResolver; |
68 import com.nokia.carbide.cpp.internal.pi.test.AnalysisInfoHandler; |
75 import com.nokia.carbide.cpp.internal.pi.test.AnalysisInfoHandler; |
69 import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities; |
76 import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities; |
70 import com.nokia.carbide.cpp.internal.pi.visual.Defines; |
|
71 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph; |
|
72 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest; |
77 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest; |
73 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; |
78 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; |
74 import com.nokia.carbide.cpp.pi.core.SessionPreferences; |
79 import com.nokia.carbide.cpp.pi.core.SessionPreferences; |
75 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
80 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
76 import com.nokia.carbide.cpp.pi.importer.SampleImporter; |
81 import com.nokia.carbide.cpp.pi.importer.SampleImporter; |
77 import com.nokia.carbide.cpp.pi.util.ColorPalette; |
|
78 import com.nokia.carbide.cpp.pi.util.GeneralMessages; |
82 import com.nokia.carbide.cpp.pi.util.GeneralMessages; |
79 |
83 |
80 |
84 |
81 /** |
85 /** |
82 * The main plugin class to be used in the desktop. |
86 * The main plugin class to be used in the desktop. |
83 */ |
87 */ |
84 public class AddressPlugin extends AbstractPiPlugin |
88 public class AddressPlugin extends AbstractPiPlugin |
85 implements ITrace, IViewMenu, IClassReplacer, //IExportItem, |
89 implements ITrace, ITraceSMP, IViewMenu, IClassReplacer, //IExportItem, |
86 IReportable, IRecordable, IVisualizable, IEventListener |
90 IReportable, IRecordable, IVisualizable, IEventListener, IFinalizeTrace |
87 { |
91 { |
88 private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".address"; //$NON-NLS-1$ |
92 private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".address"; //$NON-NLS-1$ |
|
93 |
|
94 public static final String ACTION_COMBINED_CPU_VIEW = "combined_cpu_view";//$NON-NLS-1$ |
|
95 public static final String ACTION_SEPARATE_CPU_VIEW = "separate_cpu_view";//$NON-NLS-1$ |
|
96 public static final int[] TRACE_IDS_SMP = new int[]{1, 21, 41, 62}; |
|
97 |
89 |
98 |
90 // private static HashMap<Integer,Long> uidToAddrThreadPeriod = new HashMap<Integer,Long>(); |
99 // private static HashMap<Integer,Long> uidToAddrThreadPeriod = new HashMap<Integer,Long>(); |
91 |
100 |
92 // There will be three graphs - one each for editor pages 0, 1, 2 |
101 // There will be three graphs - one each for editor pages 0, 1, 2 |
93 // This code assumes that page 0 has the threads graph, 1 the binaries, and 2 the functions |
102 // This code assumes that page 0 has the threads graph, 1 the binaries, and 2 the functions |
94 private final static int GRAPH_COUNT = 3; |
103 //private final static int GRAPH_COUNT = 3; |
|
104 private final static int PAGE_COUNT = 3; |
95 private boolean pagesCreated = false; |
105 private boolean pagesCreated = false; |
|
106 |
|
107 private IAction actionCombinedCpuView; |
|
108 private IAction actionSeparateCpuView; |
96 |
109 |
97 // The shared instance. |
110 // The shared instance. |
98 private static AddressPlugin plugin; |
111 private static AddressPlugin plugin; |
99 |
112 |
100 private int functionsShown = 10; |
113 private int functionsShown = 10; |
170 if (trace.samples.size() > 2) { |
189 if (trace.samples.size() > 2) { |
171 // because of a problem in older samplers, the first address/thread sample may have been thrown out |
190 // because of a problem in older samplers, the first address/thread sample may have been thrown out |
172 samplingInterval = (int) (((GppSample) trace.samples.get(1)).sampleSynchTime - ((GppSample) trace.samples.get(0)).sampleSynchTime); |
191 samplingInterval = (int) (((GppSample) trace.samples.get(1)).sampleSynchTime - ((GppSample) trace.samples.get(0)).sampleSynchTime); |
173 } |
192 } |
174 |
193 |
175 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval", new Integer(samplingInterval)); //$NON-NLS-1$ |
194 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval", Integer.valueOf(samplingInterval)); //$NON-NLS-1$ |
176 |
195 |
177 // make sure that the sorted samples array exists |
196 // make sure that the sorted samples array exists |
178 if (trace.getSortedGppSamples() == null) |
197 if (trace.getSortedGppSamples() == null) |
179 trace.sortGppSamples(); |
198 trace.sortGppSamples(); |
180 |
199 |
181 GppTraceGraph.refreshDataFromTrace(trace); |
200 trace.refreshDataFromTrace(this.getGraphCount()); |
182 PIPageEditor.setTime(0.0f, 0.0f); |
201 // PIPageEditor.setTime(0.0f, 0.0f); |
183 long lastSampleTime = trace.getSample(trace.samples.size() - 1).sampleSynchTime; |
202 long lastSampleTime = trace.getSample(trace.samples.size() - 1).sampleSynchTime; |
184 PIPageEditor.currentPageEditor().setMaxEndTime(((double)lastSampleTime) / 1000.0f); |
203 PIPageEditor.currentPageEditor().setMaxEndTime(((double)lastSampleTime) / 1000.0f); |
185 } |
204 } |
186 |
205 |
187 public GppTrace getTrace() |
206 public GppTrace getTrace() |
188 { |
207 { |
189 return (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
208 return (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
190 } |
209 } |
191 |
210 |
192 public GenericTraceGraph getTraceGraph(int graphIndex) |
211 public IGppTraceGraph getTraceGraph(int graphIndex) |
193 { |
212 { |
194 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
213 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
195 |
214 |
196 if (trace != null) { |
215 if (trace != null) { |
197 int uid = NpiInstanceRepository.getInstance().activeUid(); |
216 int uid = NpiInstanceRepository.getInstance().activeUid(); |
203 public GenericTrace getTrace(int graphIndex) |
222 public GenericTrace getTrace(int graphIndex) |
204 { |
223 { |
205 return (GenericTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
224 return (GenericTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
206 } |
225 } |
207 |
226 |
208 /* |
|
209 public GenericTraceGraph getTraceGraph(int graphIndex, int uid) |
|
210 { |
|
211 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
|
212 |
|
213 // if we already had it, then we can pass in the formatted trace data |
|
214 return trace.getTraceGraph(graphIndex, uid); |
|
215 } |
|
216 */ |
|
217 |
|
218 public Integer getLastSample(int graphIndex) |
227 public Integer getLastSample(int graphIndex) |
219 { |
228 { |
220 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
229 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
221 |
230 |
222 if (trace == null) |
231 if (trace == null) |
223 return null; |
232 return null; |
224 |
233 |
225 //this sets GPP thread list visible by default |
234 //this sets GPP thread list visible by default |
226 ((GppTraceGraph)trace.getTraceGraph(graphIndex)).piEventReceived(new PIEvent(null, PIEvent.MOUSE_PRESSED)); |
235 trace.getTraceGraph(graphIndex).piEventReceived(new PIEvent(null, PIEvent.MOUSE_PRESSED)); |
227 |
236 |
228 return new Integer(trace.getLastSampleNumber()); |
237 return Integer.valueOf(trace.getLastSampleNumber()); |
229 } |
238 } |
230 |
239 |
231 public GraphDrawRequest getDrawRequest(int graphIndex) { |
240 public GraphDrawRequest getDrawRequest(int graphIndex) { |
232 return null; |
241 return null; |
233 } |
242 } |
234 |
243 |
|
244 /** |
|
245 * Converts the given event string into a PIEvent if necessary, and passes it to the appropriate graph |
|
246 * @param eventString the event string indicating the action to be executed |
|
247 */ |
235 public void receiveSelectionEvent(String eventString) |
248 public void receiveSelectionEvent(String eventString) |
236 { |
249 { |
237 if (eventString == null) |
250 if (eventString == null) |
238 return; |
251 return; |
239 |
252 |
247 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
260 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
248 |
261 |
249 if (eventString.equals("fillSelected")) //$NON-NLS-1$ |
262 if (eventString.equals("fillSelected")) //$NON-NLS-1$ |
250 { |
263 { |
251 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_SELECTED_THREAD); |
264 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_SELECTED_THREAD); |
252 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
265 for (int i = 0; i < getGraphCount(); i++) { |
253 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
266 trace.getTraceGraph(i).piEventReceived(be); |
254 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
267 } |
255 |
268 |
256 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$ |
269 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$ |
257 } |
270 } |
258 else if (eventString.equals("fillAll")) //$NON-NLS-1$ |
271 else if (eventString.equals("fillAll")) //$NON-NLS-1$ |
259 { |
272 { |
260 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_ALL_THREADS); |
273 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_ALL_THREADS); |
261 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
274 for (int i = 0; i < getGraphCount(); i++) { |
262 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
275 trace.getTraceGraph(i).piEventReceived(be); |
263 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
276 } |
264 |
277 |
265 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.TRUE); //$NON-NLS-1$ |
278 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.TRUE); //$NON-NLS-1$ |
266 } |
279 } |
267 else if (eventString.equals("fillNone")) //$NON-NLS-1$ |
280 else if (eventString.equals("fillNone")) //$NON-NLS-1$ |
268 { |
281 { |
269 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_OFF); |
282 PIEvent be = new PIEvent(null, PIEvent.SET_FILL_OFF); |
270 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
283 for (int i = 0; i < getGraphCount(); i++) { |
271 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
284 trace.getTraceGraph(i).piEventReceived(be); |
272 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
285 } |
273 |
286 |
274 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$ |
287 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$ |
275 } |
288 } |
276 else if (eventString.equals("setBarOn")) //$NON-NLS-1$ |
289 else if (eventString.equals("setBarOn")) //$NON-NLS-1$ |
277 { |
290 { |
278 PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_ON); |
291 PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_ON); |
279 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
292 for (int i = 0; i < getGraphCount(); i++) { |
280 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
293 trace.getTraceGraph(i).piEventReceived(be); |
281 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
294 } |
282 |
295 |
283 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.TRUE); //$NON-NLS-1$ |
296 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.TRUE); //$NON-NLS-1$ |
284 } |
297 } |
285 else if (eventString.equals("setBarOff")) //$NON-NLS-1$ |
298 else if (eventString.equals("setBarOff")) //$NON-NLS-1$ |
286 { |
299 { |
287 PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_OFF); |
300 PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_OFF); |
288 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
301 for (int i = 0; i < getGraphCount(); i++) { |
289 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
302 trace.getTraceGraph(i).piEventReceived(be); |
290 ((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
303 } |
291 |
304 |
292 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.FALSE); //$NON-NLS-1$ |
305 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.FALSE); //$NON-NLS-1$ |
293 } |
306 } |
294 else if (eventString.equals("resetToCurrentMode")) //$NON-NLS-1$ |
307 else if (eventString.equals("resetToCurrentMode")) //$NON-NLS-1$ |
295 { |
308 { |
296 ((GppTraceGraph)trace.getTraceGraph(currentPage)).action(eventString); |
309 trace.getTraceGraph(currentPage).action(eventString); |
297 } |
310 } else if (eventString.equals(ACTION_COMBINED_CPU_VIEW) || eventString.equals(ACTION_SEPARATE_CPU_VIEW)){ |
|
311 boolean showCombined = eventString.equals(ACTION_COMBINED_CPU_VIEW); |
|
312 |
|
313 if (currentPage == PIPageEditor.THREADS_PAGE){ |
|
314 trace.getGppGraph(PIPageEditor.THREADS_PAGE, -1).setVisible(showCombined); |
|
315 for (int cpu = 0; cpu < trace.getCPUCount(); cpu++) { |
|
316 trace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE + 1 + cpu, -1).setVisible(!showCombined); |
|
317 } |
|
318 |
|
319 ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages(); |
|
320 //hiding of graphs needs to take affect |
|
321 pages.get(PIPageEditor.THREADS_PAGE).getTopComposite().getSashForm().layout(); |
|
322 if (actionCombinedCpuView != null && actionCombinedCpuView.isChecked() != showCombined){ |
|
323 actionCombinedCpuView.setChecked(showCombined); |
|
324 } |
|
325 if (actionSeparateCpuView != null && actionSeparateCpuView.isChecked() == showCombined){ |
|
326 actionSeparateCpuView.setChecked(!showCombined); |
|
327 } |
|
328 } |
|
329 |
|
330 |
|
331 NpiInstanceRepository.getInstance().activeUidSetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW, showCombined); //$NON-NLS-1$ |
|
332 |
|
333 } |
298 } |
334 } |
299 |
335 |
300 public String getTraceName() { |
336 public String getTraceName() { |
301 return "Address/Thread"; //$NON-NLS-1$ |
337 return "Address/Thread"; //$NON-NLS-1$ |
302 } |
338 } |
303 |
339 |
|
340 /* (non-Javadoc) |
|
341 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle() |
|
342 */ |
|
343 public String getTraceTitle() { |
|
344 return Messages.getString("AddressPlugin.21"); //$NON-NLS-1$ |
|
345 } |
|
346 |
304 public int getTraceId() { |
347 public int getTraceId() { |
305 return 1; |
348 return 1; |
306 } |
349 } |
307 |
350 |
308 public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws IOException |
351 /* (non-Javadoc) |
|
352 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceIdsSMP() |
|
353 */ |
|
354 public int[] getTraceIdsSMP() { |
|
355 return TRACE_IDS_SMP; |
|
356 } |
|
357 |
|
358 public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws IOException{ |
|
359 return parseTraceFiles(new File[]{file}); |
|
360 } |
|
361 |
|
362 public ParsedTraceData parseTraceFiles(File[] files) throws IOException |
309 { |
363 { |
310 // progressBar.setString("Parsing address and thread trace"); |
364 // progressBar.setString("Parsing address and thread trace"); |
311 |
365 |
312 GppTraceParser gppParser = new GppTraceParser(); |
366 GppTraceParser gppParser = new GppTraceParser(); |
313 ParsedTraceData parsed = gppParser.parse(file); |
367 ParsedTraceData parsed = gppParser.parse(files); |
314 SymbolFileFunctionResolver sffp = this.resolveSymbolFileParser(/*progressBar*/); |
368 SymbolFileFunctionResolver sffp = this.resolveSymbolFileParser(/*progressBar*/); |
315 |
369 |
316 parsed.functionResolvers = new FunctionResolver[]{sffp}; |
370 parsed.functionResolvers = new FunctionResolver[]{sffp}; |
317 |
371 |
318 return parsed; |
372 return parsed; |
640 // action.setToolTipText(Messages.getString("AddressPlugin.saveSamplesToolTip")); //$NON-NLS-1$ |
702 // action.setToolTipText(Messages.getString("AddressPlugin.saveSamplesToolTip")); //$NON-NLS-1$ |
641 // manager.add(action); |
703 // manager.add(action); |
642 |
704 |
643 manager.add(new Separator()); |
705 manager.add(new Separator()); |
644 |
706 |
645 action = new Action(Messages.getString("AddressPlugin.12"), Action.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
707 action = new Action(Messages.getString("AddressPlugin.12"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
708 @Override |
646 public void run() { |
709 public void run() { |
647 new SetThresholdsDialog(Display.getCurrent()); |
710 new SetThresholdsDialog(Display.getCurrent()); |
648 } |
711 } |
649 }; |
712 }; |
650 action.setToolTipText(Messages.getString("AddressPlugin.24")); //$NON-NLS-1$ |
713 action.setToolTipText(Messages.getString("AddressPlugin.24")); //$NON-NLS-1$ |
651 manager.add(action); |
714 manager.add(action); |
|
715 |
|
716 manager.add(new Separator()); |
|
717 |
|
718 |
|
719 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
|
720 |
|
721 if (trace != null && trace.getCPUCount() > 1){ |
|
722 //the following are SMP-related view options |
|
723 manager.add(new Separator()); |
|
724 |
|
725 boolean showCombinedCPUView = true; |
|
726 |
|
727 obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW); |
|
728 if ((obj != null) && (obj instanceof Boolean)){ |
|
729 showCombinedCPUView = (Boolean)obj; |
|
730 } |
|
731 |
|
732 actionCombinedCpuView = new Action(Messages.getString("AddressPlugin.14"), IAction.AS_RADIO_BUTTON) { //$NON-NLS-1$ |
|
733 @Override |
|
734 public void run() { |
|
735 if (this.isChecked()){ |
|
736 receiveSelectionEvent(ACTION_COMBINED_CPU_VIEW); |
|
737 } |
|
738 } |
|
739 }; |
|
740 actionCombinedCpuView.setChecked(showCombinedCPUView); |
|
741 actionCombinedCpuView.setToolTipText(Messages.getString("AddressPlugin.18")); //$NON-NLS-1$ |
|
742 manager.add(actionCombinedCpuView); |
|
743 |
|
744 actionSeparateCpuView = new Action(Messages.getString("AddressPlugin.19"), IAction.AS_RADIO_BUTTON) { //$NON-NLS-1$ |
|
745 @Override |
|
746 public void run() { |
|
747 if (this.isChecked()){ |
|
748 receiveSelectionEvent(ACTION_SEPARATE_CPU_VIEW); |
|
749 } |
|
750 } |
|
751 }; |
|
752 actionSeparateCpuView.setChecked(!showCombinedCPUView); |
|
753 actionSeparateCpuView.setToolTipText(Messages.getString("AddressPlugin.20")); //$NON-NLS-1$ |
|
754 manager.add(actionSeparateCpuView); |
|
755 |
|
756 } |
652 |
757 |
653 return manager; |
758 return manager; |
654 } |
759 } |
655 |
760 |
656 public Serializable getAdditionalData() |
761 public Serializable getAdditionalData() |
707 if (!(data instanceof Vector)) |
812 if (!(data instanceof Vector)) |
708 return; |
813 return; |
709 |
814 |
710 try { |
815 try { |
711 final GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
816 final GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
712 |
817 int uid = NpiInstanceRepository.getInstance().activeUid(); |
713 Vector<Object> tmpData = (Vector<Object>)data; |
818 trace.setAdditionalData((Vector<Object>)data); |
714 Hashtable<Integer,java.awt.Color> threadColors = (Hashtable<Integer,java.awt.Color>)tmpData.elementAt(0); |
|
715 Hashtable<String,java.awt.Color> binaryColors = (Hashtable<String,java.awt.Color>)tmpData.elementAt(1); |
|
716 Hashtable<String,java.awt.Color> functionColors = (Hashtable<String,java.awt.Color>)tmpData.elementAt(2); |
|
717 |
|
718 boolean changed; |
|
719 Enumeration<ProfiledGeneric> e; |
|
720 |
|
721 changed = false; |
|
722 e = trace.getSortedThreadsElements(); |
|
723 while (e.hasMoreElements()) |
|
724 { |
|
725 ProfiledThread pt = (ProfiledThread)e.nextElement(); |
|
726 // backward compatibility with old Swing Color |
|
727 java.awt.Color tmpAWTColor = threadColors.get(new Integer(pt.getThreadId())); |
|
728 if (tmpAWTColor != null) { |
|
729 Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue())); |
|
730 if (color != null) { |
|
731 pt.setColor(color); |
|
732 changed = true; |
|
733 } |
|
734 } |
|
735 } |
|
736 |
|
737 final int uid = NpiInstanceRepository.getInstance().activeUid(); |
|
738 |
|
739 if (changed) { |
|
740 // need to provide new colors for the thread load table |
|
741 trace.getGppGraph(PIPageEditor.THREADS_PAGE, uid).getThreadTable().addColor(Defines.THREADS); |
|
742 } |
|
743 |
|
744 changed = false; |
|
745 e = trace.getSortedBinariesElements(); |
|
746 while (e.hasMoreElements()) |
|
747 { |
|
748 ProfiledBinary pb = (ProfiledBinary)e.nextElement(); |
|
749 // backward compatibility with old Swing Color |
|
750 java.awt.Color tmpAWTColor = binaryColors.get(pb.getNameString()); |
|
751 if (tmpAWTColor != null) { |
|
752 Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue())); |
|
753 if (color != null) { |
|
754 pb.setColor(color); |
|
755 changed = true; |
|
756 } |
|
757 } |
|
758 } |
|
759 |
|
760 if (changed) { |
|
761 // need to provide new colors for the binary load table |
|
762 trace.getGppGraph(PIPageEditor.BINARIES_PAGE, uid).getBinaryTable().addColor(Defines.BINARIES); |
|
763 } |
|
764 |
|
765 changed = false; |
|
766 e = trace.getSortedFunctionsElements(); |
|
767 while (e.hasMoreElements()) |
|
768 { |
|
769 ProfiledFunction pb = (ProfiledFunction)e.nextElement(); |
|
770 // backward compatibility with old Swing Color |
|
771 java.awt.Color tmpAWTColor = functionColors.get(pb.getNameString()); |
|
772 if (tmpAWTColor != null) { |
|
773 Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue())); |
|
774 if (color != null) { |
|
775 pb.setColor(color); |
|
776 changed = true; |
|
777 } |
|
778 } |
|
779 } |
|
780 |
|
781 if (changed) { |
|
782 // need to provide new colors for the binary load table |
|
783 trace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getFunctionTable().addColor(Defines.FUNCTIONS); |
|
784 } |
|
785 |
819 |
786 } catch (Exception e) { |
820 } catch (Exception e) { |
787 System.out.println("Could not load additional address/thread data!"); //$NON-NLS-1$ |
821 System.out.println("Could not load additional address/thread data!"); //$NON-NLS-1$ |
788 // e.printStackTrace(); |
822 // e.printStackTrace(); |
789 } |
823 } |
820 */ |
854 */ |
821 public static ImageDescriptor getImageDescriptor(String path) { |
855 public static ImageDescriptor getImageDescriptor(String path) { |
822 return AbstractPiPlugin.imageDescriptorFromPlugin("com.nokia.carbide.cpp.pi.address", path); //$NON-NLS-1$ |
856 return AbstractPiPlugin.imageDescriptorFromPlugin("com.nokia.carbide.cpp.pi.address", path); //$NON-NLS-1$ |
823 } |
857 } |
824 |
858 |
825 // number of graphs supplied by this plugin |
859 /** |
|
860 * number of graphs supplied by this plugin |
|
861 */ |
826 public int getGraphCount() { |
862 public int getGraphCount() { |
827 return GRAPH_COUNT; |
863 final GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
|
864 int graphCount = trace.getCPUCount() > 1 ? PAGE_COUNT + trace.getCPUCount() : PAGE_COUNT; |
|
865 return graphCount; |
828 } |
866 } |
829 |
867 |
830 // page number of each graph supplied by this plugin |
868 // page number of each graph supplied by this plugin |
|
869 // in IVisualizable |
831 public int getPageNumber(int graphIndex) { |
870 public int getPageNumber(int graphIndex) { |
|
871 return AddressPlugin.getPageIndex(graphIndex); |
|
872 } |
|
873 |
|
874 /** |
|
875 * Returns the index of the page for the graph with this graphIndex |
|
876 * @param graphIndex the index of the graph |
|
877 * @return the page index, one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE |
|
878 */ |
|
879 public static int getPageIndex(int graphIndex){ |
832 if (graphIndex == 0) |
880 if (graphIndex == 0) |
833 return PIPageEditor.THREADS_PAGE; |
881 return PIPageEditor.THREADS_PAGE; |
834 else if (graphIndex == 1) |
882 else if (graphIndex == 1) |
835 return PIPageEditor.BINARIES_PAGE; |
883 return PIPageEditor.BINARIES_PAGE; |
836 else if (graphIndex == 2) |
884 else if (graphIndex == 2) |
837 return PIPageEditor.FUNCTIONS_PAGE; |
885 return PIPageEditor.FUNCTIONS_PAGE; |
838 |
886 else |
839 return PIPageEditor.NEXT_AVAILABLE_PAGE; |
887 return PIPageEditor.THREADS_PAGE; //all SMP graphs go onto the threads page for now |
840 } |
888 } |
841 |
889 |
842 // return whether this plugin's editor pages have been created |
890 // return whether this plugin's editor pages have been created |
843 public boolean arePagesCreated() { |
891 public boolean arePagesCreated() { |
844 return this.pagesCreated; |
892 return this.pagesCreated; |
880 if (parent == null) { |
928 if (parent == null) { |
881 // no parent composite is only for temp instance used by non-GUI importer |
929 // no parent composite is only for temp instance used by non-GUI importer |
882 GeneralMessages.showErrorMessage("Address trace failed to create UI"); //$NON-NLS-1$ |
930 GeneralMessages.showErrorMessage("Address trace failed to create UI"); //$NON-NLS-1$ |
883 return null; |
931 return null; |
884 } |
932 } |
|
933 pageHelp = getPageHelpContextId(index); |
885 |
934 |
886 if (index == 0) { |
935 if (index == 0) { |
887 pageName = "Threads"; //$NON-NLS-1$ |
936 pageName = "Threads"; //$NON-NLS-1$ |
888 pageHelp = "threadsPageContext"; //$NON-NLS-1$ |
|
889 } else if (index == 1) { |
937 } else if (index == 1) { |
890 pageName = "Binaries"; //$NON-NLS-1$ |
938 pageName = "Binaries"; //$NON-NLS-1$ |
891 pageHelp = "binariesPageContext"; //$NON-NLS-1$ |
|
892 } else if (index == 2) { |
939 } else if (index == 2) { |
893 pageName = "Functions"; //$NON-NLS-1$ |
940 pageName = "Functions"; //$NON-NLS-1$ |
894 pageHelp = "functionsPageContext"; //$NON-NLS-1$ |
941 } |
895 } else { |
942 else { |
896 return null; |
943 return null; |
897 } |
944 } |
898 |
945 |
899 ProfileVisualiser pV = new ProfileVisualiser(ProfileVisualiser.TOP_AND_BOTTOM, parent, pageName); |
946 ProfileVisualiser pV = new ProfileVisualiser(ProfileVisualiser.TOP_AND_BOTTOM, parent, pageName); |
900 int uid = NpiInstanceRepository.getInstance().activeUid(); |
947 int uid = NpiInstanceRepository.getInstance().activeUid(); |
901 AnalysisInfoHandler infoHandler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler(); |
948 AnalysisInfoHandler infoHandler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler(); |
902 pV.getParserRepository().setPIAnalysisInfoHandler(infoHandler); |
949 pV.getParserRepository().setPIAnalysisInfoHandler(infoHandler); |
903 PlatformUI.getWorkbench().getHelpSystem().setHelp(pV.getContentPane(), HELP_CONTEXT_ID + "." + pageHelp); //$NON-NLS-1$ |
950 PlatformUI.getWorkbench().getHelpSystem().setHelp(pV.getContentPane(), pageHelp); //$NON-NLS-1$ |
904 |
951 |
905 return pV; |
952 return pV; |
|
953 } |
|
954 |
|
955 /** |
|
956 * Returns the context help id for the given editor page index |
|
957 * @param pageIndex the editor page index to use |
|
958 * @return the context help id |
|
959 */ |
|
960 public static String getPageHelpContextId(int pageIndex){ |
|
961 if (pageIndex == 0) { |
|
962 return HELP_CONTEXT_ID + "." + "threadsPageContext"; //$NON-NLS-1$ |
|
963 } else if (pageIndex == 1) { |
|
964 return HELP_CONTEXT_ID + "." + "binariesPageContext"; //$NON-NLS-1$ |
|
965 } else if (pageIndex == 2) { |
|
966 return HELP_CONTEXT_ID + "." + "functionsPageContext"; //$NON-NLS-1$ |
|
967 } else { |
|
968 return null; |
|
969 } |
906 } |
970 } |
907 |
971 |
908 public void receiveEvent(String action, Event event) { |
972 public void receiveEvent(String action, Event event) { |
909 if (action.equals("scroll")) { //$NON-NLS-1$ |
973 if (action.equals("scroll")) { //$NON-NLS-1$ |
910 if ( !(event.data instanceof String) |
974 |
911 || !((String)event.data).equals("FigureCanvas")) //$NON-NLS-1$ |
|
912 return; |
|
913 |
|
914 // the currently visible page has scrolled, so scroll the other pages |
|
915 ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages(); |
975 ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages(); |
916 ProfileVisualiser pV; |
976 ProfileVisualiser pV; |
917 |
977 |
918 int currentPV = PIPageEditor.currentPageIndex(); |
978 // post the scroll event to all pages including the current page |
919 if (currentPV != PIPageEditor.THREADS_PAGE) { |
979 // since there might be multiple graph components on each page even for the same plugin |
920 pV = pages.get(PIPageEditor.THREADS_PAGE); |
980 pV = pages.get(PIPageEditor.THREADS_PAGE); |
921 pV.getTopComposite().setScrolledOrigin(event.x, event.y); |
981 pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data); |
922 } |
982 pV = (ProfileVisualiser)pages.get(PIPageEditor.BINARIES_PAGE); |
923 if (currentPV != PIPageEditor.BINARIES_PAGE) { |
983 pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data); |
924 pV = (ProfileVisualiser)pages.get(PIPageEditor.BINARIES_PAGE); |
984 pV = (ProfileVisualiser)pages.get(PIPageEditor.FUNCTIONS_PAGE); |
925 pV.getTopComposite().setScrolledOrigin(event.x, event.y); |
985 pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data); |
926 } |
|
927 if (currentPV != PIPageEditor.FUNCTIONS_PAGE) { |
|
928 pV = (ProfileVisualiser)pages.get(PIPageEditor.FUNCTIONS_PAGE); |
|
929 pV.getTopComposite().setScrolledOrigin(event.x, event.y); |
|
930 } |
|
931 } else if (action.equals("priority_init")) { //$NON-NLS-1$ |
986 } else if (action.equals("priority_init")) { //$NON-NLS-1$ |
932 // priority trace has been processed, so let the threads page know |
987 // priority trace has been processed, so let the threads page know |
933 Hashtable<Integer,String> priStringById = (Hashtable<Integer,String>)event.data; |
988 Hashtable<Integer,String> priStringById = (Hashtable<Integer,String>)event.data; |
934 |
989 |
935 if (getTrace() == null) |
990 if (getTrace() == null) |
936 return; |
991 return; |
937 |
992 |
938 GppTraceGraph addressGraph = ((GppTraceGraph) getTrace().getTraceGraph(PIPageEditor.THREADS_PAGE)); |
993 IGppTraceGraph addressGraph = ((IGppTraceGraph) getTrace().getTraceGraph(PIPageEditor.THREADS_PAGE)); |
939 |
994 |
940 if (addressGraph != null) { |
995 if (addressGraph != null) { |
941 addressGraph.updateThreadTablePriorities(priStringById); |
996 addressGraph.updateThreadTablePriorities(priStringById); |
942 } |
997 } |
943 } |
998 } |
944 } |
|
945 |
|
946 /* (non-Javadoc) |
|
947 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int) |
|
948 */ |
|
949 public String getGraphTitle(int graphIndex) { |
|
950 return null; |
|
951 } |
999 } |
952 // |
1000 // |
953 // static public void putAddrThreadPeriod(long addrThreadPeriod) { |
1001 // static public void putAddrThreadPeriod(long addrThreadPeriod) { |
954 // uidToAddrThreadPeriod.put(NpiInstanceRepository.getInstance().activeUid(), addrThreadPeriod); |
1002 // uidToAddrThreadPeriod.put(NpiInstanceRepository.getInstance().activeUid(), addrThreadPeriod); |
955 // } |
1003 // } |
956 // |
1004 // |
957 // static public long getAddrThreadPeriod() { |
1005 // static public long getAddrThreadPeriod() { |
958 // return uidToAddrThreadPeriod.get(NpiInstanceRepository.getInstance().activeUid()); |
1006 // return uidToAddrThreadPeriod.get(NpiInstanceRepository.getInstance().activeUid()); |
959 // } |
1007 // } |
|
1008 |
|
1009 /** |
|
1010 * Returns a File corresponding to the given bundle relative path. |
|
1011 * @param path the bundle relative path to resource to locate |
|
1012 * @return the File corresponding to the given bundle relative path, or null |
|
1013 * @throws IOException |
|
1014 */ |
|
1015 public File locateFileInBundle(final String path) throws IOException { |
|
1016 Bundle myBundle= getDefault().getBundle(); |
|
1017 IPath ppath= new Path(path); |
|
1018 ppath= ppath.makeRelative(); |
|
1019 URL[] urls= FileLocator.findEntries(myBundle, ppath); |
|
1020 if(urls.length != 1) { |
|
1021 return null; |
|
1022 } |
|
1023 return new File(FileLocator.toFileURL(urls[0]).getFile()); |
|
1024 } |
|
1025 |
|
1026 /* (non-Javadoc) |
|
1027 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnDispose() |
|
1028 */ |
|
1029 public void runOnDispose() { |
|
1030 //no-op |
|
1031 } |
|
1032 |
|
1033 /* (non-Javadoc) |
|
1034 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnPartOpened() |
|
1035 */ |
|
1036 public void runOnPartOpened() { |
|
1037 //execute the initial action; since it affects the GIU, execute in UI thread |
|
1038 GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$ |
|
1039 |
|
1040 if (trace != null && trace.getCPUCount() > 1){ |
|
1041 boolean showCombinedCPUView = true; |
|
1042 |
|
1043 Object obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW); |
|
1044 if ((obj != null) && (obj instanceof Boolean)){ |
|
1045 showCombinedCPUView = (Boolean)obj; |
|
1046 } |
|
1047 |
|
1048 final String actionRequest = showCombinedCPUView ? ACTION_COMBINED_CPU_VIEW : ACTION_SEPARATE_CPU_VIEW; |
|
1049 Display.getDefault().syncExec( new Runnable() { |
|
1050 public void run() { |
|
1051 receiveSelectionEvent(actionRequest); |
|
1052 } |
|
1053 }); |
|
1054 } |
|
1055 |
|
1056 } |
|
1057 |
960 } |
1058 } |