|
1 /* |
|
2 * Copyright (c) 2007-2010 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 * Show trace info command |
|
17 * |
|
18 */ |
|
19 package com.nokia.traceviewer.action; |
|
20 |
|
21 import java.nio.ByteBuffer; |
|
22 import java.util.ArrayList; |
|
23 import java.util.Iterator; |
|
24 import java.util.List; |
|
25 |
|
26 import org.eclipse.jface.resource.ImageDescriptor; |
|
27 import org.eclipse.swt.SWT; |
|
28 import org.eclipse.swt.custom.StyleRange; |
|
29 import org.eclipse.swt.widgets.Display; |
|
30 import org.eclipse.ui.ISharedImages; |
|
31 import org.eclipse.ui.PlatformUI; |
|
32 |
|
33 import com.nokia.traceviewer.TraceViewerHelpContextIDs; |
|
34 import com.nokia.traceviewer.dialog.ShowTraceInfoDialog; |
|
35 import com.nokia.traceviewer.engine.BTraceInformation; |
|
36 import com.nokia.traceviewer.engine.TraceMetaData; |
|
37 import com.nokia.traceviewer.engine.TraceProperties; |
|
38 import com.nokia.traceviewer.engine.TraceViewerGlobals; |
|
39 import com.nokia.traceviewer.engine.TraceViewerUtils; |
|
40 |
|
41 /** |
|
42 * Handler for show trace info command |
|
43 * |
|
44 */ |
|
45 public final class ShowTraceInfoAction extends TraceViewerAction { |
|
46 |
|
47 /** |
|
48 * Characters for hex string |
|
49 */ |
|
50 private final static char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', |
|
51 '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; |
|
52 |
|
53 /** |
|
54 * One byte takes this many characters to show when as hex string |
|
55 */ |
|
56 private static final int BYTE_AS_HEX_STRING_LENGTH = 3; |
|
57 |
|
58 /** |
|
59 * Empty string |
|
60 */ |
|
61 private static final String EMPTY = ""; //$NON-NLS-1$ |
|
62 |
|
63 /** |
|
64 * Hex prefix |
|
65 */ |
|
66 private static final String HEX_PREFIX = "0x"; //$NON-NLS-1$ |
|
67 |
|
68 /** |
|
69 * Lead zero |
|
70 */ |
|
71 private static final String LEAD_ZERO = "0"; //$NON-NLS-1$ |
|
72 |
|
73 /** |
|
74 * Start parenthesis |
|
75 */ |
|
76 private static final char START_PARENTHESIS = '('; |
|
77 |
|
78 /** |
|
79 * End parenthesis |
|
80 */ |
|
81 private static final char END_PARENTHESIS = ')'; |
|
82 |
|
83 /** |
|
84 * Line break |
|
85 */ |
|
86 private static final String LINE_BREAK = "\n"; //$NON-NLS-1$ |
|
87 |
|
88 /** |
|
89 * Colon + space combination |
|
90 */ |
|
91 private static final String COLON_SPACE = ": "; //$NON-NLS-1$ |
|
92 |
|
93 /** |
|
94 * Image for the action |
|
95 */ |
|
96 private static ImageDescriptor image; |
|
97 |
|
98 /** |
|
99 * Trace properties |
|
100 */ |
|
101 private TraceProperties trace; |
|
102 |
|
103 /** |
|
104 * Constructor |
|
105 */ |
|
106 ShowTraceInfoAction() { |
|
107 image = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( |
|
108 ISharedImages.IMG_OBJS_INFO_TSK); |
|
109 setText(Messages.getString("ShowTraceInfoAction.Title")); //$NON-NLS-1$ |
|
110 setToolTipText(Messages.getString("ShowTraceInfoAction.Tooltip")); //$NON-NLS-1$ |
|
111 setImageDescriptor(image); |
|
112 |
|
113 // Set help |
|
114 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, |
|
115 TraceViewerHelpContextIDs.ACTIONS); |
|
116 } |
|
117 |
|
118 /* |
|
119 * (non-Javadoc) |
|
120 * |
|
121 * @see com.nokia.traceviewer.action.TraceViewerAction#doRun() |
|
122 */ |
|
123 @Override |
|
124 protected void doRun() { |
|
125 List<StyleRange> styleRanges = new ArrayList<StyleRange>(); |
|
126 int lineNumber = 0; |
|
127 if (trace != null) { |
|
128 lineNumber = trace.traceNumber; |
|
129 } |
|
130 |
|
131 String traceNumberString = Messages |
|
132 .getString("ShowTraceInfoAction.TraceNumberString") + COLON_SPACE //$NON-NLS-1$ |
|
133 + (lineNumber) + LINE_BREAK; |
|
134 String idString = EMPTY; |
|
135 String locationString = EMPTY; |
|
136 String classMethodString = EMPTY; |
|
137 String bTraceString = EMPTY; |
|
138 String hexString = EMPTY; |
|
139 String hexTrace = EMPTY; |
|
140 |
|
141 if (trace != null) { |
|
142 TraceMetaData traceMetadata = TraceViewerGlobals |
|
143 .getDecodeProvider().getTraceMetaData(trace.information); |
|
144 |
|
145 // Construct ID strings |
|
146 if (trace.information.isDefined()) { |
|
147 idString = constructIdString(); |
|
148 } |
|
149 |
|
150 // Construct metadata strings if it's available |
|
151 if (traceMetadata != null) { |
|
152 |
|
153 // Get defined in path |
|
154 String path = traceMetadata.getPath(); |
|
155 if (path != null) { |
|
156 String locationStr = Messages |
|
157 .getString("ShowTraceInfoAction.LocationStr"); //$NON-NLS-1$ |
|
158 locationString += LINE_BREAK + locationStr + COLON_SPACE |
|
159 + path + LINE_BREAK; |
|
160 } |
|
161 |
|
162 // Get defined in line number |
|
163 int definedInLine = traceMetadata.getLineNumber(); |
|
164 if (definedInLine != 0) { |
|
165 String lineNrStr = Messages |
|
166 .getString("ShowTraceInfoAction.LineNumberStr"); //$NON-NLS-1$ |
|
167 locationString += lineNrStr + COLON_SPACE + definedInLine |
|
168 + LINE_BREAK; |
|
169 } |
|
170 |
|
171 // Get class name |
|
172 String className = traceMetadata.getClassName(); |
|
173 if (className != null && !className.equals(EMPTY)) { |
|
174 String classNameStr = Messages |
|
175 .getString("ShowTraceInfoAction.ClassnameStr"); //$NON-NLS-1$ |
|
176 classMethodString += classNameStr + COLON_SPACE + className |
|
177 + LINE_BREAK; |
|
178 } |
|
179 |
|
180 // Get method name |
|
181 String methodName = traceMetadata.getMethodName(); |
|
182 if (methodName != null && !methodName.equals(EMPTY)) { |
|
183 String methodNameStr = Messages |
|
184 .getString("ShowTraceInfoAction.MethodnameStr"); //$NON-NLS-1$ |
|
185 classMethodString += methodNameStr + COLON_SPACE |
|
186 + methodName + LINE_BREAK; |
|
187 } |
|
188 } |
|
189 |
|
190 // Construct BTrace string |
|
191 if (trace.bTraceInformation.getRecordSize() != 0) { |
|
192 int totalStringLength = (traceNumberString + idString |
|
193 + locationString + classMethodString).length(); |
|
194 bTraceString = constructBTraceString(totalStringLength, |
|
195 styleRanges); |
|
196 } |
|
197 |
|
198 // Get trace as HEX |
|
199 if (trace.byteBuffer != null) { |
|
200 hexString = LINE_BREAK |
|
201 + Messages.getString("ShowTraceInfoAction.HexString"); //$NON-NLS-1$ |
|
202 hexString += COLON_SPACE + START_PARENTHESIS |
|
203 + trace.messageLength; |
|
204 hexString += Messages |
|
205 .getString("ShowTraceInfoAction.BytesString"); //$NON-NLS-1$ |
|
206 hexString += END_PARENTHESIS + LINE_BREAK; |
|
207 hexTrace = TraceViewerUtils.getTraceAsHexString( |
|
208 trace.byteBuffer, trace.messageStart, |
|
209 trace.messageLength, true); |
|
210 } |
|
211 } |
|
212 |
|
213 int headerLength = 0; |
|
214 |
|
215 // Create the contents |
|
216 hexString += hexTrace + LINE_BREAK; |
|
217 String contents = traceNumberString + idString + locationString |
|
218 + classMethodString + bTraceString + hexString; |
|
219 int headerStartOffset = contents.length() - hexTrace.length() - 1; |
|
220 if (trace != null) { |
|
221 |
|
222 // Calculate header color offset |
|
223 headerLength = (trace.dataStart - trace.messageStart) |
|
224 * BYTE_AS_HEX_STRING_LENGTH; |
|
225 StyleRange headerRange = new StyleRange(headerStartOffset, |
|
226 headerLength, Display.getDefault().getSystemColor( |
|
227 SWT.COLOR_RED), null); |
|
228 styleRanges.add(headerRange); |
|
229 |
|
230 // Calculate data color offset |
|
231 if (headerStartOffset + headerLength + 1 < contents.length()) { |
|
232 StyleRange dataRange = new StyleRange(headerStartOffset |
|
233 + headerLength, contents.length() |
|
234 - (headerStartOffset + headerLength + 1) - 1, Display |
|
235 .getDefault().getSystemColor(SWT.COLOR_BLUE), null); |
|
236 styleRanges.add(dataRange); |
|
237 } |
|
238 } |
|
239 |
|
240 // Show information message |
|
241 new ShowTraceInfoDialog(PlatformUI.getWorkbench().getDisplay() |
|
242 .getActiveShell(), contents, styleRanges).openDialog(); |
|
243 } |
|
244 |
|
245 /** |
|
246 * Constructs ID string |
|
247 * |
|
248 * @return ID string |
|
249 */ |
|
250 private String constructIdString() { |
|
251 |
|
252 // Get names from Dictionary |
|
253 String[] names = TraceViewerGlobals.getDecodeProvider() |
|
254 .getComponentGroupTraceName(trace.information.getComponentId(), |
|
255 trace.information.getGroupId(), |
|
256 trace.information.getTraceId()); |
|
257 |
|
258 // Component ID and name |
|
259 String idStr = Messages.getString("ShowTraceInfoAction.CidStr"); //$NON-NLS-1$ |
|
260 String idString = LINE_BREAK |
|
261 + idStr |
|
262 + COLON_SPACE |
|
263 + idToHexNameString(trace.information.getComponentId(), |
|
264 names[0]); |
|
265 |
|
266 // Group ID and name |
|
267 idStr = Messages.getString("ShowTraceInfoAction.GidStr"); //$NON-NLS-1$ |
|
268 idString += LINE_BREAK + idStr + COLON_SPACE |
|
269 + idToHexNameString(trace.information.getGroupId(), names[1]); |
|
270 |
|
271 // Trace ID and name |
|
272 idStr = Messages.getString("ShowTraceInfoAction.TidStr"); //$NON-NLS-1$ |
|
273 idString += LINE_BREAK + idStr + COLON_SPACE |
|
274 + idToHexNameString(trace.information.getTraceId(), names[2]) |
|
275 + LINE_BREAK; |
|
276 return idString; |
|
277 } |
|
278 |
|
279 /** |
|
280 * Constructs BTrace string |
|
281 * |
|
282 * @param totalStringLength |
|
283 * total string length before this string |
|
284 * @param styleRanges |
|
285 * list of style ranges |
|
286 * @return BTrace string |
|
287 */ |
|
288 private String constructBTraceString(int totalStringLength, |
|
289 List<StyleRange> styleRanges) { |
|
290 BTraceInformation bTraceInf = trace.bTraceInformation; |
|
291 |
|
292 StringBuffer bTraceString = new StringBuffer(); |
|
293 bTraceString.append(LINE_BREAK); |
|
294 bTraceString.append(Messages |
|
295 .getString("ShowTraceInfoAction.BTraceInformation")); //$NON-NLS-1$ |
|
296 bTraceString.append(LINE_BREAK); |
|
297 |
|
298 // BTrace header |
|
299 bTraceString.append(Messages |
|
300 .getString("ShowTraceInfoAction.RecordSize")); //$NON-NLS-1$ |
|
301 bTraceString.append(byteToString(bTraceInf.getRecordSize())); |
|
302 bTraceString.append(LINE_BREAK); |
|
303 bTraceString.append(Messages.getString("ShowTraceInfoAction.Flags")); //$NON-NLS-1$ |
|
304 bTraceString.append(byteToString(bTraceInf.getFlags())); |
|
305 bTraceString.append(LINE_BREAK); |
|
306 bTraceString.append(Messages.getString("ShowTraceInfoAction.Category")); //$NON-NLS-1$ |
|
307 bTraceString.append(byteToString(bTraceInf.getCategory())); |
|
308 bTraceString.append(LINE_BREAK); |
|
309 bTraceString.append(Messages |
|
310 .getString("ShowTraceInfoAction.SubCategory")); //$NON-NLS-1$ |
|
311 bTraceString.append(byteToString(bTraceInf.getSubCategory())); |
|
312 bTraceString.append(LINE_BREAK); |
|
313 |
|
314 // BTrace variables |
|
315 if (bTraceInf.isHeader2Present()) { |
|
316 bTraceString |
|
317 .append(Messages.getString("ShowTraceInfoAction.CpuId")); //$NON-NLS-1$ |
|
318 bTraceString.append(bTraceInf.getCpuId()); |
|
319 bTraceString.append(LINE_BREAK); |
|
320 } |
|
321 if (bTraceInf.isTimestampPresent()) { |
|
322 bTraceString.append(Messages |
|
323 .getString("ShowTraceInfoAction.Timestamp")); //$NON-NLS-1$ |
|
324 bTraceString.append(idToHexNameString(bTraceInf.getTimestamp(), |
|
325 null)); |
|
326 bTraceString.append(LINE_BREAK); |
|
327 } |
|
328 if (bTraceInf.isTimestamp2Present()) { |
|
329 bTraceString.append(Messages |
|
330 .getString("ShowTraceInfoAction.Timestamp2")); //$NON-NLS-1$ |
|
331 bTraceString.append(idToHexNameString(bTraceInf.getTimestamp2(), |
|
332 null)); |
|
333 bTraceString.append(LINE_BREAK); |
|
334 } |
|
335 if (bTraceInf.isContextIdPresent()) { |
|
336 bTraceString.append(Messages |
|
337 .getString("ShowTraceInfoAction.ContextId")); //$NON-NLS-1$ |
|
338 bTraceString |
|
339 .append(idToHexNameString(bTraceInf.getThreadId(), null)); |
|
340 |
|
341 // Check context |
|
342 if ((bTraceInf.getThreadId() & (1 << 0)) == 0) { |
|
343 |
|
344 // NThread |
|
345 if ((bTraceInf.getThreadId() & (1 << 1)) == 0) { |
|
346 bTraceString.append(Messages |
|
347 .getString("ShowTraceInfoAction.NThread")); //$NON-NLS-1$ |
|
348 // FIQ Context |
|
349 } else { |
|
350 bTraceString.append(Messages |
|
351 .getString("ShowTraceInfoAction.FIQ")); //$NON-NLS-1$ |
|
352 } |
|
353 } else { |
|
354 // IRQ Context |
|
355 if ((bTraceInf.getThreadId() & (1 << 1)) == 0) { |
|
356 bTraceString.append(Messages |
|
357 .getString("ShowTraceInfoAction.IRQ")); //$NON-NLS-1$ |
|
358 |
|
359 // IDFC Context |
|
360 } else { |
|
361 bTraceString.append(Messages |
|
362 .getString("ShowTraceInfoAction.IDFC")); //$NON-NLS-1$ |
|
363 } |
|
364 } |
|
365 bTraceString.append(LINE_BREAK); |
|
366 } |
|
367 if (bTraceInf.isProgramCounterPresent()) { |
|
368 bTraceString.append(Messages |
|
369 .getString("ShowTraceInfoAction.ProgramCounter")); //$NON-NLS-1$ |
|
370 bTraceString.append(idToHexNameString( |
|
371 bTraceInf.getProgramCounter(), null)); |
|
372 bTraceString.append(LINE_BREAK); |
|
373 } |
|
374 if (bTraceInf.isExtraValuePresent()) { |
|
375 bTraceString.append(Messages |
|
376 .getString("ShowTraceInfoAction.ExtraValue")); //$NON-NLS-1$ |
|
377 bTraceString.append(idToHexNameString(bTraceInf.getExtraValue(), |
|
378 null)); |
|
379 bTraceString.append(LINE_BREAK); |
|
380 } |
|
381 if (bTraceInf.isTruncated()) { |
|
382 bTraceString.append(Messages |
|
383 .getString("ShowTraceInfoAction.Truncated")); //$NON-NLS-1$ |
|
384 bTraceString.append(LINE_BREAK); |
|
385 } |
|
386 if (bTraceInf.isTraceMissing()) { |
|
387 bTraceString.append(Messages |
|
388 .getString("ShowTraceInfoAction.RecordMissing")); //$NON-NLS-1$ |
|
389 bTraceString.append(LINE_BREAK); |
|
390 } |
|
391 |
|
392 // Multipart stuff |
|
393 if (bTraceInf.getMultiPart() != 0) { |
|
394 bTraceString.append(Messages |
|
395 .getString("ShowTraceInfoAction.MultiPart")); //$NON-NLS-1$ |
|
396 if (bTraceInf.getMultiPartTraceParts() != null) { |
|
397 bTraceString.append(LINE_BREAK); |
|
398 bTraceString.append(Messages |
|
399 .getString("ShowTraceInfoAction.AssembledFromParts")); //$NON-NLS-1$ |
|
400 bTraceString.append(LINE_BREAK); |
|
401 bTraceString.append(LINE_BREAK); |
|
402 Iterator<byte[]> i = bTraceInf.getMultiPartTraceParts() |
|
403 .getTraceParts().iterator(); |
|
404 Iterator<Integer> headerLenIterator = bTraceInf |
|
405 .getMultiPartTraceParts().getTracePartHeaderSizes() |
|
406 .iterator(); |
|
407 |
|
408 // Loop through trace parts |
|
409 int partNumber = 1; |
|
410 while (i.hasNext()) { |
|
411 byte[] byteArr = i.next(); |
|
412 bTraceString.append(Messages |
|
413 .getString("ShowTraceInfoAction.Part")); //$NON-NLS-1$ |
|
414 bTraceString.append(partNumber++); |
|
415 bTraceString.append(COLON_SPACE + START_PARENTHESIS |
|
416 + byteArr.length); |
|
417 bTraceString.append(Messages |
|
418 .getString("ShowTraceInfoAction.BytesString")); //$NON-NLS-1$ |
|
419 bTraceString.append(END_PARENTHESIS + LINE_BREAK); |
|
420 String hexTrace = TraceViewerUtils.getTraceAsHexString( |
|
421 ByteBuffer.wrap(byteArr), 0, byteArr.length, true); |
|
422 |
|
423 int headerLen = headerLenIterator.next().intValue(); |
|
424 int colorHeaderStartOffset = totalStringLength |
|
425 + bTraceString.length(); |
|
426 int colorDataStartOffset = colorHeaderStartOffset |
|
427 + (headerLen * BYTE_AS_HEX_STRING_LENGTH); |
|
428 |
|
429 // Add offsets to style range |
|
430 StyleRange headerRange = new StyleRange( |
|
431 colorHeaderStartOffset, headerLen |
|
432 * BYTE_AS_HEX_STRING_LENGTH, |
|
433 Display.getDefault().getSystemColor(SWT.COLOR_RED), |
|
434 null); |
|
435 StyleRange dataRange = new StyleRange( |
|
436 colorDataStartOffset, |
|
437 hexTrace.length() |
|
438 - (headerLen * BYTE_AS_HEX_STRING_LENGTH), |
|
439 Display.getDefault().getSystemColor(SWT.COLOR_BLUE), |
|
440 null); |
|
441 styleRanges.add(headerRange); |
|
442 styleRanges.add(dataRange); |
|
443 |
|
444 bTraceString.append(hexTrace); |
|
445 bTraceString.append(LINE_BREAK); |
|
446 bTraceString.append(LINE_BREAK); |
|
447 } |
|
448 |
|
449 } else if (bTraceInf.getMultiPart() == 1) { |
|
450 bTraceString.append(Messages |
|
451 .getString("ShowTraceInfoAction.FirstPart")); //$NON-NLS-1$ |
|
452 } else if (bTraceInf.getMultiPart() == 2) { |
|
453 bTraceString.append(Messages |
|
454 .getString("ShowTraceInfoAction.MiddlePart")); //$NON-NLS-1$ |
|
455 } else if (bTraceInf.getMultiPart() == 3) { |
|
456 bTraceString.append(Messages |
|
457 .getString("ShowTraceInfoAction.LastPart")); //$NON-NLS-1$ |
|
458 } |
|
459 bTraceString.append(LINE_BREAK); |
|
460 } |
|
461 |
|
462 return bTraceString.toString(); |
|
463 } |
|
464 |
|
465 /** |
|
466 * Converts ID to hex string and name |
|
467 * |
|
468 * @param id |
|
469 * ID |
|
470 * @param name |
|
471 * name |
|
472 * @return ID as hex and name string |
|
473 */ |
|
474 private String idToHexNameString(int id, String name) { |
|
475 String idString = Integer.toHexString(id); |
|
476 if (idString.length() == 1) { |
|
477 idString = LEAD_ZERO + idString; |
|
478 } |
|
479 idString = HEX_PREFIX + idString; |
|
480 |
|
481 if (name != null) { |
|
482 idString += " (" + name + ")"; //$NON-NLS-1$//$NON-NLS-2$ |
|
483 } |
|
484 |
|
485 return idString; |
|
486 } |
|
487 |
|
488 /** |
|
489 * Converts byte to string |
|
490 * |
|
491 * @param b |
|
492 * byte to be converted |
|
493 * @return byte as a string |
|
494 */ |
|
495 private String byteToString(byte b) { |
|
496 StringBuffer out = new StringBuffer(); |
|
497 int v = b & 0xFF; |
|
498 out.append(hexChars[v >>> 4]); |
|
499 out.append(hexChars[v & 0xF]); |
|
500 return out.toString(); |
|
501 } |
|
502 |
|
503 /** |
|
504 * Sets trace metadata |
|
505 * |
|
506 * @param trace |
|
507 * the trace properties |
|
508 */ |
|
509 public void setTrace(TraceProperties trace) { |
|
510 this.trace = trace; |
|
511 } |
|
512 } |