18 package com.nokia.s60tools.crashanalyser.model; |
18 package com.nokia.s60tools.crashanalyser.model; |
19 |
19 |
20 import java.io.*; |
20 import java.io.*; |
21 import java.text.SimpleDateFormat; |
21 import java.text.SimpleDateFormat; |
22 import java.util.Calendar; |
22 import java.util.Calendar; |
|
23 import java.util.Timer; |
|
24 import java.util.TimerTask; |
|
25 |
23 import org.eclipse.core.runtime.IConfigurationElement; |
26 import org.eclipse.core.runtime.IConfigurationElement; |
24 import org.eclipse.core.runtime.IExtension; |
27 import org.eclipse.core.runtime.IExtension; |
25 import org.eclipse.core.runtime.IExtensionPoint; |
28 import org.eclipse.core.runtime.IExtensionPoint; |
26 import org.eclipse.core.runtime.IExtensionRegistry; |
29 import org.eclipse.core.runtime.IExtensionRegistry; |
27 import org.eclipse.core.runtime.Platform; |
30 import org.eclipse.core.runtime.Platform; |
28 import org.eclipse.swt.widgets.Display; |
31 import org.eclipse.swt.widgets.Display; |
|
32 |
29 import com.nokia.s60tools.crashanalyser.data.*; |
33 import com.nokia.s60tools.crashanalyser.data.*; |
30 import com.nokia.s60tools.crashanalyser.interfaces.IErrorLibraryObserver; |
34 import com.nokia.s60tools.crashanalyser.interfaces.IErrorLibraryObserver; |
31 import com.nokia.s60tools.crashanalyser.files.*; |
35 import com.nokia.s60tools.crashanalyser.files.*; |
32 import com.nokia.s60tools.crashanalyser.export.*; |
36 import com.nokia.s60tools.crashanalyser.export.*; |
33 import com.nokia.s60tools.crashanalyser.plugin.*; |
37 import com.nokia.s60tools.crashanalyser.plugin.*; |
|
38 |
|
39 |
34 |
40 |
35 /** |
41 /** |
36 * This class listens MobileCrash files via TraceViewer |
42 * This class listens MobileCrash files via TraceViewer |
37 * |
43 * |
38 */ |
44 */ |
39 public final class TraceListener implements ITraceDataProcessor, |
45 public final class TraceListener implements ITraceDataProcessor, |
40 IErrorLibraryObserver { |
46 IErrorLibraryObserver { |
|
47 |
|
48 /** |
|
49 * Private timer class. Takes care that we do not start crash |
|
50 * decoding process too many times within the predefined time |
|
51 * interval. |
|
52 */ |
|
53 private final class TraceTimerTask extends TimerTask |
|
54 { |
|
55 private final TraceListener traceListener; |
|
56 |
|
57 TraceTimerTask(final TraceListener listener) { |
|
58 traceListener = listener; |
|
59 } |
|
60 |
|
61 @Override |
|
62 public void run() { |
|
63 traceListener.timerExpired(); |
|
64 } |
|
65 } |
|
66 |
|
67 |
41 private final static String MOBILE_CRASH_STARTTAG = "<MB_CR_START>"; //$NON-NLS-1$ |
68 private final static String MOBILE_CRASH_STARTTAG = "<MB_CR_START>"; //$NON-NLS-1$ |
42 private final static String MOBILE_CRASH_LINE_TAG = "<MB_CD>"; //$NON-NLS-1$ |
69 private final static String MOBILE_CRASH_LINE_TAG = "<MB_CD>"; //$NON-NLS-1$ |
43 private final static String MOBILE_CRASH_STOPTAG = "<MB_CR_STOP>"; //$NON-NLS-1$ |
70 private final static String MOBILE_CRASH_STOPTAG = "<MB_CR_STOP>"; //$NON-NLS-1$ |
44 private final static String MOBILECRASH_START = "MobileCrash_"; //$NON-NLS-1$ |
71 private final static String MOBILECRASH_START = "MobileCrash_"; //$NON-NLS-1$ |
45 final String EXTENSION_TRACE_PROVIDER = "traceprovider"; //$NON-NLS-1$ |
72 private final static String EXTENSION_TRACE_PROVIDER = "traceprovider"; //$NON-NLS-1$ |
46 |
73 private final static int MAX_DECODER_COUNT = 3; |
47 |
74 private final static int DECODER_TIMER_DELAY = 10000; // 10 secs. |
|
75 |
48 boolean listening = false; |
76 boolean listening = false; |
49 boolean mobileCrashStarted = false; |
77 boolean mobileCrashStarted = false; |
50 BufferedWriter mcFile = null; |
78 BufferedWriter mcFile = null; |
51 String dumpFolder = ""; //$NON-NLS-1$ |
79 String dumpFolder = ""; //$NON-NLS-1$ |
52 File dumpFile; |
80 File dumpFile; |
53 ErrorLibrary errorLibrary = null; |
81 ErrorLibrary errorLibrary = null; |
54 boolean decode = false; |
82 boolean decode = false; |
55 private static ITraceProvider traceProvider = null; |
83 private static ITraceProvider traceProvider = null; |
|
84 private Timer timer; |
|
85 |
|
86 private int decoderCount = 0; |
56 |
87 |
57 /** |
88 /** |
58 * Constructor |
89 * Constructor |
59 */ |
90 */ |
60 public TraceListener() { |
91 public TraceListener() { |
61 readTraceProvider(); |
92 readTraceProvider(); |
|
93 timer = new Timer(); |
62 } |
94 } |
63 |
95 |
64 /** |
96 /** |
65 * Starts trace listening asynchronously |
97 * Starts trace listening asynchronously |
66 */ |
98 */ |
67 public void errorLibraryReady() { |
99 public void errorLibraryReady() { |
68 Runnable refreshRunnable = new Runnable(){ |
100 final Runnable refreshRunnable = new Runnable(){ |
69 public void run(){ |
101 public void run(){ |
70 startListening(); |
102 startListening(); |
71 } |
103 } |
72 }; |
104 }; |
73 |
105 |
113 /** |
145 /** |
114 * All lines in trace data will be passed to this method. This method |
146 * All lines in trace data will be passed to this method. This method |
115 * pics up MobileCrash file content from trace data. |
147 * pics up MobileCrash file content from trace data. |
116 * @param line trace data line |
148 * @param line trace data line |
117 */ |
149 */ |
118 public void processDataLine(String line) { |
150 public void processDataLine(final String line) { |
119 int idx = line.indexOf(MOBILE_CRASH_STARTTAG); |
151 int idx = line.indexOf(MOBILE_CRASH_STARTTAG); |
120 |
152 |
121 try { |
153 try { |
122 // Line contained <MC_CR_START> |
154 // Line contained <MC_CR_START> |
123 if (idx > -1) { |
155 if (idx > -1) { |
124 mobileCrashStarted = true; |
156 mobileCrashStarted = true; |
125 dumpFolder = FileOperations.addSlashToEnd(DecoderEngine.getNewCrashFolder()); |
157 dumpFolder = FileOperations.addSlashToEnd(DecoderEngine.getNewCrashFolder()); |
126 |
158 |
127 Calendar cal = Calendar.getInstance(); |
159 final Calendar cal = Calendar.getInstance(); |
128 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmssSSS"); //$NON-NLS-1$ |
160 final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmssSSS"); //$NON-NLS-1$ |
129 dumpFile = new File(dumpFolder + |
161 dumpFile = new File(dumpFolder + |
130 MOBILECRASH_START + |
162 MOBILECRASH_START + |
131 sdf.format(cal.getTime()) + |
163 sdf.format(cal.getTime()) + |
132 "." + |
164 "." + |
133 CrashAnalyserFile.TRACE_EXTENSION); |
165 CrashAnalyserFile.TRACE_EXTENSION); |
155 mcFile.close(); |
187 mcFile.close(); |
156 mcFile = null; |
188 mcFile = null; |
157 mobileCrashStarted = false; |
189 mobileCrashStarted = false; |
158 |
190 |
159 // give this mobilecrash file for further processing |
191 // give this mobilecrash file for further processing |
160 MobileCrashImporter tc = new MobileCrashImporter(); |
192 final MobileCrashImporter tc = new MobileCrashImporter(); |
161 tc.importFrom(dumpFolder, dumpFile.getName(), errorLibrary, decode); |
193 |
|
194 if (decoderCount < MAX_DECODER_COUNT) { |
|
195 decoderCount++; |
|
196 if (decoderCount == 1) { |
|
197 // Start timer when starting decoder at first time |
|
198 timer.schedule(new TraceTimerTask(this), DECODER_TIMER_DELAY); |
|
199 } |
|
200 tc.importFrom(dumpFolder, dumpFile.getName(), errorLibrary, decode); |
|
201 } else { |
|
202 // Too many crashes in the trace file, do not decode (last parameter is false). |
|
203 tc.importFrom(dumpFolder, dumpFile.getName(), errorLibrary, false); |
|
204 } |
162 } |
205 } |
163 } |
206 } |
164 } |
207 } |
165 } catch (Exception e) { |
208 } catch (Exception e) { |
166 if (mcFile != null) { |
209 if (mcFile != null) { |
181 return false; |
224 return false; |
182 return true; |
225 return true; |
183 } |
226 } |
184 |
227 |
185 /** |
228 /** |
|
229 * This is called when the timer expires. |
|
230 */ |
|
231 public final void timerExpired() |
|
232 { |
|
233 decoderCount = 0; |
|
234 } |
|
235 |
|
236 /** |
186 * Tries to find plugins which are Trace Providers. Selected the first found |
237 * Tries to find plugins which are Trace Providers. Selected the first found |
187 * Trace provider plugin. |
238 * Trace provider plugin. |
188 */ |
239 */ |
189 void readTraceProvider() { |
240 void readTraceProvider() { |
190 try { |
241 try { |
191 IExtensionRegistry er = Platform.getExtensionRegistry(); |
242 final IExtensionRegistry er = Platform.getExtensionRegistry(); |
192 IExtensionPoint ep = |
243 final IExtensionPoint ep = |
193 er.getExtensionPoint(CrashAnalyserPlugin.PLUGIN_ID, EXTENSION_TRACE_PROVIDER); |
244 er.getExtensionPoint(CrashAnalyserPlugin.PLUGIN_ID, EXTENSION_TRACE_PROVIDER); |
194 IExtension[] extensions = ep.getExtensions(); |
245 final IExtension[] extensions = ep.getExtensions(); |
195 |
246 |
196 // if plug-ins were found. |
247 // if plug-ins were found. |
197 if (extensions != null && extensions.length > 0) { |
248 if (extensions != null && extensions.length > 0) { |
198 |
249 |
199 // read all found trace providers |
250 // read all found trace providers |
200 for (int i = 0; i < extensions.length; i++) { |
251 for (int i = 0; i < extensions.length; i++) { |
201 IConfigurationElement[] ce = extensions[i].getConfigurationElements(); |
252 final IConfigurationElement[] ce = extensions[i].getConfigurationElements(); |
202 if (ce != null && ce.length > 0) { |
253 if (ce != null && ce.length > 0) { |
203 try { |
254 try { |
204 ITraceProvider provider = (ITraceProvider)ce[0].createExecutableExtension("class"); |
255 final ITraceProvider provider = (ITraceProvider)ce[0].createExecutableExtension("class"); |
205 // we support only one trace provider |
256 // we support only one trace provider |
206 if (provider != null) { |
257 if (provider != null) { |
207 traceProvider = provider; |
258 traceProvider = provider; |
208 break; |
259 break; |
209 } |
260 } |