crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/model/TraceListener.java
changeset 16 72f198be1c1d
parent 4 615035072f7e
equal deleted inserted replaced
15:0367d2db2c06 16:72f198be1c1d
    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 		
    92 	
   124 	
    93 	/**
   125 	/**
    94 	 * Sets whether we should decode imported files or just import them as undecoded state.
   126 	 * Sets whether we should decode imported files or just import them as undecoded state.
    95 	 * @param decodeFiles 
   127 	 * @param decodeFiles 
    96 	 */
   128 	 */
    97 	public void setDecode(boolean decodeFiles) {
   129 	public void setDecode(final boolean decodeFiles) {
    98 		decode = decodeFiles;
   130 		decode = decodeFiles;
    99 	}
   131 	}
   100 	
   132 	
   101 	/**
   133 	/**
   102 	 * De-activates MobileCrash file listening
   134 	 * De-activates MobileCrash file listening
   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 							}