# HG changeset patch # User Matti Laitinen # Date 1271869268 -10800 # Node ID 8e12a575a9b5bb75019c279d6e726f46a5fab28d # Parent f65f740e69f92974202dffd33bbacd9ef8030b59 MemSpy Carbide Extension 1.6.0 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.carbide.extensions.memspy/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,18 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +bin.includes = feature.xml,\ + license.txt diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.carbide.extensions.memspy/feature.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/feature.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,77 @@ + + + + + MemSpy tool is used for analysing memory state and chances of s60 device over time. + + + + Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + All rights reserved. License: http://www.eclipse.org/legal/epl-v10.html. + + + + Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. +This component and the accompanying materials are made available +under the terms of "Eclipse Public License v1.0" +which accompanies this distribution, and is available +at the URL "http://www.eclipse.org/legal/epl-v10.html". + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.carbide.extensions.memspy/license.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/license.txt Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,6 @@ +Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. +This component and the accompanying materials are made available +under the terms of "Eclipse Public License v1.0" +which accompanies this distribution, and is available +at the URL "http://www.eclipse.org/legal/epl-v10.html". diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.classpath Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,7 @@ + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.settings/org.eclipse.jdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,7 @@ +#Tue Jan 27 09:55:50 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/DbgEntSymbol.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/DbgEntSymbol.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapAnalyser.exe Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapAnalyser.exe has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonUiLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonUiLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapCtrlLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapCtrlLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapDataJavaScriptLib.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapDataJavaScriptLib.js Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* - Neither the name of Nokia Corporation nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +var info = document.createElement("div"); +var header = document.createElement("div"); +var body = document.createElement("div"); + +function initialize() +{ + info.style.position="absolute"; + info.style.visibility='hidden'; + + setGeneralStyle(header); + + header.style.fontWeight='bold'; + header.style.color='#4B7A98'; + header.style.background='#D5EBF9'; + + setGeneralStyle(body); + + body.style.borderTop='0px'; + body.style.color='#1B4966'; + body.style.background='#FFFFFF'; + + info.appendChild(header); + info.appendChild(body); + + document.body.appendChild(info); +} + +function setGeneralStyle(elm) +{ + elm.style.fontFamily='arial'; + elm.style.fontSize='10'; + elm.style.padding='2'; + elm.style.border='1px solid #A5CFE9'; +} + +function showInfo(title, text, width) +{ + header.innerHTML = title; + body.innerHTML = text; + + if ( width ) + { + header.style.width = width + "px"; + body.style.width = width + "px"; + } + else + { + header.style.width = '180px'; + body.style.width = '180px'; + } + + info.style.visibility = 'visible'; +} + +function hideInfo() +{ + info.style.visibility = 'hidden'; +} + +function mouseMove(e) +{ + if ( info.style.visibility == 'visible' ) + { + var evt; + + e?evt=e:evt=event; + + var x, y; + + if ( !evt.pageX ) + x = evt.x + document.body.scrollLeft; + else + x = evt.pageX; + + info.style.left = x + 15; + + if ( !evt.pageY ) + y = evt.y + document.body.scrollTop; + else + y = evt.pageY; + + info.style.top = y + 15; + } +} + +function showMainFormCell( txt ) +{ + var currentURL = parent.MainWindow.location.toString(); + var hashPos = currentURL.indexOf('#'); + + if ( hashPos >= 0 ) + { + var hashArray = currentURL.split("#"); + currentURL = hashArray[ 0 ]; + } + + var newURL = currentURL + '#Cell_' + txt; + + parent.MainWindow.location = newURL; +} \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapUiLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapUiLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Office.Interop.Excel.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Office.Interop.Excel.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Vbe.Interop.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Vbe.Interop.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginMap.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginMap.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginObey.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginObey.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginSymbol.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginSymbol.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginZip.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginZip.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SupportingLibraries.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SupportingLibraries.txt Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,43 @@ +ZedGraph (c) John Champion +========================== +http://zedgraph.org/wiki/index.php?title=ZedGraph_License + +ZedGraph is licensed under the Lesser or Library General Public License. + + + + + + + +XPTable (c) Mathew Hall +======================= +http://www.codeproject.com/cs/miscctrl/XPTable.asp +http://sourceforge.net/projects/xptable/ + +/* + * Copyright © 2005, Mathew Hall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLibUi.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLibUi.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianExcelLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianExcelLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianStructuresLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianStructuresLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianSymbolLib.plugin.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianSymbolLib.plugin.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianTree.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianTree.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtils.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtils.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtilsUi.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtilsUi.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianWizardLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianWizardLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianXmlInputLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianXmlInputLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianZipLib.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianZipLib.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/XPTable.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/XPTable.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/ZedGraph.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/ZedGraph.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/office.dll Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/office.dll has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/META-INF/MANIFEST.MF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Carbide.c++ Extensions - Heapanalyser Plug-in +Bundle-SymbolicName: com.nokia.s60tools.heapanalyser +Bundle-Version: 1.6.0 +Bundle-Activator: com.nokia.s60tools.heapanalyser.HeapAnalyserPlugin +Bundle-Vendor: Nokia +Require-Bundle: org.eclipse.core.runtime, + com.nokia.s60tools.util;bundle-version="1.1.12" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: com.nokia.s60tools.heapanalyser.interfaces;x-friends:="com.nokia.s60tools.memspy" diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/OSS/zedgraph_source_v515.zip Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/OSS/zedgraph_source_v515.zip has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/about.html Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ + + + +About + + + +

About This Content

+ +

Dec 11, 2009

+ +

Copyright

+ +

+ +

Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: http://www.eclipse.org/legal/epl-v10.html.

+ +

+ + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,24 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +javacSource=1.5 +javacTarget=1.5 +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + Binaries/,\ + about.html diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/HeapAnalyserPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/HeapAnalyserPlugin.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.heapanalyser; + +import java.io.File; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class HeapAnalyserPlugin extends Plugin { + + /** + * The plug-in ID for Heap Analyser. + */ + public static final String PLUGIN_ID = "com.nokia.s60tools.heapanalyser"; + + private String pluginInstallPath = ""; + + // The shared instance + private static HeapAnalyserPlugin plugin; + + /** + * The constructor + */ + public HeapAnalyserPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static HeapAnalyserPlugin getDefault() { + return plugin; + } + + /** + * Returns the path where this plugin is installed + * @return the path where this plugin is installed + */ + public static String getPluginInstallPath() { + try { + if ("".equals(plugin.pluginInstallPath)) { + // URL to the plugin's root ("/") + URL relativeURL = plugin.getBundle().getEntry("/"); + // Converting into local path + URL localURL = FileLocator.toFileURL(relativeURL); + // Getting install location in correct form + File f = new File(localURL.getPath()); + plugin.pluginInstallPath = f.getAbsolutePath(); + } + return plugin.pluginInstallPath; + } catch (Exception e) { + return ""; + } + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/interfaces/HeapAnalyserLauncher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/interfaces/HeapAnalyserLauncher.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.heapanalyser.interfaces; + +import java.io.File; + +import com.nokia.s60tools.heapanalyser.HeapAnalyserPlugin; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Class with static variables and helper method to launch Heap Analyser. + */ +public class HeapAnalyserLauncher { + + /// Indicates an unspecified or general error + public static final int KErrCommandLineGeneral = -1; + + /// Indicates that one or more mandatory command line arguments was omitted + public static final int KErrCommandLineArgumentsMissing = -2; + + /// Indicates that an input command was not supported or valid + public static final int KErrCommandLineInvalidCommand = -3; + + /// Indicates that the specified input file was not found + public static final int KErrCommandLineArgumentsFileNotFound = -4; + + /// Indicates a fatal problem when attempting to read the input file + public static final int KErrCommandLineArgumentsFileInvalid = -5; + + /// Indicates source file(s) were not found or specified + public static final int KErrCommandLineSourceFileNotFound = -6; + + /// Indicates debug meta data was omitted from the inputs + public static final int KErrCommandLineDebugMetaDataMissing = -7; + + /// Occurs if Heap Analyser cannot find a handler for the specified command + /// line arguments. + public static final int KErrCommandLineUINotAvailable = -8; + + /// The requested analysis type is not supported + public static final int KErrCommandLineAnalysisTypeNotSupported = -9; + + /// The specified analysis thread name is invalid + public static final int KErrCommandLineAnalysisThreadNameInvalid = -10; + + /// The specified output data is invalid + public static final int KErrCommandLineAnalysisOutputInvalid = -11; + + /// The specified output data is invalid + public static final int KErrCommandLineLaunchingFailed = -12; + + + private static final String EXE_FOLDER = "Binaries"; + private static final String COMMAND_LINE_COMMAND = " -input "; + + /** + * Launch Heap Analyser application. + * @param configurationFilePath + * @return {@link Process#exitValue()} or {@link HeapAnalyserLauncher#KErrCommandLineLaunchingFailed} + * if an exception occurs. + */ + public static int launchHeapAnalyser( String configurationFilePath ){ + String workingDirectory = getHeapAnalyserPath(); + String heapAnalyserCommand = workingDirectory + "HeapAnalyser.exe"; + + // surround file paths with quotation marks so that spaces in file names wont cause failure. + heapAnalyserCommand = surroundWithQuotation( heapAnalyserCommand ); + configurationFilePath = surroundWithQuotation( configurationFilePath ); + + String commandLineCommand = heapAnalyserCommand + COMMAND_LINE_COMMAND + configurationFilePath; + + int returnValue = 0; + + File file = new File(workingDirectory); + + // execute HeapAnalyser.exe + try { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Starting Heap Analyser: " + commandLineCommand); //$NON-NLS-N$ + Process p = Runtime.getRuntime().exec(commandLineCommand, null, file); + p.waitFor(); + returnValue = p.exitValue(); + } + catch (Exception e) { + return KErrCommandLineLaunchingFailed; + } + + return returnValue; + + + } + + /** + * Gets the path where HeapAnalyserConsole.exe is located + * @return the path where HeapAnalyserConsole.exe is located + */ + private static String getHeapAnalyserPath() { + String heapAnalyserExePath = HeapAnalyserPlugin.getPluginInstallPath(); + if (!heapAnalyserExePath.endsWith(File.separator)){ + heapAnalyserExePath += File.separator; + } + heapAnalyserExePath += EXE_FOLDER + File.separator; + return heapAnalyserExePath; + } + + private static String surroundWithQuotation( String text ){ + String retVal = "\""; + retVal = retVal + text + retVal; + return retVal; + } + + /** + * Gets HeapAnalyser launcher error message. + */ + public static String getErrorMessage(int returnValue ){ + switch(returnValue){ + case HeapAnalyserLauncher.KErrCommandLineLaunchingFailed:{ + return "MemSpy was unable to start analysing imported files."; + } + case HeapAnalyserLauncher.KErrCommandLineGeneral:{ + return "Unspecified or general error"; + } + case HeapAnalyserLauncher.KErrCommandLineArgumentsMissing:{ + return "An error occurred when starting Heap Analyser.(Command line argument missing)"; + } + case HeapAnalyserLauncher.KErrCommandLineInvalidCommand:{ + return "An error occurred when starting Heap Analyser.(Input command not specified)"; + } + case HeapAnalyserLauncher.KErrCommandLineArgumentsFileNotFound:{ + return "An error occurred when starting Heap Analyser.(Input.xml file not found)"; + } + case HeapAnalyserLauncher.KErrCommandLineArgumentsFileInvalid:{ + return "An error occurred when starting Heap Analyser.(Unable to read input file. Perhaps your symbol or map files are moved/renamed. )"; + } + case HeapAnalyserLauncher.KErrCommandLineSourceFileNotFound:{ + return "An error occurred when starting Heap Analyser.(Unable to read source file)"; + } + case HeapAnalyserLauncher.KErrCommandLineDebugMetaDataMissing:{ + return "An error occurred when starting Heap Analyser.(Symbol files were not found)"; + } + case HeapAnalyserLauncher.KErrCommandLineUINotAvailable:{ + return "An error occurred when starting Heap Analyser.(Command line UI not available)"; + } + case HeapAnalyserLauncher.KErrCommandLineAnalysisTypeNotSupported:{ + return "An error occurred when starting Heap Analyser.(Analysis type not supported)"; + } + case HeapAnalyserLauncher.KErrCommandLineAnalysisThreadNameInvalid:{ + return "An error occurred when starting Heap Analyser.(Thread name invalid)"; + } + case HeapAnalyserLauncher.KErrCommandLineAnalysisOutputInvalid:{ + return "An error occurred when starting Heap Analyser.(Output file invalid)"; + } + default: + return "An unknown error occurred when starting Heap Analyser. " + + "Check software prerequisites from release notes " + + "(e.g. check correct version of .NET framework is installed)."; + } + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/META-INF/MANIFEST.MF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Carbide.c++ Extensions - MemSpy Help Plug-in +Bundle-SymbolicName: com.nokia.s60tools.memspy.help;singleton:=true +Bundle-Version: 1.6.0 +Bundle-Vendor: Nokia diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/about.html Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,19 @@ + + + +About + + + + +

About This Content

+

April 21, 2010

+ +

Copyright

+ +

Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: http://www.eclipse.org/legal/epl-v10.html.

+ + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/book.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/book.css Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,184 @@ +/* + Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + All rights reserved. + License: http://www.eclipse.org/legal/epl-v10.html +*/ + +/* Add whitespace around entire display to avoid crowding edges of view */ +/* 20070523-Removed top margin size to close gap between location breadcrumbs and page title */ +html { + margin: 2px 10px 10px 10px; + } + +/* Set default font to serif style, 12-pt and plain */ +body, p, table { + font-family: Verdana, Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; +} + +/* Use sans-serif fonts for all title styles */ +h1, h2, h3, h4, h5, h6, strong, em { + font-family: Verdana, Helvetica, Arial, sans-serif; + color: #000000; + } + +h1 { font-size:20px } +h2 { font-size:18px } +h3 { font-size:16px } +h4 { font-size:14px } +h5 { font-size:13px } +h6 { font-size:12px } + +/* For headlines at the top of a view, add space */ +/* 20090224-changed green fade to gold header image */ +h1, h2, h3 { + background-image: url(html/images/gold_header.png); + background-repeat: no-repeat; + padding:10px 0px 10px 12px; + } + +li { + margin-bottom:8px; + margin-top:8px; + } + +/* Footer includes space and a gray line above the company logo */ +#footer { + padding-top:10px; + margin-top:20px; + border-top:1px solid #999; + font-family: Helvetica, sans-serif; + font-size: 11px; + color:#333; + } + +.listing { + font-family: "Courier New", Courier, mono; + color: #000000; + background-color: #FFFFCC; + margin: 5px 0px; + } + +.code, pre { + font-family: "Courier New", Courier, mono; + font-size: 13px; + color: #000000; + } + +.step { + /* background-color: #EEE; */ + /* margin: 10px 0px; */ + /* color: #111; */ + /* border-bottom:2px solid #EEE; */ + } + +.substep { + background-color: #EEE; + } + + +/* Figure/Listing/Table titles are centered and gray */ +p.table { + color: #999; + font-weight: bold; + padding-top: 5px; + } + +table { + border: solid #999 1px; + table-layout: auto; + font-size: 13px; + } + +td, th { + border: solid #999 1px; + padding: 5px; + vertical-align:top; + } + +/* 20070522-replaced gray with green background to match gradiant color for title */ +th { + background-color:#FFC550; /* background-color:#acd79b; + background-color:#999; + color:#FFF; */ + } + +div.ol.p { + margin-left: 3em; + } + +/* Make all ordered/unordered list items appear in bold gray */ +div ol > li, div ul > li { + font-weight:bold; + color: #333; + } + +div ol > p, div ul > p, div li > p { + font-weight:normal; + } + +/* Make all H4 and H5 items appear in bold gray against a light green background */ +div h5, div h4 { + padding:5px 0px 5px 12px; + background-color:#FDCB2F; + /* background-color: #EEE; */ + font-weight:bold; + color: #000000; + } + + +/* Notes stand out using a light top & bottom borders with dark gray text */ +p.note { + /* color: #03C; */ + /* background-color: #FFFF99; */ + color: #333; + padding: 5px; + margin-left: 1em; + margin-right: 1em; + border-top: solid #BBB thin; + border-bottom: solid #BBB thin; + } + + +/* Figure/Listing/Table titles are centered and gray */ +p.figure { + color: #333; + text-align: center; + font-weight: bold; + } + +/* highly visible red background and white text for things that need fixing before release */ +/* SHOULD NOT BE PRESENT IN RELEASED PRODUCTS */ +.fix { + background-color: red; + font-weight: bold; + color: white; + } + +.question { + font-style:italic; + font-weight:bold; + color: #555; + } + +.titleSmall { + font-family: Helvetica, sans-serif; + font-size: 11px; + } + + +.plain { + font-family: Helvetica, sans-serif; + font-size: 12px; + font-style: normal; + line-height: normal; + font-weight: normal; + font-variant: normal; + color: #000000; + text-decoration: none; + } + +a:link { color: #0033CC } +a:visited { color: #555555 } +a:hover { color: #0033CC } diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,26 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + html/,\ + about.html,\ + book.css,\ + build.properties + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/concepts.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/concepts.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,25 @@ + + + + +Concepts + + + + +

Concepts

+

The following concepts provide information on MemSpy +terminology, technologies, and processes:

+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/files.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/files.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,30 @@ + + + + +Symbol and Map files + + + + +

Symbol and Map files

+

In the MemSpy Import Wizard, you have to define at least one symbol file. Defining map files is optional.

+ +

Symbol files

+

When you create an image, symbol files are generated automatically. Symbol files contain the binary structure of an image, which is needed for producing an analysis file. You can find a symbol file for example from \epoc32\rombuild\<device>\core.

+

After defining symbol files, you can also define map files.

+ +

Map files

+

If you want to define map files, you can select the Map files folder option to define the location of map files, or you can select MapFiles.zip option if you want to provide a ZIP file containing the map files. If you choose the SDK Map files folder option, the MemSpy Import Wizard checks which SDKs you have installed in Carbide.c++, and lists the directories of each SDK which contain map files. Choose the directory you want. If you do not want to define any map files, select the No map files option.

+ +
Related task
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_analyser.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_analyser.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,40 @@ + + + + + Heap Analyser + + + + +

Heap Analyser

+ +

Heap Analyser is a PC side tool for graphically displaying and analyzing +heap dumps produced by the MemSpy S60 application and imported to PC with the +MemSpy Carbide.c++ Extension. Heap Analyser is automatically started after you +import a heap dump file with the MemSpy Carbide.c++ Extension.

+ +
Related references
+ + +
Related tasks
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_dump.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_dump.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,27 @@ + + + + +Heap Dump + + + + +

Heap Dump

+

A Heap Dump is a log file that contains actual data contents of a specific heap. Heap Dumps can be read and analysed with the Heap Analyser tool.

+ +
Related concepts
+ + +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/memspy.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/memspy.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,18 @@ + + + + +MemSpy and MemSpy Launcher S60 applications + + + + +

MemSpy and MemSpy Launcher S60 applications

+

The MemSpy S60 application tracks various subsystems that directly or indirectly contribute to overall system memory usage and provides information about the changes in these subsystems at specified time intervals.

+

The memory tracing functionality of MemSpy can be targeted at a specific thread to analyze the memory changes that occur during the life cycle of the thread.

+

The MemSpy Launcher S60 application listens to TraceCore for activation messages from the MemSpy Carbide.c++ Extension. After receiving an activation message, MemSpy Launcher commands MemSpy.

+ + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmt_log.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmt_log.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,21 @@ + + + + +System Wide Memory Tracking log + + + + +

System Wide Memory Tracking log

+

A System Wide Memory Tracker log file contains information about system wide memory status changes over time.

+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmtanalyser.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmtanalyser.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ + + + + +SWMT Analyser + + + + +

SWMT Analyser

+

SWMT Analyser is a Carbide.c++ Extension for analyzing System Wide Memory Tracking logs produced by the MemSpy S60 application and imported to PC with the MemSpy Carbide.c++ Extension. SWMT Analyzer is launched automatically after you import a SWMT log file using the MemSpy Carbide.c++ Extension.

+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/contexts.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/contexts.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,74 @@ + + + + + + MemSpy Main View + + + + + MemSpy Tasks + + + + + Importing and analyzing heap dump files + + + + + Symbol and Map files + + + + + Importing and comparing two heap dump files + + + + + Importing and analyzing System Wide Memory Tracking log files + + + + + Setting System Wide Memory Tracking tracked categories + + + + + Configuring connection settings + + + + Generating PDF reports + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/GS_index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/GS_index.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,21 @@ + + + + +Getting started + + + + +

Getting started

+

The information in this section will help you get started quickly using the basic features of the MemSpy Extension for Carbide.c++.

Topics in this section include:

+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/overview.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/overview.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,36 @@ + + + + +Overview + + + + +

Overview

+

The MemSpy Carbide.c++ Extension is a tool for importing heap dumps and System Wide Memory Tracking logs from a device to a PC for analysis with Heap Analyser or SWMT Analyser. The MemSpy S60 application is used to track memory usage in a device at specified time intervals and produce the heap dump and SWMT log files.

By using the MemSpy S60 application and Carbide.c++ extension you can analyze:

+ + +
Related concepts
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/prerequisites.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/prerequisites.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,23 @@ + + + + +Prerequisites for use + + + + +

Prerequisites for use

+

Before you start using MemSpy, check the following items:

+ +

If you are importing log files from a disk, there are no prerequisites.

+

If you are importing log files from a target device, check that you have a TraceCore connection from the target device to the PC.

+ +

The MemSpy connection to a target device uses the MemSpy Launcher application that runs in the background in the device. The Launcher application is delivered with the MemSpy Carbide.c++ Extension as an RnD signed SIS file that is located in the plugins\com.nokia.s60tools.memspy.trace_X.Y.Z\Launcher.binaries folder in the Carbide.c++ installation folder in which X.Y.Z is plugin version number.

+ +

In addition, note that USB tracing requires that you have a tracing application such as TraceCoreUserApp or TraceSwitch installed in your target device.

+ + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/walk_through.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/walk_through.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,45 @@ + + + + + Basic walk-through + + + + +

Basic walk-through

+ +

You can begin importing and analyzing heap dump and SWMT log files by +activating the MemSpy Import Wizard. Select Carbide > MemSpy +and then take the following steps:

+
    +
  1. Select an action (Importing and + analyzing heap dump files, Importing and comparing two heap dump + files, or Importing and analyzing + System Wide Memory Tracking log files.
  2. +
  3. Select files to be imported and analyzed or compared. If you are + comparing two heap dumps, define the reporting settings.
  4. +
  5. When importing heap dumps, define the location of symbol and map files. +

    If the heap dumps are large, increase the buffer size in the tracing + application such as TraceCoreUserApp or TraceSwitch.

    +
  6. +
  7. Start analyzing the files.
  8. +
+ +

When the files have been imported, they will be displayed in the +MemSpy tab in the Carbide.c++ Tabbed View Area, and if you imported a +single heap dump file or SWMT log files, Heap Analyser or SWMT Analyser application will be +automatically launched for analyzing the files.

+ +

You can launch the MemSpy Import Wizard also by selecting File > +Import > Carbide Extensions > MemSpy.

+ + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Analyse_Heap.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Analyse_Heap.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Compare_2_Heaps.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Compare_2_Heaps.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Launch_SWMT.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Launch_SWMT.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Memspy_16.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Memspy_16.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_PDF_options.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_PDF_options.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_graph.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_graph.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Thumbs.db Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Thumbs.db has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/about_cpp.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/about_cpp.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/background_carbide.jpg Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/background_carbide.jpg has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/brandmark_cpp.gif Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/brandmark_cpp.gif has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_01.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_01.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_platsim.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_platsim.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_usb.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_usb.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/gold_header.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/gold_header.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/green_fade_left_68_165_28.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/green_fade_left_68_165_28.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_list.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_list.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_size_distributions.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_size_distributions.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_allocated_cell_size.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_allocated_cell_size.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_associated_binary.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_associated_binary.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_cell_overhead.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_cell_overhead.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_free_cell_size.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_free_cell_size.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_size_by_cell_index.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_size_by_cell_index.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_cell_length.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_cell_length.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_isolation.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_isolation.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_object_type.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_object_type.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_parent_binary.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_parent_binary.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_pervasiveness.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_pervasiveness.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_objects.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_objects.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_relationships.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_relationships.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_device.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_device.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_filesystem.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_filesystem.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_1.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_1.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_2.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_2.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_3.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_3.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/output_in_excel.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/output_in_excel.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/test_results_zip.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/test_results_zip.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/index.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/index.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/legal.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/legal.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,748 @@ + + + + +License Information + + + + +

License Information

+ +

COPYRIGHTS

+

Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. This component and the accompanying materials are made available under the terms of "Eclipse Public License v1.0" which accompanies this distribution and is available at the URL http://www.eclipse.org/legal/epl-v10.html.

+

Initial Contributors:
+Nokia Corporation - initial contribution

+ +

NOTICES

+ +

Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.

+

Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met:

+ + +

Neither the name of Sun Microsystems, Inc. or the names of +contributors may be used to endorse or promote products derived +from this software without specific prior written permission.

+

This software is provided "AS IS," without a warranty of any +kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND +WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY +EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL +NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF +USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS +DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR +ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, +CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND +REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR +INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES.

+

You acknowledge that this software is not designed or intended for +use in the design, construction, operation or maintenance of any +nuclear facility.

+ +

----

+ +

Copyright (c) 1988-1997 Sam Leffler
+Copyright (c) 1991-1997 Silicon Graphics, Inc.

+ +

Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics.

+

THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

+

IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE.

+ +

----

+ +

COPYRIGHT AND PERMISSION NOTICE

+

Copyright (C) 1991-2007 Unicode, Inc. All rights reserved. Distributed under +the Terms of Use in http://www.unicode.org/copyright.html.

+ +

Permission is hereby granted, free of charge, to any person obtaining a copy +of the Unicode data files and any associated documentation (the "Data Files") +or Unicode software and any associated documentation (the "Software") to deal +in the Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell copies +of the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that (a) the above copyright +notice(s) and this permission notice appear with all copies of the Data Files +or Software, (b) both the above copyright notice(s) and this permission notice +appear in associated documentation, and (c) there is clear notice in each +modified Data File or in the Software as well as in the documentation associated +with the Data File(s) or Software that the data or software has been modified.

+

THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE +LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.

+ +

Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in these Data Files or Software without prior written authorization of the +copyright holder.

+ + +

Mozilla Public License Version 1.1

+ +
1. Definitions.
+
+
1.0.1. "Commercial Use" +
means distribution or otherwise making the Covered Code available to a third party. +
1.1. "Contributor" +
means each entity that creates or contributes to the creation of Modifications. +
1.2. "Contributor Version" +
means the combination of the Original Code, prior Modifications used by a Contributor, + and the Modifications made by that particular Contributor. +
1.3. "Covered Code" +
means the Original Code or Modifications or the combination of the Original Code and + Modifications, in each case including portions thereof. +
1.4. "Electronic Distribution Mechanism" +
means a mechanism generally accepted in the software development community for the + electronic transfer of data. +
1.5. "Executable" +
means Covered Code in any form other than Source Code. +
1.6. "Initial Developer" +
means the individual or entity identified as the Initial Developer in the Source Code + notice required by Exhibit A. +
1.7. "Larger Work" +
means a work which combines Covered Code or portions thereof with code not governed + by the terms of this License. +
1.8. "License" +
means this document. +
1.8.1. "Licensable" +
means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently acquired, any and all of the rights + conveyed herein. +
1.9. "Modifications" +
+ means any addition to or deletion from the substance or structure of either the + Original Code or any previous Modifications. When Covered Code is released as a + series of files, a Modification is: +
    +
  1. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. +
  2. Any new file that contains any part of the Original Code or + previous Modifications. +
+
1.10. "Original Code" +
means Source Code of computer software code which is described in the Source Code + notice required by Exhibit A as Original Code, and which, + at the time of its release under this License is not already Covered Code governed + by this License. +
1.10.1. "Patent Claims" +
means any patent claim(s), now owned or hereafter acquired, including without + limitation, method, process, and apparatus claims, in any patent Licensable by + grantor. +
1.11. "Source Code" +
means the preferred form of the Covered Code for making modifications to it, + including all modules it contains, plus any associated interface definition files, + scripts used to control compilation and installation of an Executable, or source + code differential comparisons against either the Original Code or another well known, + available Covered Code of the Contributor's choice. The Source Code can be in a + compressed or archival form, provided the appropriate decompression or de-archiving + software is widely available for no charge. +
1.12. "You" (or "Your") +
means an individual or a legal entity exercising rights under, and complying with + all of the terms of, this License or a future version of this License issued under + Section 6.1. For legal entities, "You" includes any entity + which controls, is controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or otherwise, or (b) + ownership of more than fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. +
+ +
2. Source Code License.
+
2.1. The Initial Developer Grant.
+

The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive + license, subject to third party intellectual property claims: +

    +
  1. under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, + sublicense and distribute the Original Code (or portions thereof) with or without + Modifications, and/or as part of a Larger Work; and +
  2. under Patents Claims infringed by the making, using or selling + of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or + otherwise dispose of the Original Code (or portions thereof). +
  3. the licenses granted in this Section 2.1 + (a) and (b) are effective on + the date Initial Developer first distributes Original Code under the terms of this + License. +
  4. Notwithstanding Section 2.1 (b) + above, no patent license is granted: 1) for code that You delete from the Original Code; + 2) separate from the Original Code; or 3) for infringements caused by: i) the + modification of the Original Code or ii) the combination of the Original Code with other + software or devices. +
+ +
2.2. Contributor Grant.
+

Subject to third party intellectual property claims, each Contributor hereby grants You + a world-wide, royalty-free, non-exclusive license +

    +
  1. under intellectual property rights (other than patent or trademark) + Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and + distribute the Modifications created by such Contributor (or portions thereof) either on + an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger + Work; and +
  2. under Patent Claims infringed by the making, using, or selling of + Modifications made by that Contributor either alone and/or in combination with its + Contributor Version (or portions of such combination), to make, use, sell, offer for + sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor + (or portions thereof); and 2) the combination of Modifications made by that Contributor + with its Contributor Version (or portions of such combination). +
  3. the licenses granted in Sections 2.2 + (a) and 2.2 (b) are effective + on the date Contributor first makes Commercial Use of the Covered Code. +
  4. Notwithstanding Section 2.2 (b) + above, no patent license is granted: 1) for any code that Contributor has deleted from + the Contributor Version; 2) separate from the Contributor Version; 3) for infringements + caused by: i) third party modifications of Contributor Version or ii) the combination of + Modifications made by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code + in the absence of Modifications made by that Contributor. +
+ +
3. Distribution Obligations.
+
3.1. Application of License.
+

The Modifications which You create or to which You contribute are governed by the terms + of this License, including without limitation Section 2.2. The + Source Code version of Covered Code may be distributed only under the terms of this License + or a future version of this License released under Section 6.1, + and You must include a copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code version that alters or + restricts the applicable version of this License or the recipients' rights hereunder. + However, You may include an additional document offering the additional rights described in + Section 3.5. + +

3.2. Availability of Source Code.
+

Any Modification which You create or to which You contribute must be made available in + Source Code form under the terms of this License either on the same media as an Executable + version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic Distribution Mechanism, + must remain available for at least twelve (12) months after the date it initially became + available, or at least six (6) months after a subsequent version of that particular + Modification has been made available to such recipients. You are responsible for ensuring + that the Source Code version remains available even if the Electronic Distribution + Mechanism is maintained by a third party. + +

3.3. Description of Modifications.
+

You must cause all Covered Code to which You contribute to contain a file documenting the + changes You made to create that Covered Code and the date of any change. You must include a + prominent statement that the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the Initial Developer in + (a) the Source Code, and (b) in any notice in an Executable version or related documentation + in which You describe the origin or ownership of the Covered Code. + +

3.4. Intellectual Property Matters
+
(a) Third Party Claims
+

If Contributor has knowledge that a license under a third party's intellectual property + rights is required to exercise the rights granted by such Contributor under Sections + 2.1 or 2.2, Contributor must include a + text file with the Source Code distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will know whom to contact. If + Contributor obtains such knowledge after the Modification is made available as described in + Section 3.2, Contributor shall promptly modify the LEGAL file in + all copies Contributor makes available thereafter and shall take other steps (such as + notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who + received the Covered Code that new knowledge has been obtained. + +

(b) Contributor APIs
+

If Contributor's Modifications include an application programming interface and Contributor + has knowledge of patent licenses which are reasonably necessary to implement that + API, Contributor must also include this information in the + legal file. + +

(c) Representations.
+

Contributor represents that, except as disclosed pursuant to Section 3.4 + (a) above, Contributor believes that Contributor's Modifications + are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the + rights conveyed by this License. + +

3.5. Required Notices.
+

You must duplicate the notice in Exhibit A in each file of the + Source Code. If it is not possible to put such notice in a particular Source Code file due to + its structure, then You must include such notice in a location (such as a relevant directory) + where a user would be likely to look for such a notice. If You created one or more + Modification(s) You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership rights relating to + Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity + or liability obligations to one or more recipients of Covered Code. However, You may do so + only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You + must make it absolutely clear than any such warranty, support, indemnity or liability + obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer + and every Contributor for any liability incurred by the Initial Developer or such Contributor + as a result of warranty, support, indemnity or liability terms You offer. + +

3.6. Distribution of Executable Versions.
+

You may distribute Covered Code in Executable form only if the requirements of Sections + 3.1, 3.2, + 3.3, 3.4 and + 3.5 have been met for that Covered Code, and if You include a + notice stating that the Source Code version of the Covered Code is available under the terms + of this License, including a description of how and where You have fulfilled the obligations + of Section 3.2. The notice must be conspicuously included in any + notice in an Executable version, related documentation or collateral in which You describe + recipients' rights relating to the Covered Code. You may distribute the Executable version of + Covered Code or ownership rights under a license of Your choice, which may contain terms + different from this License, provided that You are in compliance with the terms of this + License and that the license for the Executable version does not attempt to limit or alter the + recipient's rights in the Source Code version from the rights set forth in this License. If + You distribute the Executable version under a different license You must make it absolutely + clear that any terms which differ from this License are offered by You alone, not by the + Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial Developer or such Contributor as + a result of any such terms You offer. + +

3.7. Larger Works.
+

You may create a Larger Work by combining Covered Code with other code not governed by the + terms of this License and distribute the Larger Work as a single product. In such a case, + You must make sure the requirements of this License are fulfilled for the Covered Code. + +

4. Inability to Comply Due to Statute or Regulation.
+

If it is impossible for You to comply with any of the terms of this License with respect to + some or all of the Covered Code due to statute, judicial order, or regulation then You must: + (a) comply with the terms of this License to the maximum extent possible; and (b) describe + the limitations and the code they affect. Such description must be included in the + legal file described in Section + 3.4 and must be included with all distributions of the Source Code. + Except to the extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to understand it. + +

5. Application of this License.
+

This License applies to code to which the Initial Developer has attached the notice in + Exhibit A and to related Covered Code. + +

6. Versions of the License.
+
6.1. New Versions
+

Netscape Communications Corporation ("Netscape") may publish revised and/or new versions + of the License from time to time. Each version will be given a distinguishing version number. + +

6.2. Effect of New Versions
+

Once Covered Code has been published under a particular version of the License, You may + always continue to use it under the terms of that version. You may also choose to use such + Covered Code under the terms of any subsequent version of the License published by Netscape. + No one other than Netscape has the right to modify the terms applicable to Covered Code + created under this License. + +

6.3. Derivative Works
+

If You create or use a modified version of this License (which you may only do in order to + apply it to code which is not already Covered Code governed by this License), You must (a) + rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", + "NPL" or any confusingly similar phrase do not appear in your license (except to note that + your license differs from this License) and (b) otherwise make it clear that Your version of + the license contains terms which differ from the Mozilla Public License and Netscape Public + License. (Filling in the name of the Initial Developer, Original Code or Contributor in the + notice described in Exhibit A shall not of themselves be deemed to + be modifications of this License.) + +

7. Disclaimer of warranty
+

Covered code is provided under this license on an "as is" + basis, without warranty of any kind, either expressed or implied, including, without + limitation, warranties that the covered code is free of defects, merchantable, fit for a + particular purpose or non-infringing. The entire risk as to the quality and performance of + the covered code is with you. Should any covered code prove defective in any respect, you + (not the initial developer or any other contributor) assume the cost of any necessary + servicing, repair or correction. This disclaimer of warranty constitutes an essential part + of this license. No use of any covered code is authorized hereunder except under this + disclaimer. + +

8. Termination
+

8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure such breach + within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which + are properly granted shall survive any termination of this License. Provisions which, by + their nature, must remain in effect beyond the termination of this License shall survive. +

8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer or a Contributor + (the Initial Developer or Contributor against whom You file such action is referred to + as "Participant") alleging that: +

    +
  1. such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such Participant to You under + Sections 2.1 and/or 2.2 of this + License shall, upon 60 days notice from Participant terminate prospectively, unless if + within 60 days after receipt of notice You either: (i) agree in writing to pay + Participant a mutually agreeable reasonable royalty for Your past and future use of + Modifications made by such Participant, or (ii) withdraw Your litigation claim with + respect to the Contributor Version against such Participant. If within 60 days of + notice, a reasonable royalty and payment arrangement are not mutually agreed upon in + writing by the parties or the litigation claim is not withdrawn, the rights granted by + Participant to You under Sections 2.1 and/or + 2.2 automatically terminate at the expiration of the 60 day + notice period specified above. +
  2. any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then any rights + granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first + made, used, sold, distributed, or had made, Modifications made by that Participant. +
+ +

8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or indirectly infringes + any patent where such claim is resolved (such as by license or settlement) prior to the + initiation of patent infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or + 2.2 shall be taken into account in determining the amount or + value of any payment or license. +

8.4. In the event of termination under Sections + 8.1 or 8.2 above, all end user + license agreements (excluding distributors and resellers) which have been validly + granted by You or any distributor hereunder prior to termination shall survive + termination. + +

9. Limitation of liability
+

Under no circumstances and under no legal theory, whether + tort (including negligence), contract, or otherwise, shall you, the initial developer, + any other contributor, or any distributor of covered code, or any supplier of any of + such parties, be liable to any person for any indirect, special, incidental, or + consequential damages of any character including, without limitation, damages for loss + of goodwill, work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses, even if such party shall have been informed of the + possibility of such damages. This limitation of liability shall not apply to liability + for death or personal injury resulting from such party's negligence to the extent + applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion + or limitation of incidental or consequential damages, so this exclusion and limitation + may not apply to you. + +

10. U.S. government end users
+

The Covered Code is a "commercial item," as that term is defined in 48 + C.F.R. 2.101 (Oct. 1995), consisting of + "commercial computer software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. + 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. + 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users + acquire Covered Code with only those rights set forth herein. + +

11. Miscellaneous
+

This License represents the complete agreement concerning subject matter hereof. If + any provision of this License is held to be unenforceable, such provision shall be + reformed only to the extent necessary to make it enforceable. This License shall be + governed by California law provisions (except to the extent applicable law, if any, + provides otherwise), excluding its conflict-of-law provisions. With respect to + disputes in which at least one party is a citizen of, or an entity chartered or + registered to do business in the United States of America, any litigation relating to + this License shall be subject to the jurisdiction of the Federal Courts of the + Northern District of California, with venue lying in Santa Clara County, California, + with the losing party responsible for costs, including without limitation, court + costs and reasonable attorneys' fees and expenses. The application of the United + Nations Convention on Contracts for the International Sale of Goods is expressly + excluded. Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this License. + +

12. Responsibility for claims
+

As between Initial Developer and the Contributors, each party is responsible for + claims and damages arising, directly or indirectly, out of its utilization of rights + under this License and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +

13. Multiple-licensed code
+

Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits + you to utilize portions of the Covered Code under Your choice of the MPL + or the alternative licenses, if any, specified by the Initial Developer in the file + described in Exhibit A. + +

Exhibit A - Mozilla Public License.
+
"The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is ______________________________________.
+
+The Initial Developer of the Original Code is ________________________.
+Portions created by ______________________ are Copyright (C) ______
+_______________________. All Rights Reserved.
+
+Contributor(s): ______________________________________.
+
+Alternatively, the contents of this file may be used under the terms
+of the _____ license (the  "[___] License"), in which case the
+provisions of [______] License are applicable instead of those
+above. If you wish to allow use of your version of this file only
+under the terms of the [____] License and not to allow others to use
+your version of this file under the MPL, indicate your decision by
+deleting the provisions above and replace them with the notice and
+other provisions required by the [___] License. If you do not delete
+the provisions above, a recipient may use your version of this file
+under either the MPL or the [___] License."
+ +

NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.

+

+ +

Apache License

+

Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/ +

+

+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +

+

1. Definitions.

+

+ "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. +

+

+ "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + +

+

+ "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. +

+

+ "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. +

+

+ "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. +

+

+ "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. +

+ +

+ "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). +

+

+ "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. +

+

+ "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." +

+

+ "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. +

+

2. Grant of Copyright License. +Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +

+

3. Grant of Patent License. +Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. +

+

4. Redistribution. +You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: +

    +
  1. You must give any other recipients of the Work or + Derivative Works a copy of this License; and +

  2. + +
  3. You must cause any modified files to carry prominent notices + stating that You changed the files; and +

  4. + +
  5. You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and +

  6. + +
  7. If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License.
  8. +
+ You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. +

+

5. Submission of Contributions. +Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. +

+

6. Trademarks. +This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. +

+

7. Disclaimer of Warranty. +Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. +

+

8. Limitation of Liability. +In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +

+

9. Accepting Warranty or Additional Liability. +While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. +

+

+END OF TERMS AND CONDITIONS +

+ + +

+ APPENDIX: How to apply the Apache License to your work +

+
+

+ To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +

+
+ Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +
+ + + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/HA_data_analysis.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/HA_data_analysis.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,40 @@ + + + + + + + Data Analysis with Heap Analyser + + + + +

Data Analysis with Heap Analyser

+ +

When analysing a single heap dump, Heap Analyser displays information about +the heap visually. The information is divided into six tabbed views:

+ + +

+ +

Tip: Tooltips are displayed when you hover over a View Type +selection. They give a very basic overview of the purpose of each view type.

+ +

Note: The Cell List, +Objects, Relationships, and Cell Size +Distributions tabs present much the same information as the +Heap View, only in simple list or table form.

+ + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/associated_binary.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/associated_binary.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,32 @@ + + + + + Associated Binary + + + + +

Associated Binary

+ +

The Associated Binary view is an alternative statistical representation of +the Parent Binary Heap View, in the style of the Objects tab. This view can +offer a quick way to establish which module is the greatest contributor to heap +allocation when aggregating all that module’s defined classes.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_lenght.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_lenght.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,32 @@ + + + + + Cell Lenght + + + + +

Cell Lenght

+ +

The Cell Length view is much like the Object Type in terms +of labelling, but it differs based on the allocated length of each object with +the intent to make it easier to quickly pick out the largest objects.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_list.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_list.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,30 @@ + + + + + Cell List + + + + +

Cell List

+ +

In the Cell List view, you can display a simple tabular representation of +all the cells in the heap displaying cell number, status (allocated/free), +address, length, and type when known. Double-clicking on a cell takes you to +its representation in the Heap View. The drop down box allows +you to filter by type.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_overhead.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_overhead.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,31 @@ + + + + + Cell Overhead + + + + +

Cell Overhead

+ +

Cell Overhead is a graphical representation of the space costs for the +heap’s book-keeping data. The smaller the objects in the heap are on +average, the greater the book-keeping data overheap will be as a percentage.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_size.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_size.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,28 @@ + + + + + Cell Size Distributions + + + + +

Cell Size Distributions

+ +

The Cell Size Distributions view displays a type-independent statistical +breakdown of the heap by cell size, both for free and allocated cells. This +view can be useful e.g. when evaluating heap fragmentation issues.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_type.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_type.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,74 @@ + + + + + Cell Type + + + + +

Cell Type

+ +

The Cell Type view is a low-level view of the layout of the heap. It is +useful for getting a quick feel for fragmentation, for example, but the other +views are more commonly used.

+ +

+ +

The Cell Type view breaks down the heap into word-sized (4 byte) blocks, +each represented by a coloured square. The following colour-coding is applied +to each related group of words for easy identification:

+ + +

The colour fade between the start and end of a group of words makes it +easier for you to pick out the beginning and the end of cells.

+ +

If you highlight a cell by hovering the mouse over it (the whole of the +associated cell is highlighted), you get a pop-up summary of its contents as a +tool-tip. You can also right-click to bring up a context menu of options.

+ +

If you click on a cell to select it, or navigate to it using the cursor keys +or the Previous / Next buttons, or search for it by address in +the Search box, then that cell will be selected and you will +get a summary in the Information box below.

+ + +

If you double-click on a cell, a floating memory inspector window will be +displayed, showing you the cell contents. Cells that contain references to +other memory locations are highlighted. Double-clicking a highlighted value +jumps to the referenced location.

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/free_cell_size.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/free_cell_size.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,32 @@ + + + + + Free Cell Size and Allocated Cell Size + + + + +

Free Cell Size and Allocated Cell Size

+ +

The Free Cell Size and Allocated Cell Size graphs display graphical +representations of free cell fragmentation and allocated cell size distribution +respectively.

+ +

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/graphs.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/graphs.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,31 @@ + + + + + Graphs + + + + +

Graphs

+ +

The Graphs view yields a course-grain statistical breakdown of the behaviour +and representation efficiency of the heap. It can be useful for identifying +problematic allocation patterns, bad interactions between allocation patterns +and the RHeap free cell reuse algorithms, and also the effectiveness of changes +to heap algorithms and client allocation patterns. See the following sections +for more details:

+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_analyser_overview.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_analyser_overview.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,50 @@ + + + + + Overview + + + + +

Heap Analyser overview

+ +

Heap Analyser is PC application used to graphically inspect and analyse +Symbian OS heap objects. It is the PC-side complement to the heap capture +technology of MemSpy and MemSpy Carbide.c++ +Extension. Use MemSpy or MemSpy Carbide Extension to capture heap +data, and then Heap Analyser to display and analyse the contents.

+ +

Heap Analyser contains the following features:

+ + +
Related references
+ + +
Related tasks
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_view.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_view.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,29 @@ + + + + + Heap View + + + + +

Heap View

+ +

In the Heap View, you can view information about the header and contents of +individual cell heaps. You can also search heaps by address or allocation +number. Double-clicking a cell displays detailed stack information. See the +following sections for more details:

+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/isolation.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/isolation.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,55 @@ + + + + + Isolation and Pervasiveness + + + + +

Isolation and Pervasiveness

+ +

The Isolation and Pervasiveness views are about highlighting reference +density.

+ +

The Isolation view shades objects from cold (blue) to hot +(more red) based on how “popular” they are with other objects. The +actual incoming reference count is also displayed in the box at the start of +each object. Darkest blue objects with a red zero count indicate objects that +have no references at all within the heap itself. That does not necessarily +mean they are orphans that have been leaked; they could be referenced from the +stack or from static variables instead. However, if you do think you may have a +memory leak then these zero count objects are a good place to start looking.

+ +

+ +

The Pervasiveness view is the inverse of the Isolation +view. In Pervasiveness view, objects are shaded from cold (blue) to hot (more +red) based on how many other objects they are “interested” in. The +actual outgoing reference count is also displayed in the box at the start of +the object. The other highlighted boxes within cells are the actual locations +of the potential outgoing references Heap Analyser has identified. As pure data +datatypes with no outgoing references, descriptors are distinguished in yellow +here. If you have a memory leak, bright red objects may be worth investigating +as the potential home to an abnormally large number of references. For example, +the buffer object within a large array of pointers may be highlighted in this +view, and in some cases could be the source of a leak e.g. due to forgetting to +delete objects from the array when they’re no longer needed.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/object_type.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/object_type.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,79 @@ + + + + + Object Type + + + + +

Object Type

+ +

The Object Type view presents the objects on the heap and their position +within it, just as in the Cell Type view, but by tagging them +with their C++ type name so that you can easily recognize the objects from your +own code. Determining an object’s type for display is usually possible +for the majority of objects in the heap, but not for them all. An +object’s type can usually be determined if

+ + +

If the object type cannot be determined, but there is a unique referrer for +the object type, or if all referrers are of the same known type, [Part of +XXX] is displayed, where XXX is the type of the referrer.

+ +

Otherwise, [Unknown] is displayed.

+ +

A virtual function in a class means each instance of that class will contain +a vtable pointer. The vtable pointer can be used, in combination with the +symbolic information provided at startup, to determine the name of the class +associated with the vtable for presentation. Symbian’s CBase defines a +virtual destructor, so all conventional C-prefixed classes in Symbian will have +a vtable and so be identifiable in this way.

+ +

There are a number of possibilities, but an [Unknown] or [Part +of XXX] object is typically either a raw (non-descriptor) data buffer, or +sometimes a T-class allocated on the heap. Because such an object is often +owned and encapsulated by an identifiable C-class, one effective strategy for +identifying objects, which type cannot be determined, is to use the incoming +reference information Heap Analyser constructs. If an otherwise unknown object +type has this reference information, it is displayed in the view as [Part +of XXX], where XXX is the type of the referrer. In addition, if you +right-click an object and select Go to… > +Incoming reference, the context menu will display the types of +the objects that refer to the object. In fact there are a number of +ways of visualizing object reference relationships available from the +right-click context menu, including drawing the link relationships between +objects as an overlay of dotted lines (right click and select +Relationships… > Incoming > +Breadcrumbs).

+ +

Colours are chosen arbitrarily on a type-by-type basis in this view, with +the exception of descriptors (Yellow), [Unknown] and [Part of +XXX] (Red), and free space (Blue). The colour allocation can be viewed and +refined by clicking Set Filters. This filter settings panel is +also useful for focusing down on just object types of particular interest; +click Enable None, then selectively enable just the types you +are interested in. To get an overview, select View > +Size > Small.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/objects.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/objects.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,29 @@ + + + + + Objects + + + + +

Objects

+ +

The Objects view breaks down the identified objects in the heap +statistically by type. This is the quickest way to determine which types of +objects are dominating allocated memory. Note that this tab cannot represent +[Unknown] objects..

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/parent_binary.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/parent_binary.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,46 @@ + + + + + Parent Binary + + + + +

Parent Binary

+ +

The Parent Binary view is effectively the same as the Object +Type view, except that instead of displaying each object’s type, +it displays the name of the object file that defined that type’s +vtable.

+ +

What this view does not do is record the logical allocation point of an +object, since that is simply not recoverable from the information available. +For example, if some of your own code contains a CFoo::NewL() where +CFoo is imported from a dll, then it will be an object file in the dll +that is displayed for the resulting allocated cell, not the object file +containing the call to NewL.

+ +

This view can be useful to quickly find a module that is contributing into a +heap objects that are unexpectedly large, or that you do not expect to be +there.

+ +

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/prerequisites_for_HA.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/prerequisites_for_HA.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,33 @@ + + + + + Prerequisites for using Heap Analyser + + + + +

Prerequisites for using Heap Analyser

+ +

Heap Analyser is distributed together with the MemSpy Carbide.c++ Extension +in the SymSEE delivery.

+ +

Heap Analyser requires the Microsoft .NET Framework v2.0.50727 or newer. You +can download the .NET Framework 2.0 installation package from http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=en.

+ +

The Compare functionality requires also Microsoft Office Excel 2003 or +newer.

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/references.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/references.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,26 @@ + + + + + + + References + + + + +

References

+ +

The following references are available for this tool:

+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/relationships.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/relationships.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,28 @@ + + + + + Relationships + + + + +

Relationships

+ +

The Relationships view is like Cell List, but when you select a cell from +the Cells table, its incoming and outgoing references can be viewed in the +bottom half of the view.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/saving_HA_reports.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/saving_HA_reports.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,41 @@ + + + + + Saving Heap Analyser reports + + + + +

Saving Heap Analyser reports

+ +

In Heap Analyser, you can save heap dump logs to several formats for further +analysis.

+ +

Select File > Save As, and then one of +the file formats:

+ + +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/size_by_cell_index.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/size_by_cell_index.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,33 @@ + + + + + Size by Cell Index + + + + +

Size by Cell Index

+ +

The Size by Cell Index graph displays a cell’s position in the heap +set against its size. An uneven distribution here may tell you something about +the phases and allocation patterns of the program under investigation. Note, +though, that while often aligned to a degree, a cell’s index is not an +indicator of age along the execution timeline due to cell re-use.

+ +

+ +
Related references
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/toolbar.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/toolbar.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,55 @@ + + + + + + Toolbar + + + + + +

Toolbar

+

The toolbar in the MemSpy view contains the following icons:

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ButtonDescription
Launch SWMT AnalyserLaunch SWMT Analyser.
Compare 2 heapsCompare two selected files, or import a file and compare it to a selected file. +
Analyse heapLaunch Heap Analyser and analyse the selected file(s).
Launch MemSpy importLaunch MemSpy Import Wizard.
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/troubleshooting.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/troubleshooting.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,115 @@ + + + + + Troubleshooting + + + + +

Troubleshooting

+ +

MemSpy

+ +

The MemSpy> Carbide.c++ Extension error messages are listed below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MessageDescription
MemSpy extension was unable to receive response from MemSpy + S60-application.The target device does not respond to requests sent from the MemSpy + Carbide.c++ Extension. Restart the target device. If you are using an + USB connection, make sure you have activated trace sending in + TraceSwitch or TraceCoreUserApp.
MemSpy s60-application was not found from your device.Your device has MemSpy Launcher, but not MemSpy S60 application + installed. Install MemSpy S60 application to the device and restart the + device.
Received log files are corrupt.The heap dump or SWMT log files are missing lines. If you are using + an USB connection, increase the buffer size in TraceSwitch or + TraceCoreUserApp.
No Heap Found.The selected thread is missing, probably because it has terminated. + Reload the thread list. If this does not help, restart the device.
Selected heap's heap type is wrong (needs to be Symbian OS + RHeap).The heap of the selected thread is not supported, and the heap dump + cannot be retrieved by MemSpy.
Invalid heap dump file. The file doesn't contain any threads with + binary data information.The file you are trying to import does not contain any threads with + binary data information, or contains a binary data error. The file will + not be imported.
+ +

SWMT Analyser

+ +

The SWMT Analyser error messages are listed below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
MessageDescription
xyz.xls file is already exists and opened, could not overwrite. + Please close it and try again.The Excel XLS file is already opened in the target folder.
+ Close the Excel file and try exporting to Excel again.
Invalid order of the log files. The selected files must be in + consecutive order and must start from the cycle 1.The selected files in the MemSpy view are not in consecutive order, + starting from cycle 1.
+ Select the log files and make sure that they are in consecutive order + and starting from cycle 1.
This is a delta file. It does not contain the complete + information. Do you still want to continue?You tried to open a single file which has a cycle number other than + 1.
+ Click Yes to continue, or No to cancel.
The file is invalid.SWMT Analyser cannot read the data from the log file. This may occur + if there are typos or other manual edits in the log file.
+ Please check the filename and the line number shown in the error + message, and act accordingly.
+ + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/release_notes.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/release_notes.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,210 @@ + + + + + Release Notes + + + + + +

Release Notes

+ +

MemSpy Carbide.c++ Extension – Version 1.6.0

+ +

Released 21st April 2010

+ + +

Product description

+ +

The MemSpy extension for Carbide.c++ is a tool for importing heap dumps and +System Wide Memory Tracking logs from a device to PC and analyzing them.

+ +

MemSpy can be started either by selecting Carbide > MemSpy, or +from File > Import > Carbide Extensions > MemSpy.

+ +

Main features

+ + +

What's new

+ + +

Installation notes

+ + +

System requirements

+ +

Basic requirements:

+ + +

Additional requirements:

+ + +

Compatibility issues

+ + +

Known issues

+ + +

Version history

+ +
Version 1.5.0 – 11th December 2009
+ + +
Version 1.4.0 – 5th October 2009
+ + +
Version 1.3.0 – 19th August 2009
+ + +
Version 1.2.1 – 14th August 2009
+ + +
Version 1.2.0 – 24th June 2009
+ + +
Version 1.1.0 – 9th April 2009
+ + +
Version 1.0.0 – 16th February 2009
+ +

The first version.

+ + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/analyse_data_using_graphs.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/analyse_data_using_graphs.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,38 @@ + + + + +Using SWMT Analyser + + + + +

Analysing data using graphs

+

SWMT Analyser represents the log data in a graphical format for the selected events and elements on the Graphs tab. The Graphs tab contains two tabs called Events and Graphed items.

+ + +

+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/compare_two_heaps.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/compare_two_heaps.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ + + + + + Importing and comparing two heap dump files + + + + +

Importing and comparing two heap dump files

+
    +
  1. Click the icon to start the MemSpy + Import Wizard.
  2. +
  3. Select to Import heap and compare logs with Heap Analyser, and + click Next.
  4. +
  5. Select whether to get the heap dumps From File System or + From Device via TraceViewer, and select the heap dump files to + import and compare.

    +
      +
    • If you selected From File System, define the first heap dump + file location and then a heap, and click Next. Select the second + file and heap in the same way, and click Next. Note that you can + only compare two dumps from the same thread.
    • +
    • If you selected From Device via TraceViewer, click + Load/Refresh Thread List to get a thread list from the device, + select the first heap to compare, click Get Selected Heap Now, + and click Next. Similarly, select the second heap to compare, + and click Next.
      + You can also filter the thread list by using the Starts with and + Contains selections.
    • +
    +

    If this fails, click Connection Settings and configure connection + settings.

    +
  6. +
  7. Define an output file location and name for the report file, and click + Next. The report is an MS Excel sheet (XLS) file.
  8. +
  9. Define the location of symbol and map files. You have to define at least + one symbol file. Defining map files is optional. For more information, see + Symbol and Map files.
  10. +
  11. Click Finish. A MemSpy tab appears in the Carbide.c++ Tabbed View + Area with a file list populated.
  12. +
  13. A confirmation dialog opens, asking if you want to view the generated + file in Excel. See the figure below for an example of the outfile in + Excel.
  14. +
+ +
Related references
+ + +
Related tasks
+ + +
Related concepts
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/connection_settings.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/connection_settings.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,58 @@ + + + + +Configuring connection settings + + + +

Configuring connection settings

+

If the connection to the target device fails, check and configure your connections settings:

+
    +
  1. In the step 1 of the MemSpy Import Wizard, click Connection +Settings. This takes you to the connection settings of the TraceViewer Carbide.c++ Extension.
  2. +
  3. In Use connection, select an existing connection to use and click OK, or click New... to create a new connection or Edit to edit an existing one. Follow the next steps if you selected to create a new connection or to edit an existing one.
  4. +
  5. In Connection name, enter a unique name for this connection. +

    In Connection type, select a connection method:

    +
      +
    • PlatSim if you are using a PlatSim connection between the PC and the target device.
    • +
    • TCP/IP Musti if you are using an XTI connection between the PC and the +target device.
    • +
    • USB if you are using a USB cable connection between the PC and +the target device.
    • +
    +

    Click Next. +

  6. + +
  7. Modify the connection settings:

    +
      +
    • For PlatSim and TCP/IP Musti: define the IP address to connect to and the OS to be used. +

    • + +
    • For USB: define the serial port used for USB connection on your PC (such as COM1) amd the OS to be used. To find out the port:

      +
        +
      1. Connect your phone to the PC using a USB cable and the Nokia PC Suite +application.
      2. +
      3. (Optional) If you connect for the first time, install the necessary drivers +to your phone.
      4. +
      5. In Windows, check the correct serial port from the Device Manager + in the Control Panel. Select Ports (COM & LPT), and +locate an item similar to Series 60 Nokia S60 Phone USB (COMX), where +X means the port to connect to.
      6. +
      +

      +
  8. +
  9. Click OK to save and exit.
  10. +
+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/generate_pdf_report.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/generate_pdf_report.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,38 @@ + + + + +Using SWMT Analyser + + + + +

Generating PDF reports

+
    +
  1. Go to the Analysis tab and click Generate report. This opens the Create Report dialog where you can select report options.
  2. +
  3. Select the type of report to be created: +
      +
    • If you select to Create report for the selected issues option, the report will contain a graph for the selected issues, and the graph area in the analysis tab is captured and written to the PDF file. Expand the graph area to get a clear graph. If no issues are selected in the Analysis tab, an error message will be displayed explaining that you need to select some issues in the analysis view.
    • +
    • If you select to Create overview report, a graph and only the overview of all the types of issues will be captured and written to the PDF file.
    • +
    +
  4. +
  5. (Optional) Enter comments that will appear at the end of the PDF report.
  6. +
  7. Enter a file path for the report file.
  8. +
  9. Click Finish. +

    +
  10. +
+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/tasks.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/tasks.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,30 @@ + + + + + +Tasks + + + +

Tasks

+

The following tasks are available for the MemSpy Carbide.c++ Extension:

+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/understanding_excel_data.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/understanding_excel_data.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,161 @@ + + + + +Using SWMT Analyser + + + + +

Understanding the Excel data

+

Because reading and analyzing SWMT log files is difficult, SWMT Analyser tool can write the log file data to an Excel sheet in an appropriate manner so that you can easily understand and analyse the data.

+

Excel contains different worksheets to represent various data such as heap-chunks, non heap-chunks, RAM and disk memory, and total heap size.

+ +

The Excel tabs and the information displayed in them are explained in the following table.

+ + +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TabDescription

Overview

+
    +
  • Cycle numbers, that is, numbers of selected log files to export, Time Period and Time Duration.
  • +
  • Total delta of various fields like Heap Size, Free Cell Count, Allocated Cell Count, Free Space, Allocated Space, Slack Space, Total files, and Total P&S Handles for all the threads.
  • +
  • Status of each thread in the last cycle and delta of various attributes for each thread.
  • +
+

Note: Stack size will be displayed for all threads which are alive.

+

RAM and Disk Memory

+
    +
  • Specifies the amount of used RAM and disk memory of all drives in bytes and for each cycle in seconds.
  • +
  • Shows how the used memory varies between RAM and other drives in each cycle.
  • +
+

Non-Heap Chunk Size

+
    +
  • Specifies the non-heap chunk sizes for all the threads that contain heap in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Global Chunk Size

+
    +
  • Specifies the global chunk sizes for all the threads that contain heap in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Total Heap Size

+
    +
  • Specifies the heap sizes for each thread and for each cycle.
  • +
  • Shows the difference between the first and the last cycle value.

    +
+

Total Heap Allocated Space

+
    +
  • Specifies the toal heap allocated space for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Total Heap Free Space

+
    +
  • Specifies the toal heap free space for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Allocated Heap Cell Count

+
    +
  • Specifies the allocated heap cell count for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Free Heap Cell Count

+
    +
  • Specifies the free heap cell count for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between first and the last cycle value.
  • +
+

Slack Space Size

+
    +
  • Specifies the free slack size for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between first and the last cycle value.
  • +
+

Largest Allocated Cell Size in Heap

+
    +
  • Specifies the largest allocated cell size in heap for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+

Largest Free Cell Size in Heap

+
    +
  • Specifies the largest free cell size in heap for each thread in bytes and for each cycle in seconds.
  • +
  • Shows the difference between the first and the last cycle value.
  • +
+
+ +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/use_swmt_analyser.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/use_swmt_analyser.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,59 @@ + + + + +Using SWMT Analyser + + + + +

Using SWMT Analyser

+

You can start the tool in any of the following ways:

+ + +
Preconditions
+

If more than one files are selected, check that the following requirements are met:

+ + +

SWMT Analyser will open in Carbide.c++ with two tabs called Overview and Graphs. In addition, an Analysis tab will be displayed only when there are issues found in the analysis. The Graphs tab will be displayed only when you have more than one file selected. When you have only one file selected, the Overview tab is displayed with the following information:

+ + + + +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_heap.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_heap.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,66 @@ + + + + + Importing and analyzing heap dump files + + + + +

Importing and analyzing heap dump files

+
    +
  1. Click the icon to start the MemSpy + Import Wizard.
  2. +
  3. Select to Import heap and analyse log with Heap Analyser, and + click Next.
  4. +
  5. Select whether to get the heap dumps From File System or + From Device via TraceViewer, select file(s) to import, and click + Next.

    +
      +
    • If you selected From File System, define the heap dump file + location and then a heap. +

      +
    • +
    • If you selected From Device via TraceViewer, click + Load/Refresh Thread List to get a thread list from the device, + select a heap, and click Get Selected Heap Now.
      + You can also filter the thread list by using the Starts with and + Contains selections. +

      +
    • +
    +

    If this fails, click Connection Settings and configure connection + settings.

    +
  6. +
  7. Define the location of symbol and map files. You have to define at least + one symbol file. Defining map files is optional. For more information, see + Symbol and Map files.
  8. +
  9. Click Finish. A MemSpy tab appears in the Carbide.c++ + Tabbed View Area with a file list populated, and Heap Analyser is + launched if you selected to import only one file. For more information, see + Data analysis with Heap + Analyser.
  10. +
+ +
Related references
+ + +
Related tasks
+ + +
Related concepts
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_issues_on_the_analysis_tab.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_issues_on_the_analysis_tab.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,45 @@ + + + + +Using SWMT Analyser + + + + +

Viewing issues on the Analysis tab

+

SWMT Analyser tool will analyse the data internally and list the issues found. The issues will be displayed in a tree format in three groups: RAM and Disk Memory, Threads, and SystemData.

+

The tool internally analyses some events for items such as RAM, Disks, Threads, Chunks and etc. The analysis finds the growth of these events based on some calculations and uses that as the growing factor. All issues displayed in the Analysis tab would be sorted in the descending order of the growing factor by default.

+

Each issue has four fields:

+ + +

A graph illustrating the checked issues will be automatically displayed on the top of the Analysis tab.

+ +

You can filter the issues by using the Severity dropdown or Select Custom filter in the drop-down menu.

+

You can save a graph as an image by using the Save graph… option in the context menu of the graph.

+ +

Note that the Overview tab will also display the top 5 issues.

+

If the thread dies and restarts again then that would be treated as separate instances, those thread instances will be respresented like 'thread_name(01)' and 'thread_name(02)'. +For example, assume that there are 100 cycles and a thread starts at cycle 1 and dies at cycle 10. And the same thread starts again at cycle 20. Then this thread will be considered as having two instances. +And those instances will be shown as 'thread_name(01)' and 'thread_name(02)' in Analysis tab. However, in Graphs tab this will be shown as single thread with 'thread_name'.

+ + +
Related tasks
+ + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_swmt_log.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_swmt_log.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ + + + + + Importing and analyzing System Wide Memory Tracking log files + + + + +

Importing and analyzing System Wide Memory Tracking log files

+
    +
  1. Click the icon to start the MemSpy + Import Wizard.
  2. +
  3. Select to Import System Wide Memory Tracking logs and analyse them + with SWMT Analyser, and click Next.
  4. +
  5. Select whether to get the SWMT log files From File System or + From Device via TraceViewer.

    +

    +
      +
    • If you selected From File System, define the SWMT log file + location and then a log file, and click Next.
    • +
    • If you selected From Device via TraceViewer, click Get + SWMT Log Now to get an SWMT log file from the device. After this + you can set a timer interval to get log files automatically at defined + intervals. Select the interval and click Start Timer. Note that + each log added with a timer or by clicking Get SWMT Log Now + contains only changes since the last received log. To stop the timer, + click Stop Timer.

      +

      +
    • +
    • In Tracked Categories and Advanced Options, select a + predefined set of categories, or select Custom Categories and + Advanced Options and click Edit. In the Advanded + Options, you can select categories for SWMT logging and customise + the logging options. +

      To stop the S60 MemSpy application in the target device between log + cycles, select the option Close MemSpy Symbian Agent Between + Cycles. Closing the agent between cycles makes it possible to get + full SWMT snapshot for each data fetch cycle (instead of getting only + delta information).

      +

      To include in the SWMT log cycle heap dumps for later analysis in + Heap Analyser, select the option Get Heap Dumps for Threads + to Analyse with Heap Analyser.

      + To use a thread heap filter, type the filter name (such as Akn) + in the Heap Data Thread Filter field. +

      +
    • +
    +

    If the connection to the target device fails, click Connection + Settings and configure connection settings.

    +
  6. +
  7. Click Finish. A MemSpy tab appears in the Carbide.c++ + Tabbed View Area with a file list populated. The received log files appear + in the file list.
  8. +
+ +
Related tasks
+ + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocConcepts.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocConcepts.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocGettingStarted.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocGettingStarted.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocReference.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocReference.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocTasks.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocTasks.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tool.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tool.htm Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,32 @@ + + + + + + Carbide.c++ User Guide + + + + + +

 

+ + + + + + + + +

+

 

+

 

+

 

+

Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+ License: http://www.eclipse.org/legal/epl-v10.html

+

MemSpy User Guide

+

Version 1.6.0; April, 2010

+ + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/toolTOC.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/toolTOC.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy.help/plugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/plugin.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/.classpath Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,7 @@ + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/.settings/org.eclipse.jdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,7 @@ +#Tue Jul 07 08:43:46 EEST 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/META-INF/MANIFEST.MF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Carbide.c++ Extensions - MemSpy +Bundle-SymbolicName: com.nokia.s60tools.memspy;singleton:=true +Bundle-Version: 1.6.0 +Bundle-Activator: com.nokia.s60tools.memspy.plugin.MemSpyPlugin +Bundle-Vendor: Nokia +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.nokia.s60tools.ui;bundle-version="1.5.0", + com.nokia.s60tools.sdk;bundle-version="1.2.1", + com.nokia.s60tools.heapanalyser;bundle-version="1.0.0", + com.nokia.s60tools.util;bundle-version="1.1.12", + com.nokia.s60tools.swmtanalyser;bundle-version="1.0.0", + org.eclipse.core.resources;bundle-version="3.4.1" +Bundle-ActivationPolicy: lazy +Export-Package: com.nokia.s60tools.memspy.export, + com.nokia.s60tools.memspy.interfaces;x-friends:="com.nokia.s60tools.memspy.tests", + com.nokia.s60tools.memspy.model;x-friends:="com.nokia.s60tools.memspy.tests" +Import-Package: org.eclipse.core.filesystem, + org.eclipse.ui.ide +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.html Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ + + + +About + + + +

About This Content

+ +

Dec 11, 2009

+ +

Copyright

+ +

+ +

Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: http://www.eclipse.org/legal/epl-v10.html.

+ +

+ + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/about.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.ini Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,45 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +# +# +# about.ini +# contains information about a feature +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# "%key" are externalized strings defined in about.properties +# This file does not need to be translated. + +# Property "aboutText" contains blurb for "About" dialog (translated) +# This text is shown in Feature Details -dialog when feature is selected. +aboutText=%productBlurb + +# Property "windowImage" contains path to window icon (16x16) +# needed for primary features only + +# Property "featureImage" contains path to feature image (32x32) +# Not using this in here because we do not want the icon to +# show on about dialog. Only using aboutText above. +#featureImage=icons/appdep.png + +# Property "aboutImage" contains path to product image (500x330 or 115x164) +# needed for primary features only + +# Property "appName" contains name of the application (translated) +# needed for primary features only + +# Property "welcomePerspective" contains the id of the perspective in which the +# welcome page is to be opened. +# optional diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/about.mappings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.mappings Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,25 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +# +# about.mappings +# contains fill-ins for about.properties +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# This file does not need to be translated. + +# The following should contain the build version. +# e.g. "0=20020612" +0=0 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/about.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,31 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +# about.properties +# contains externalized strings for about.ini +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# fill-ins are supplied by about.mappings +# This file should be translated. + +productBlurb=Carbide.c++ Extensions - MemSpy \n\ +\n\ +Version: 1.6\n\ +Build id: {0}\n\ +\n\ +\n\ +Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n\ +License: "http://www.eclipse.org/legal/epl-v10.html".\n\ +\n\ diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,13 @@ +javacSource=1.5 +javacTarget=1.5 +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + bin/,\ + icons/,\ + about.html,\ + about.ini,\ + about.mappings,\ + about.properties diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Analyse_Heap.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Analyse_Heap.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Compare_2_Heaps.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Compare_2_Heaps.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Export_To_html.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Export_To_html.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Heap_Dump_File.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Heap_Dump_File.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Launch_SWMT.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Launch_SWMT.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_16.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_16.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_45.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_45.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/icons/SWMT_Log_File.png Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/SWMT_Log_File.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/plugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/plugin.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,56 @@ + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/schema/traceprovider.exsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/schema/traceprovider.exsd Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,98 @@ + + + + + + + + + This extension point can be used to provide trace data for MemSpy. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Trace provider instance's class implementing ITraceProvider interface + + + + + + + + + + Name of the trace provider instance + + + + + + + + + + + + 1.6.0 + + + + + + + + + + + + Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. +This component and the accompanying materials are made available +under the terms of "Eclipse Public License v1.0" +which accompanies this distribution, and is available +at the URL "http://www.eclipse.org/legal/epl-v10.html". + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/Product.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/Product.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.common; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * Class for getting properties from product.properties file, located in same package. + */ +public class Product { + private static final String BUNDLE_NAME = "com.nokia.s60tools.memspy.common.product"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Product() { + } + /** + * @param key to product.properties -file + * @return a String from product.properties -file + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/ProductInfoRegistry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/ProductInfoRegistry.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.common; + +/** + * This class stores product information such as product name, + * version, console view name etc. + * The idea is to have the product information in one place. + */ +public class ProductInfoRegistry { + + + /** + * @return Returns the Console window name. + */ + public static String getConsoleWindowName() { + return getProductName() + " " + Product.getString("ProductInfoRegistry.Console_Window_Name_Postfix"); //$NON-NLS-1$ //$NON-NLS-2$ + } + /** + * @return Returns the Product name. + */ + public static String getProductName() { + return Product.getString("ProductInfoRegistry.Product_Name"); //$NON-NLS-1$ + } + + /** + * @return Returns the images directory. + */ + public static String getImagesDirectoryName() { + return Product.getString("ProductInfoRegistry.Images_Directory"); //$NON-NLS-1$ + } + + /** + * @return Returns the required MemSpy Launcher data version. + */ + public static int getRequiredMemSpyLauncherDataVersion() { + String versionStr = Product.getString("ProductInfoRegistry.Required_MemSpyLauncherS60DataVersion"); //$NON-NLS-1$ + int version = Integer.parseInt(versionStr); + return version; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/product.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/product.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# + +ProductInfoRegistry.Product_Name=MemSpy +ProductInfoRegistry.Console_Window_Name_Postfix=Console +ProductInfoRegistry.Images_Directory=icons +#For Required_MemSpyLauncherS60DataVersion use format 'n' e.g. =1 +ProductInfoRegistry.Required_MemSpyLauncherS60DataVersion=1 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/SWMTLogInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/SWMTLogInfo.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.containers; + +import java.util.Date; + +/** + * + * class SWMTLogInfo + * SWMTLogInfo class that contains info from one System Wide Memory Tracking log file or directory. + * + */ +public class SWMTLogInfo { + + /** + * Enum about what type the log is + */ + public enum SWMTLogType{ DEVICE, FILE }; + private SWMTLogType type; + + // Path of file + private String path; + + // Date when file has been imported. + private Date date; + + /** + * SWMTLogInfo. + * constructor. + */ + public SWMTLogInfo(){ + } + + + /** + * Get the log type + * @return type + */ + public SWMTLogType getType() { + return type; + } + /** + * Set the log type + * @param type + */ + public void setType(SWMTLogType type) { + this.type = type; + } + /** + * Get file path where log file is located + * @return path + */ + public String getPath() { + return path; + } + /** + * Set file path where log file is located + * @param path + */ + public void setPath(String path) { + this.path = path; + } + /** + * Get date when log file is created + * @return date + */ + public Date getDate() { + return date; + } + /** + * Set date when log file is created + * @param date + */ + public void setDate(Date date) { + this.date = date; + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/ThreadInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/ThreadInfo.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,191 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.containers; + +import java.util.Date; + + + + +/** + * threadInfo + * thread info from one thread + */ +public class ThreadInfo { + + /** + * Enum about what type the log is + */ + public enum HeapDumpType{ DEVICE, FILE }; + private HeapDumpType type; + + // Name of the thread + private String threadName; + + // ID-number of thread + private String threadID; + + // File path of file + private String threadFilePath; + + // Date when file has been imported. + private Date date; + + // Status when heap from thread has been imported, + // or "-" if it has not been imported. + private String status; + + + /** + * ThreadInfo + * constructor + */ + public ThreadInfo(){ + threadName = ""; + threadID = ""; + threadFilePath = ""; + date = new Date(); + status = "-"; + } + + /** + * Private constructor for clone method. Status is set as empty. + * @param threadName Name of the thread + * @param threadID ID-number of thread + * @param threadFilePath File path of file + * @param date Date when file has been imported. + * @param type Enum of which type info. + */ + private ThreadInfo(String threadName, String threadID, String threadFilePath, Date date, HeapDumpType type){ + this.threadName = threadName; + this.threadID = threadID; + this.threadFilePath = threadFilePath; + this.date = date; + this.type = type; + + this.status = "-"; + } + + /** + * Clone this object. + * @return New {@link ThreadInfo} object made from this ThreadInfo. Status is as default value. + */ + public ThreadInfo clone() { + ThreadInfo clone = new ThreadInfo(threadName, threadID, threadFilePath, date, type); + return clone; + } + + + /** + * Get thread name + * @return thread name + */ + public String getThreadName() { + return threadName; + } + + /** + * Set thread name + * @param threadName + */ + public void setThreadName(String threadName) { + this.threadName = threadName; + } + + /** + * Get thread id + * @return thread id + */ + public String getThreadID() { + return threadID; + } + + /** + * Set thread id + * @param threadID + */ + public void setThreadID(String threadID) { + this.threadID = threadID; + } + + /** + * Get date + * @return date + */ + public Date getDate() { + return date; + } + + /** + * Set date when log was created + * @param date + */ + public void setDate(Date date) { + this.date = date; + } + + /** + * Get absolute file path where log file is located + * @return file path + */ + public String getThreadFilePath() { + return threadFilePath; + } + + /** + * Set absolute file path where log file is located + * @param threadFilePath + */ + public void setThreadFilePath(String threadFilePath) { + this.threadFilePath = threadFilePath; + } + + /** + * Get the type of this log + * @return type + */ + public HeapDumpType getType() { + return type; + } + + /** + * Set the type of this log + * @param type + */ + public void setType(HeapDumpType type) { + this.type = type; + } + + /** + * Get status + * @return status + */ + public String getStatus() { + return status; + } + + /** + * Set status + * @param status + */ + public void setStatus(String status) { + this.status = status; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceClientNotificationsIf.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceClientNotificationsIf.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.export; + +/** + * Callback interface reporting trace related error information from trace source side. + */ +public interface ITraceClientNotificationsIf { + + /** + * Notifies informative message from trace source. + * @param message message + */ + public void notifyInformation(String message); + + /** + * Notifies warning from trace source. + * @param message message + */ + public void notifyWarning(String message); + + /** + * Notifies error from trace source. + * @param message message + */ + public void notifyError(String message); +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceDataProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceDataProcessor.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.export; + +/** + * Data processor interfacing for handling trace output data from device. + */ +public interface ITraceDataProcessor { + + /** + * Handles a single trace data line. + * @param traceDataLine trade data line + */ + public void processDataLine(String traceDataLine); +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.export; + +/** + * Interface for binding external trace data providers for MemSpy. + * Only a single trace data provider instance at a time is supported. + * In case more that a single trace data providers are available + * the selection among them is undeterministic. + */ +public interface ITraceProvider { + + /** + * Connects to trace source. + * @param traceClient Client to send information about changes in connectivity status and errors etc. + * @return true on success, otherwise false + */ + public boolean connectTraceSource(ITraceClientNotificationsIf traceClient); + + /** + * Disconnects to trace source. + */ + public void disconnectTraceSource(); + + /** + * Sends current usage context-specific integer data to launcher. + * Integer data can contain values that can be expressed with 10 bytes + * i.e. only 10 lower bytes are taken into account when setting data. + * @param integerData integer data to be sent + * @return false if failed to send integer data, otherwise true + */ + public boolean sendIntData(int integerData); + + /** + * Sends current usage context-specific string message to launcher. + * @param stringData string data to send + * @return true on success, otherwise false + */ + boolean sendStringData( String stringData); + + /** + * Activates trace with given group ID. + * @param traceGroupID trace group ID + * @return true on success, otherwise false + */ + boolean activateTrace(String traceGroupID); + + /** + * Starts trace data listening + * @param dataProcessor data processor that further handles trace data at MemSpy side. + * @return true in case data processor is registered properly, otherwise false + */ + public boolean startListenTraceData(ITraceDataProcessor dataProcessor); + + /** + * Stops trace data listening + */ + public void stopListenTraceData(); + + /** + * Gets preference page ID for the user trace source. + * @return preference page ID for the user trace source + */ + public String getTraceSourcePreferencePageId(); + + /** + * Gets current connections display name. + * @return current connections display name + */ + public String getDisplayNameForCurrentConnection(); + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/HeapDumpFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/HeapDumpFile.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.files; + +/** + * class HeapDumpFile. + * This class represents one Heap Dump. + */ + +public class HeapDumpFile extends MemSpyFile { + + /* path of XML-file*/ + private String xmlPath; + + /** + * HeapDumpFile. + * constructor + * @param filePath files path + * @param xmlPath xml files path + */ + public HeapDumpFile( String filePath, String xmlPath ) { + super(filePath); + this.xmlPath = xmlPath; + } + + /** + * Read's file variables from file that is defined in filePath + * @param folder folder where files are searched + * @return New HeapDumpFile + */ + static public HeapDumpFile read( String folder ){ + + String xmlPath = findFile(folder, "xml"); + String heapPath = findFile(folder, "txt"); + + if ( xmlPath == null || heapPath == null ){ + return null; + } + HeapDumpFile heapFile = new HeapDumpFile( heapPath, xmlPath ); + heapFile.doRead(); + heapFile.setFileType("Heap Dump"); + return heapFile; + } + + /** + * Get XML file path + * @return path of xml-file + */ + public String getXmlPath() { + return xmlPath; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/MemSpyFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/MemSpyFile.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.files; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import org.xml.sax.helpers.DefaultHandler; + +import com.nokia.s60tools.memspy.model.MemSpyFileOperations; + +/** + * This is a base class for all MemSpy file types. + * + */ +public class MemSpyFile extends DefaultHandler{ + + /* files path */ + protected String filePath = ""; + + /* files name */ + protected String fileName = ""; + + /* time code from file */ + protected String time = ""; + + /* date time code from file */ + private Date dateTime = null; + + /* type of the file */ + protected String fileType = ""; + + /** + * MemSpyFile. + * constructor + * @param filePath Path of file + */ + public MemSpyFile( String filePath ){ + this.filePath = filePath; + } + + /** + * doRead. + * Read's file variables from file that is defined in filePath + */ + public void doRead(){ + File f = new File(filePath); + + //if file exists + if (f.exists() && f.isFile()) { + + //Get date + Date date = new Date(f.lastModified()); + setDateTime(date); + SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT ); + time = formatter.format(date); + + // get File name + fileName = f.getName(); + } else { + fileName = ""; + } + } + + /** + * findFiles. + * Finds all files with defined extension. + * @param folder folder where from files are searched + * @param extension file extension + * @return arraylist that contains found file names + */ + protected static ArrayList findFiles(String folder, String extension) { + + ArrayList retVal = new ArrayList(); + if ( !extension.startsWith(".") ){ + extension = "." + extension; + } + File cFolder = new File(folder); + if (cFolder.isDirectory() && cFolder.exists()) { + File[] files = cFolder.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.getName().endsWith(extension)) { + retVal.add( file.getAbsolutePath() ); + } + } + } + } + + return retVal; + } + + /** + * findFile + * Finds file with defined extension. + * @param folder folder where file is searched + * @param extension file extension + * @return fileName + */ + protected static String findFile(String folder, String extension) { + if ( !extension.startsWith(".") ){ + extension = "." + extension; + } + File cFolder = new File(folder); + if (cFolder.isDirectory() && cFolder.exists()) { + File[] files = cFolder.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.getName().endsWith(extension)) { + return file.getAbsolutePath(); + } + } + } + } + + return null; + } + + + + /** + * Get file name + * @return file name + */ + public String getFileName() { + return fileName; + } + /** + * Set file name + * @param fileName + */ + public void setFileName(String fileName) { + this.fileName = fileName; + } + /** + * Get time when log file was created + * @return time + */ + public String getTime() { + return time; + } + /** + * Set time when log file was created + * @param time + */ + public void setTime(String time) { + this.time = time; + } + /** + * Get type of log file + * @return type + */ + public String getFileType() { + return fileType; + } + /** + * Set type of log file + * @param fileType + */ + public void setFileType(String fileType) { + this.fileType = fileType; + } + + /** + * Get absolute file path + * @return file path + */ + public String getFilePath() { + return filePath; + } + + /** + * Set date time + * @param dateTime the dateTime to set + */ + private void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + + /** + * Get date time read from file + * @return the dateTime + */ + public Date getDateTime() { + return dateTime; + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/SWMTFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/SWMTFile.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.files; + +import java.util.ArrayList; + +/** + * class SWMTFile. + * This class represents one System Wide Memory Tracking log. + */ + +public class SWMTFile extends MemSpyFile { + + + + /** + * SWMTFile. + * Constructor + * @param filePath path of file + */ + private SWMTFile(String filePath) { + super(filePath); + } + + /** + * read. + * Reads searches swmt-file from given folder + * @param folder + * @return new SWMTFile + */ + static public SWMTFile read( String folder ){ + + ArrayList filePaths = findFiles(folder, "txt"); + String xmlFile = findFile(folder, "xml"); + + + if ( filePaths.size() == 0 || xmlFile != null ){ + return null; + } + SWMTFile swmtFile = new SWMTFile( filePaths.get(0) ); + swmtFile.doRead(); + swmtFile.setFileType("SWMT-Log"); + return swmtFile; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IAnalyseHeapJobListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IAnalyseHeapJobListener.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.interfaces; + + +/** + * IAnalyseHeapJobListener. + * interface for Heap Analyser launcher listener. + */ +public interface IAnalyseHeapJobListener { + + /** + * heapAnalyserFinished. + * Methot that is called when Heap Aanalyser finishes + * @param returnValue return value of Heap Analyser + */ + public void heapAnalyserFinished(final int returnValue); + + /** + * heapAnalyserFinished. + * Methot that is called when Heap Aanalyser finishes + * @param returnValue return value of Heap Analyser + * @param outputFilePath file path of output file + */ + public void heapAnalyserFinished(final int returnValue, String outputFilePath); + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IMemSpyTraceListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IMemSpyTraceListener.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.interfaces; + +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; + + +/** + * interface MemSpyTraceListener + * MemSpy trace listener interface that all MemSpy Trace listeners implement + * + */ + +public interface IMemSpyTraceListener { + + /** + * MemSpy Launchers actions. + */ + public enum LauncherAction{ + START_MEMSPY_THREAD_LIST, + GET_THREAD_LIST, + GET_HEAP_DUMP, + SWMT_UPDATE, + TIMED_SWMT_UPDATE + }; + + /** + * Launch error types. + */ + public enum LauncherErrorType{ + + // The order of 4 first launcher error enumerators should not be changed because the error codes + // sent from launcher side must match enumerator ordinals. + + GENERAL_LAUNCHER_ERROR, // This is general launcher error when there is no error code, only error description. + MEMSPY_NOT_RUNNING, // error code/ordinal=1, MemSpy is not running on device as should have been at the state of execution + MEMSPY_NOT_FOUND, // error code/ordinal=2, MemSpywas not installed on device + HEAP_NOT_FOUND, // error code/ordinal=3, Requested heap was not found from device + + // Ordinals of other errors are not used as error codes at launcher side, + // and therefore they can be freely re-organized if needed. + + HEAP_TYPE_WRONG, // + NO_ANSWER_FROM_DEVICE, // + DUMPED_TRACES, // + ACTIVATION, // Activation of MemSpy functionality via MemSpyLauncher has failed + FILE, // + CATEGORIES_NOT_SUPPORTED, // MemSpy installed on the device does not support setting of custom categories + TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION // MemSpyLauncher installed supports only older data version + }; + + public final static String ERROR_HEAP_TYPE = "Selected heap's heap type is wrong(needs to be Symbian OS RHeap)."; + public final static String ERROR_NO_RESPONSE = "MemSpy extension was unable to receive response from MemSpy S60-application."; + public final static String ERROR_POSSIBLE_REASONS = "Following reason(s) might be causing this problem: "; + public final static String ERROR_MEMSPY = "MemSpy Error"; + public final static String ERROR_USB_TRACE_ENABLED = "\n- Trace data sending is not activated from your TraceSwitch application."; + public final static String ERROR_INSTALL_MEMSPY_LAUNCHER = "\n- MemSpy Launcher application is not installed in your device, or the installed launcher version is not up-to-date.\n\n(Installing MemSpy Launcher requires that Nokia PC suite is found from this computer and device is connected with usb-cable.) "; + public final static String ERROR_CONNECTION_BROKEN = "\n- Network connection between workstation and Musti box does not work properly."; + public final static String ERROR_MEMSPY_NOT_RUNNING = "MemSpy is not running on device. MemSpy will be restarted when you perform next operation. "; + public final static String ERROR_MEMSPY_NOT_FOUND = "MemSpy s60-application was not found from your device."; + public final static String ERROR_HEAP_NOT_FOUND = "Requested heap not found from device.( Perhaps thread has been terminated after loading of thread list, try reloading thread list. )"; + public final static String ERROR_DUMPED_TRACES = "Received Heap Dump/SWMT-log is corrupted. See help for more information."; + public final static String ERROR_SWMT_NEEDS_RESET = "\n\nSince last imported log was missed, logs cannot be imported anymore before removing all logs."; + public final static String ERROR_ACTIVATION_NOT_SUCCESFUL = "Unable to send activation messages to TraceCore. Check connection settings."; + public final static String ERROR_FILE_OPERATIONS_NOT_SUCCESSFUL= "MemSpy was unable to write data to hard drive. Please make sure that MemSpy has sufficient user rights to Carbide's workspace."; + public final static String ERROR_CONNECTION = "Cannot connect to trace. Check connection settings."; + public final static String ERROR_CATEGORIES_NOT_SUPPORTED = "SWMT category setting feature is not supported by the MemSpy installed on the device and will be disabled for the rest of the session. Re-run the operation without category support."; + public final static String ERROR_TOO_OLD_MEMSPY_LAUNCHER_VERSION = "Installed launcher version is not up-to-date.\n\n(Installing MemSpy Launcher requires that Nokia PC suite is found from this computer and device is connected with usb-cable."; + public static final String ERROR_GENERAL_LAUNCHER_ERROR = "An unexpected error occurred in launcher component. See console log for detailed error information."; + public final static String ERROR_SEE_CONSOLE_LOG = "\n\nSee console log for additional error information."; + public final static String ERROR_LAUNCHER_ERROR_DETAILS = "S60 MemSpy Launcher error details: "; + + /** + * deviceError. + * method that is called whenever errors occur. + * @param error error code + */ + public void deviceError( LauncherErrorType error ); + + /** + * operationFinished. + * @param action which action was finished + */ + public void operationFinished( LauncherAction action ); + + /** + * operationFinished. + * @param action which action was finished + * @param swmtLog that was received + */ + public void operationFinished( LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning ); + + /** + * startedReceivingSWMTLog. + * notification that is sent to interface when swmtReceiving is started. + */ + public void startedReceivingSWMTLog(); +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/INewMemSpyFilesObserver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/INewMemSpyFilesObserver.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.interfaces; + +/** + * interface INewMemSpyFilesObserver. + * interface for MemSpy file observer. + * + */ + +public interface INewMemSpyFilesObserver { + + /** + * memSpyFilesUpdated. + * Method that is called when MemSPy file scan is complete. + */ + public void memSpyFilesUpdated(); + + /** + * setOutputFilePath. + * sets output file's path + * @param outputFilePath new outputFilePath + */ + public void setOutputFilePath(String outputFilePath); + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyseHeapJob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyseHeapJob.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + + + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +import com.nokia.s60tools.heapanalyser.interfaces.HeapAnalyserLauncher; +import com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener; + + +/** + * This class is responsible for launching Heap Analyser and waiting for it to stop. + * If Heap Analyser returns with and error code, error code is passed to job listener + */ +public class AnalyseHeapJob extends Job { + + + /* path of the configuration file */ + private String configurationFile; + + /* path of output file */ + private String analyseOutputFile; + + /* Job listener(MemSpy main view */ + private IAnalyseHeapJobListener listener; + + /** + * Constructor + * @param name Name of the process + * @param listener listener that is notified if errors occur. + */ + public AnalyseHeapJob(String name, IAnalyseHeapJobListener listener ) { + super(name); + this.listener = listener; + analyseOutputFile = null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor arg0) { + + // launch heap analyser and wait for it to stop + int retVal = HeapAnalyserLauncher.launchHeapAnalyser( configurationFile ); + + // if output file was generated return it as attchment to main view. + if( analyseOutputFile != null ){ + listener.heapAnalyserFinished( retVal, analyseOutputFile ); + } + else{ + listener.heapAnalyserFinished( retVal ); + } + + return Status.OK_STATUS; + } + + /** + * Launches Heap Analyser. + */ + public void refresh() { + try { + setPriority(Job.LONG); + setUser(false); + schedule(100); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + } + } + + + /** + * setter for configurationFiles path + * @param configurationFile + */ + public void setConfigurationFile(String configurationFile) { + this.configurationFile = configurationFile; + } + + /** + * setAnalyseOutputFile. + * @param analyseOutputFile file path of analyse file output. + */ + public void setAnalyseOutputFile(String analyseOutputFile) { + this.analyseOutputFile = analyseOutputFile; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLGenerator.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,574 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.BufferedWriter; +import java.io.IOException; + +/** + * AnalyserXMLGenerator. + * XML file generator that writes configuration XML-files for Heap Analyser and + * Crash Analyser based on parameters it has received. + * + * AnalyserXMLGenerator can be used for example like this: + *
+ * AnalyserXMLGenerator generator = new AnalyserXMLGenerator(XMLGeneratorAction.ANALYSE_HEAP, "c:\\temp\\source.txt", "c:\\directory\\", null, null, "thread", "c:\\temp\\output.xls", null, null);
+ * File filename = new File("c:\\temp\\testxml.xml");
+ * BufferedWriter writer = null;
+ * 	try {
+ * 		writer = new BufferedWriter(new FileWriter(filename)); 
+ * 		generator.GenerateXML(writer);
+ * 	} catch (IOException e) {
+ * 		e.printStackTrace();
+ * 	} 
+ * 	finally {
+ *  	try {
+ *   		if (writer != null) {
+ *   			writer.flush();
+ *   			writer.close();
+ *   		}
+ *  	} 
+ *  	catch (IOException ex) {
+ *  		ex.printStackTrace();
+ *  		return false;
+ *  	}
+ *  }
+ *  
+ */ + +public class AnalyserXMLGenerator { + + /** + * Enumeration for Heap Analyser actions + */ + public enum XMLGeneratorAction { + ANALYSE_HEAP, COMPARE_HEAPS, ANALYSE_CRASH_SUMMARY, ANALYSE_CRASH_FULL + } + + private XMLGeneratorAction XMLAction; + private String[] XMLSourceFile; + private String XMLSourceDirectory; + private String[] XMLDebugMetaDataFile = null; + private String XMLDebugMetaDataDirectory; + private String XMLThreadName; + private String XMLExtension; + private String XMLAnalyseFileOutput; + private String XMLAnalyseDirectoryOutput; + + + //Commands for XML + + private final static String COMMAND_VIEWER = "Viewer"; + private final static String COMMAND_COMPARE_HEAPS = "CompareTwoHeaps"; + private final static String COMMAND_SUMMARY = "Summary"; + private final static String COMMAND_FULL_ANALYSIS = "Full"; + + // XML-tags + + private final static String CRASH_ANALYSER_START = ""; + private final static String CRASH_ANALYSER_END = ""; + + private final static String HEAP_ANALYSER_START = ""; + private final static String HEAP_ANALYSER_END = ""; + + private final static String SOURCE_START = " "; + private final static String SOURCE_END = " "; + + private final static String DEBUG_META_DATA_START = " "; + private final static String DEBUG_META_DATA_END = " "; + + private final static String FILE_START = " "; + + private final static String DIRECTORY_START = " "; + + private final static String PARAMETERS_START = " "; + private final static String PARAMETERS_END = " "; + + private final static String THREAD_START = " "; + private final static String THREAD_END = ""; + + private final static String COMMAND_START = " "; + private final static String COMMAND_END = ""; + + private final static String OUTPUT_START = " "; + private final static String OUTPUT_END = " "; + + private final static String EXTENSION_START = " "; + + + + /** + * XMLGenerator() + * Constructor + */ + public AnalyserXMLGenerator() { + + XMLAction = null; + XMLSourceFile = null; + XMLSourceDirectory = null; + XMLDebugMetaDataFile = null; + XMLDebugMetaDataDirectory = null; + XMLThreadName = null; + XMLAnalyseFileOutput = null; + XMLExtension = null; + + } + + /** + * AnalyserXMLGenerator() + * Constructor for XMLGenerator + * + * @param action + * @param sourceFile file that is added into -section under -tag + * @param sourceDirectory directory that is added into -section under -tag + * @param debugMetaDataFile file that is added into -section under -tag + * @param debugMetaDataDirectory directory that is added into -section under -tag + * @param threadName thread name that is added into -section under -tag + * @param extension extension text that is is added into -section under -tag + * @param analyseFileOutput file name that is added into -section under -tag + * @param analyseDirectoryOutput file name that is added into -section under -tag + */ + + public AnalyserXMLGenerator( XMLGeneratorAction action, + String[] sourceFile, + String sourceDirectory, + String[] debugMetaDataFile, + String debugMetaDataDirectory, + String threadName, + String analyseFileOutput, + String analyseDirectoryOutput, + String extension ) { + + XMLAction = action; + XMLSourceFile = sourceFile; + XMLSourceDirectory = sourceDirectory; + XMLDebugMetaDataFile = debugMetaDataFile; + XMLDebugMetaDataDirectory = debugMetaDataDirectory; + XMLThreadName = threadName; + XMLAnalyseFileOutput = analyseFileOutput; + XMLAnalyseDirectoryOutput = analyseDirectoryOutput; + XMLExtension = extension; + } + + /** + * GenerateXML() + * Writes XML file. + * @param writer BufferedWriter stream where XML is written. + * @throws IOException if something goes when writing to stream + */ + + public void GenerateXML( BufferedWriter writer ) throws IOException{ + + + if( XMLAction != null ) { + // Begin XML + switch( XMLAction ){ + case ANALYSE_CRASH_FULL: + case ANALYSE_CRASH_SUMMARY: + writer.write(CRASH_ANALYSER_START); + break; + case ANALYSE_HEAP: + case COMPARE_HEAPS: + writer.write(HEAP_ANALYSER_START); + break; + default: + break; + } + + writer.newLine(); + writer.newLine(); + } + // Write Sources + this.writeSource(writer); + + + // Write debug meta data + this.writeDebugMetaData(writer); + + // Write parameters + this.writeParameters(writer); + + // Write output location + this.writeOutput(writer); + + // End XML + if( XMLAction != null ) { + switch(XMLAction){ + case ANALYSE_CRASH_SUMMARY: + case ANALYSE_CRASH_FULL: + writer.write(CRASH_ANALYSER_END); + break; + case ANALYSE_HEAP: + case COMPARE_HEAPS: + writer.write(HEAP_ANALYSER_END); + break; + default: + break; + } + writer.newLine(); + } + + + } + + /** + * writeSource() + * Writes source - parameters + * @param writer BufferedWriter stream where XML is written. + */ + private void writeSource( BufferedWriter writer ) throws IOException{ + + + // Start Source definition + writer.write(SOURCE_START); + writer.newLine(); + + if( XMLSourceFile != null ){ + // File Definition + for(int i = 0; i < XMLSourceFile.length; i++ ){ + writer.write( FILE_START ); + writer.write( XMLSourceFile[i] ); + writer.write( FILE_END ); + writer.newLine(); + } + } + if( XMLSourceDirectory != null ) { + writer.write( DIRECTORY_START ); + writer.write( XMLSourceDirectory ); + writer.write( DIRECTORY_END ); + writer.newLine(); + } + + // End Source definition + writer.write(SOURCE_END); + writer.newLine(); + writer.newLine(); + } + + /** + * writeDebugMetaData() + * Writes debug_meta_data - parameters + * @param writer BufferedWriter stream where XML is written. + * @throws IOException + */ + private void writeDebugMetaData( BufferedWriter writer ) throws IOException{ + // Start Debug meta data definition + + if( XMLDebugMetaDataFile != null || + XMLDebugMetaDataDirectory != null ){ + + writer.write(DEBUG_META_DATA_START); + writer.newLine(); + + // File Definition + if( XMLDebugMetaDataFile != null ){ + for(int i = 0; i < XMLDebugMetaDataFile.length; i++ ){ + writer.write( FILE_START ); + writer.write( XMLDebugMetaDataFile[i] ); + writer.write( FILE_END ); + writer.newLine(); + } + } + if( XMLDebugMetaDataDirectory != null ) { + writer.write( DIRECTORY_START ); + writer.write( XMLDebugMetaDataDirectory ); + writer.write( DIRECTORY_END ); + writer.newLine(); + } + + // End Debug meta data definition + writer.write(DEBUG_META_DATA_END); + writer.newLine(); + writer.newLine(); + } + } + + + + /** + * writeParameters( + * Writes parameters - parameters + * @param writer BufferedWriter stream where XML is written. + * @throws IOException + */ + + private void writeParameters( BufferedWriter writer ) throws IOException { + + if( XMLThreadName != null || XMLAction != null || XMLExtension != null){ + + + // Start parameter definition + writer.write(PARAMETERS_START); + writer.newLine(); + + + if( XMLThreadName != null ){ + // Add thread info + writer.write( THREAD_START ); + writer.write( XMLThreadName ); + writer.write( THREAD_END ); + writer.newLine(); + + } + + if( XMLAction != null ){ + // Command + + writer.write(COMMAND_START); + + // Begin XML + switch(XMLAction){ + case ANALYSE_CRASH_SUMMARY: + writer.write(COMMAND_SUMMARY); + break; + case ANALYSE_CRASH_FULL: + writer.write(COMMAND_FULL_ANALYSIS); + break; + case ANALYSE_HEAP: + writer.write(COMMAND_VIEWER); + break; + case COMPARE_HEAPS: + writer.write(COMMAND_COMPARE_HEAPS); + break; + default: + break; + } + writer.write(COMMAND_END); + writer.newLine(); + } + + if( XMLExtension != null ){ + // extension + writer.write( EXTENSION_START ); + writer.write( XMLExtension ); + writer.write( EXTENSION_END ); + writer.newLine(); + } + + + + // End parameter definition + writer.write(PARAMETERS_END); + writer.newLine(); + writer.newLine(); + } + + + } + + + /** + * Writes output - parameters + * @param writer BufferedWriter stream where XML is written. + * @throws IOException + */ + private void writeOutput( BufferedWriter writer ) throws IOException{ + + if( XMLAnalyseFileOutput != null || XMLAnalyseDirectoryOutput != null ){ + writer.write(OUTPUT_START); + writer.newLine(); + + // Output file + if( XMLAnalyseFileOutput != null ){ + writer.write(FILE_START); + writer.write(XMLAnalyseFileOutput); + writer.write(FILE_END); + writer.newLine(); + } + // Output directory + if( XMLAnalyseDirectoryOutput != null ) { + writer.write(DIRECTORY_START); + writer.write(XMLAnalyseDirectoryOutput); + writer.write(DIRECTORY_END); + writer.newLine(); + } + + writer.write(OUTPUT_END); + writer.newLine(); + writer.newLine(); + + + } + } + + + + + + /** + * Get file name parameters + * @return XMLSourceFile + */ + public String[] getXMLSourceFile() { + return XMLSourceFile; + } + + /** + * Set file name parameters + * @param sourceFile the XMLSourceFile to set + */ + public void setXMLSourceFile(String[] sourceFile) { + XMLSourceFile = sourceFile; + } + + /** + * Get symbol or map files + * @return XMLDebugMetaDataFile + */ + public String[] getXMLDebugMetaDataFile() { + return XMLDebugMetaDataFile; + } + + /** + * Set symbol or map files + * @param XMLDebugMetaDataFile to set + */ + public void setXMLDebugMetaDataFile(String[] debugMetaDataFile) { + XMLDebugMetaDataFile = debugMetaDataFile; + } + + /** + * Check if XMLDebugMetaDataFile has been set + * @return XMLDebugMetaDataFile + */ + public boolean hasXMLDebugMetaDataFile() { + boolean isXMLSet = XMLDebugMetaDataFile!=null; + if(isXMLSet){ + isXMLSet = XMLDebugMetaDataFile.length > 0; + } + return isXMLSet; + } + + /** + * Get thread parameter + * @return XMLThreadName + */ + public String getXMLThreadName() { + return XMLThreadName; + } + + /** + * Set thread parameter + * @param XMLThreadName to set + */ + public void setXMLThreadName(String threadName) { + XMLThreadName = threadName; + } + + /** + * Get analyse output file + * @return XMLAnalyseFileOutput + */ + public String getXMLAnalyseFileOutput() { + return XMLAnalyseFileOutput; + } + + /** + * Set analyse output file + * @param XMLAnalyseFileOutput to set + */ + public void setXMLAnalyseFileOutput(String analysefileOutput) { + XMLAnalyseFileOutput = analysefileOutput; + } + + /** + * Get current action + * @return XMLAction + */ + public XMLGeneratorAction getXMLAction() { + return XMLAction; + } + + /** + * Set action + * @param action the XMLGeneratorAction to set + */ + public void setXMLAction(XMLGeneratorAction action) { + XMLAction = action; + } + + /** + * Get directory parameter + * @return XMLSourceDirectory + */ + public String getXMLSourceDirectory() { + return XMLSourceDirectory; + } + + /** + * Set directory parameter + * @param XMLSourceDirectory to set + */ + public void setXMLSourceDirectory(String sourceDirectory) { + XMLSourceDirectory = sourceDirectory; + } + + /** + * Get debug metadata directory. In UI it's shown as Map file folder. + * @return XMLDebugMetaDataDirectory + */ + public String getXMLDebugMetaDataDirectory() { + return XMLDebugMetaDataDirectory; + } + + /** + * Set debug metadata directory. In UI it's shown as Map file folder. + * @param XMLDebugMetaDataDirectory to set + */ + public void setXMLDebugMetaDataDirectory(String debugMetaDataDirectory) { + XMLDebugMetaDataDirectory = debugMetaDataDirectory; + } + + /** + * Get extension parameter + * @return XMLExtension + */ + public String getXMLExtension() { + return XMLExtension; + } + + /** + * Set extension parameter + * @param extension the XMLExtension to set + */ + public void setXMLExtension(String extension) { + XMLExtension = extension; + } + + /** + * Get output directory + * @return XMLAnalyseDirectoryOutput + */ + public String getXMLAnalyseDirectoryOutput() { + return XMLAnalyseDirectoryOutput; + } + + /** + * Set output directory + * @param analyseDirectoryOutput the XMLAnalyseDirectoryOutput to set + */ + public void setXMLAnalyseDirectoryOutput(String analyseDirectoryOutput) { + XMLAnalyseDirectoryOutput = analyseDirectoryOutput; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLParser.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.BufferedReader; +import java.util.ArrayList; + + +/** + * class AnalyserXMLParser. + * class that parses symbol and thread name information from debug configuration file. + * + */ + +public class AnalyserXMLParser { + + static final String DEBUG_META_DATA_START_TAG = ""; + static final String DEBUG_META_DATA_END_TAG = ""; + static final String THREAD_TAG = ""; + static final String FILE_NAME = "file name"; + static final String DIRECTORY_NAME = "directory name"; + + + /** + * Add wanted lines from given input to XML generator and returns the generator. + * @param reader + * @return XML generator + */ + public static AnalyserXMLGenerator parseXML( BufferedReader reader ){ + AnalyserXMLGenerator retVal = new AnalyserXMLGenerator(); + + boolean readingDebugMetaData = false; + ArrayList debugMetaDataFiles = new ArrayList(); + String debugMetaDataDirectory = null; + String threadName = ""; + + try{ + String line = ""; + + // Go thru file in loop and search for lines that contain debugMetaData -text. + // If text is found, save meta data file information into AnalyserXMLGenerator-object. + + while( reader.ready() ){ + + line = reader.readLine(); + + if( line == null){ + break; + } + + // Search for debug meta data start and end tags. + if( line.contains(DEBUG_META_DATA_START_TAG) ){ + readingDebugMetaData = true; + } + else if( line.contains(DEBUG_META_DATA_END_TAG) ){ + readingDebugMetaData = false; + } + + // if between debug meta data start and end tags, search for debug meta data info. + if( readingDebugMetaData ){ + if(line.contains(FILE_NAME)){ + debugMetaDataFiles.add( getMetaDataInfo(line) ); + } + if(line.contains(DIRECTORY_NAME)){ + debugMetaDataDirectory = getMetaDataInfo(line); + } + } + + // search for thread name tag. + if( line.contains(THREAD_TAG) ){ + threadName = getThreadName(line); + } + } + + } + catch (Exception e){ + e.printStackTrace(); + return null; + } + + if(threadName.equals("") ){ + return null; + } + + // check that thread name and at least one symbol file was found. + if( debugMetaDataFiles.size() != 0 ){ + // set found data into AnalyserXMLGenerator-object. + retVal.setXMLDebugMetaDataFile(debugMetaDataFiles.toArray(new String [debugMetaDataFiles.size()])); + } + + if( !threadName.equals("")){ + retVal.setXMLDebugMetaDataDirectory(debugMetaDataDirectory); + } + retVal.setXMLThreadName(threadName); + + return retVal; + + } + + /** + * getMetaDataInfo. + * @param line String that is parsed + * @return string between quotation marks + */ + private static String getMetaDataInfo( String line ) { + int firstIndex = line.indexOf("\"") + 1 ; + int secondIndex = line.indexOf(("\""), firstIndex ); + return line.substring(firstIndex, secondIndex); + } + + + /** + * getThreadName. + * @param line String that is parsed + * @return string between threas tags + */ + private static String getThreadName(String line){ + int firstIndex = line.indexOf("=\"thread\">") + 10; + int secondIndex = line.indexOf(""); + return line.substring(firstIndex, secondIndex); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/CategoryProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/CategoryProfile.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.model; + +import java.util.Iterator; +import java.util.List; + +import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoryEntry; + +/** + * Class for one Category Profile + */ +public class CategoryProfile { + + private String name; + + private int categories = 0; + + /** + * Create a new Category Profile + * @param name Profile name + */ + public CategoryProfile(String name) { + this.setName(name); + } + + /** + * + * @param name Profile name + * @param categories Categories for profile + */ + public CategoryProfile(String name, int categories) { + this.categories = categories; + this.setName(name); + } + + /** + * Get profile name + * @return the name + */ + public String getName() { + return name; + } + + /** + * Set profile name + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * Add one or more category to categories + * @param categories the categories to set + */ + public void addCategory(int category) { + categories = categories & category; + } + + /** + * Get categories + * @return the categories + */ + public int getCategories() { + return categories; + } + + /** + * Get all SWMT categories for this profile + * @return the categories + */ + public List getCategoryEntrys() { + + SWMTCategorys cat = SWMTCategorys.getInstance(); + List categoryEntries = cat.getCategoryEntries(getCategories()); + + return categoryEntries; + } + + /** + * Get names of the Categories added to this profile. + * @return list of Category names + */ + public String [] getCategoryEntryNames(){ + List categoryEntrys = getCategoryEntrys(); + if(categoryEntrys.isEmpty()){ + return new String[0]; + } + String[] names = new String[categoryEntrys.size()]; + int i = 0; + for (Iterator iterator = categoryEntrys.iterator(); iterator.hasNext();) { + SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator + .next(); + names[i] = entry.getCategoryName(); + i++; + } + return names; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/ImportEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/ImportEngine.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,391 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; + +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType; +import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator.XMLGeneratorAction; +import com.nokia.s60tools.memspy.ui.views.MemSpyMainView; + +/** + * Class that is used when importing MemSpy data. + * ImportEngine takes care of copying files into predefined file structure that Main View is able to read. + */ +public class ImportEngine { + + /* MemSpy's Main View */ + private MemSpyMainView view; + + /** + * Import Engine constructor. + * @param view MemSpy's main view + */ + public ImportEngine( MemSpyMainView view ){ + this.view = view; + } + + /** + * Imports Heap Dump file(s) and starts heap analyser if only one file was imported. Method also shows + * error message if some of operations was not successful. + * @param importedHeaps list of imported files + * @param symbols symbol information that is used. + * @return true, if importing was successful. + */ + public boolean importAndAnalyseHeap( ArrayList importedHeaps, AnalyserXMLGenerator xmlGenerator, boolean startHeapAnalyser ){ + return importAndAnalyseHeap( importedHeaps, xmlGenerator, startHeapAnalyser, true); + } + + /** + * Imports Heap Dump file(s) and starts heap analyser if only one file was imported. Method also shows + * error message if some of operations was not successful. + * @param importedHeaps list of imported files + * @param symbols symbol information that is used. + * @param deleteTempFiles if temp files and folder should be deleted after import + * @return true, if importing was successful. + */ + public boolean importAndAnalyseHeap( ArrayList importedHeaps, AnalyserXMLGenerator xmlGenerator, boolean startHeapAnalyser, boolean deleteTempFiles ){ + + boolean importFailed = false; + + // Set xmlGenerators action type correct. + xmlGenerator.setXMLAction( XMLGeneratorAction.ANALYSE_HEAP ); + String fileName = ""; + for ( ThreadInfo threadInfo : importedHeaps ){ + fileName = this.moveHeapToImportedFolder( threadInfo ); + if( fileName != null ){ + // save new filepath into threadInfo-variable. + threadInfo.setThreadFilePath( fileName ); + + if( !generateViewConfigurationFile( fileName, threadInfo.getThreadName(), xmlGenerator) ){ + importFailed = true; + } + + } + else{ + importFailed = true; + } + } + + // if importing was failed, show error message. + if( importFailed ){ + view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_HEAP_IMPORT_FAILED ); + return false; + } + + // Start heap analyser if only one heap was imported. + if( importedHeaps.size() == 1 && startHeapAnalyser ){ + + // get configuration files path + String analyserFileOutput = importedHeaps.get(0).getThreadFilePath().substring( 0, fileName.lastIndexOf("\\") + 1); + analyserFileOutput = analyserFileOutput + "configuration.xml"; + + // launch Heap Analyser + view.launchHeapAnalyser( analyserFileOutput, null, xmlGenerator.getXMLThreadName(), true ); + + } + + + // Refresh main view so that newly imported files are shown. + view.refreshContentAndViewAsync(); + + // delete temp folder + if(deleteTempFiles){ + MemSpyFileOperations.deleteTempMemSpyFiles(); + } + + return true; + } + + /** + * Move imported heap from temporary file into import directory + * @param threadInfo imported heap + * @return true if file operations were successful + */ + + private String moveHeapToImportedFolder( ThreadInfo threadInfo ){ + + // Get new file name for imported file. + String newFileName = MemSpyFileOperations.getFileNameForHeapDump( threadInfo.getThreadFilePath() ); + + if( newFileName == null ){ + return null; + } + + // Move heap dump from temp folder into Heap Dumps-folder + if( MemSpyFileOperations.moveFile(new File(threadInfo.getThreadFilePath()), new File(newFileName)) ){ + return newFileName; + } + else{ + return null; + } + } + + /** + * Starts comparing two heap dump files. + * @param firstHeap first heap dump + * @param secondHeap second heap dump + */ + public void compareHeaps( ThreadInfo firstHeap, ThreadInfo secondHeap, AnalyserXMLGenerator xmlGenerator, String output ){ + + boolean importFailed = false; + + // get file paths of heap dumps. + String firstHeapFile = firstHeap.getThreadFilePath(); + String secondHeapFile = secondHeap.getThreadFilePath(); + + if( firstHeapFile != null && secondHeapFile != null ){ + + // generate compare heaps configuration file. + xmlGenerator.setXMLAnalyseFileOutput( output ); + if( this.generateCompareConfigurationFile( new String[]{ firstHeapFile, secondHeapFile}, firstHeap.getThreadName(), xmlGenerator) ){ + + // launch Heap Analyser + view.launchHeapAnalyser( MemSpyFileOperations.getCompareConfigurationFilePath(), xmlGenerator.getXMLAnalyseFileOutput(), xmlGenerator.getXMLThreadName(), false ); + } + else{ + importFailed = true; + } + } + if( importFailed ){ + view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_HEAP_IMPORT_FAILED); + } + + } + + + /** + * Imports SystemWide Memory Tracking logs and starts swmt viewer. + * @param importedLogs imported swmt logs. + */ + public void importSWMTLogs( final ArrayList importedLogs ){ + importSWMTLogs( importedLogs, true); + } + + /** + * Imports SystemWide Memory Tracking logs and starts swmt viewer. + * @param importedLogs imported swmt logs. + * @param deleteTempFiles if temp files and folder should be deleted after import + */ + public void importSWMTLogs( final ArrayList importedLogs, boolean deleteTempFiles){ + + boolean isImportedFromDevice = false; + boolean importFailed = false; + + // check if files were imported from device. + if( importedLogs.size() > 0 ){ + if (importedLogs.get(0).getType() == SWMTLogType.DEVICE ){ + isImportedFromDevice = true; + } + } + + ArrayList directories = new ArrayList(); + + // If files were imported from device, move those files into imported directory. + if( isImportedFromDevice ){ + + for( SWMTLogInfo swmtLogInfo : importedLogs){ + + // Get next free directory + String directory = MemSpyFileOperations.getNextFreeDirectory(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + + // Add directory to arraylist + directories.add( directory ); + + if( !MemSpyFileOperations.copyFileToDirectory( swmtLogInfo.getPath(), directory ) ){ + + // if operations fail show error message and remove all imported files. + importFailed = true; + MemSpyFileOperations.deleteDir( new File( directory ) ); + break; + } + } + } + else{// if importing log from file system, copy files into imported directory + + for( SWMTLogInfo swmtLogInfo : importedLogs){ + + // if file + if( swmtLogInfo.getType() == SWMTLogType.FILE ){ + + // Get next free directory + String directory = MemSpyFileOperations.getNextFreeDirectory(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + + // Add directory to arraylist + directories.add( directory ); + + if( !MemSpyFileOperations.copyFileToDirectory( swmtLogInfo.getPath(), directory ) ){ + + // if operation fails show error message and remove all imported files. + importFailed = true; + MemSpyFileOperations.deleteDir( new File( directory ) ); + break; + } + } + + + } + + } + // if error occurred show error message + if( importFailed ){ + view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_SWMT_IMPORT_FAILED); + } + else{ + // Get ArrayList of imported files. + ArrayList files = new ArrayList(); + try{ + for( String item : directories ){ + // Get filename from Log file from each directory that is saved into directories-ArrayList. + File directory = new File(item); + String fileName = directory.list()[0]; + fileName = item + fileName; + files.add( fileName ); + } + view.launchSWMTAnalyser( files ); + + } + catch( Exception e ){ + view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_LAUNCH_SWMT_ANALYSER ); + } + + } + + // Refresh main view so that newly imported files are shown. + view.refreshContentAndViewAsync(); + + // delete temp folder + if(deleteTempFiles){ + MemSpyFileOperations.deleteTempMemSpyFiles(); + } + + + + + } + + + /** + * Uses AnalyserXMLGenerator to generate configuration file for viewing heap with Heap Analyser + * @param name of the source file + * @param threadName thread's name + * @param xmlGenerator XML generator that is used. + * @return true if file was generated successfully + */ + public boolean generateViewConfigurationFile( String fileName, String threadName, AnalyserXMLGenerator xmlGenerator ){ + + xmlGenerator.setXMLAction(XMLGeneratorAction.ANALYSE_HEAP); + xmlGenerator.setXMLSourceFile( new String[]{ fileName } ); + xmlGenerator.setXMLThreadName( threadName ); + + // get filenames path + String analyserFileOutput = fileName.substring( 0, fileName.lastIndexOf("\\") + 1); + analyserFileOutput = analyserFileOutput + "configuration.xml"; + + // generate xml-file + + File filename = new File( analyserFileOutput ); + BufferedWriter writer = null; + + try { + // Construct FileWriter and print xml into that stream + writer = new BufferedWriter(new FileWriter(filename)); + xmlGenerator.GenerateXML(writer); + } + catch (IOException e) { + + e.printStackTrace(); + return false; + } + finally { + try { + if (writer != null) { + writer.flush(); + writer.close(); + return true; + } + } + catch (IOException ex) { + ex.printStackTrace(); + return false; + } + + } + return false; + } + + /** + * Uses AnalyserXMLGenerator to generate configuration file for comparing two heap's with Heap Analyser + * @param fileName names of the source files. + * @param threadName thread's name + * @param xmlGenerator XML generator that is used. + * @return true if file was generated successfully + */ + public boolean generateCompareConfigurationFile( String[] fileName, String threadName, AnalyserXMLGenerator xmlGenerator ){ + xmlGenerator.setXMLAction(XMLGeneratorAction.COMPARE_HEAPS); + xmlGenerator.setXMLSourceFile( fileName ); + xmlGenerator.setXMLThreadName( threadName ); + + String analyserFileOutput = MemSpyFileOperations.getCompareConfigurationFilePath(); + + // generate xml-file + File filename = new File( analyserFileOutput ); + + + BufferedWriter writer = null; + + try { + // Construct FileWriter and print xml into that stream + writer = new BufferedWriter(new FileWriter(filename)); + xmlGenerator.GenerateXML(writer); + } + catch (IOException e) { + + e.printStackTrace(); + return false; + } + finally { + try { + if (writer != null) { + writer.flush(); + writer.close(); + return true; + } + } + catch (IOException ex) { + ex.printStackTrace(); + return false; + } + + } + return false; + + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileBundle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileBundle.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,414 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.model; + + +import java.io.File; +import java.util.Date; + +import com.nokia.s60tools.memspy.files.HeapDumpFile; +import com.nokia.s60tools.memspy.files.SWMTFile; + +/** + * MemSpyBundle class bundles up one folder under MemSpy plugin's folder. I.e. one + * MemSpyFileBundle is one row in MainView. A Bundle can contain an Heap Dump file or + * + * SWMT-log file. All of the file listed above are found e.g. from + * c:\my_carbide_workspace\.metadata\.plugins\com.nokia.s60tools.memspy\ImportedFiles[bundle folder] + * + * Bundle can also be a waiting bundle, so that 'Loading files. Please wait' row can be shown in MainView. + * + */ +public class MemSpyFileBundle { + + public static final int INDEX_FILE_TYPE = 0; + public static final int INDEX_FILE_NAME = 1; + public static final int INDEX_TIME = 2; + + + /* + * Heap Dump file + */ + private HeapDumpFile heapDumpFile = null; + + /* + * SWMT-log file + */ + private SWMTFile swmtFile = null; + + /** + * Bundle name for an empty or waiting bundle + */ + private String bundleName = ""; + + /** + * Folder where all bundle's files can be found from + */ + private String bundleFolder = ""; + + /** + * If true, bundle is an empty or waiting bundle + */ + private boolean emptyFile = false; + + /** + * Used for creating an empty or waiting bundle + * @param empty If true, an empty bundle is created. If false, a waiting bundle is created. + */ + public MemSpyFileBundle(boolean empty) { + if (empty) + bundleName = "No Crash Files Found."; + else + bundleName = "Loading files. Please wait."; + emptyFile = true; + } + + /** + * Creates a bundle from folder + * @param folder Bundle folder. Bundle's file will be read from here. + */ + public MemSpyFileBundle( String folder ) { + bundleFolder = MemSpyFileOperations.addSlashToEnd(folder); + + heapDumpFile = HeapDumpFile.read( folder ); + swmtFile = SWMTFile.read( folder ); + + } + + /** + * Create dummy bundle. + * @param folder where files are searched. + * @return returns new bundle. + */ + public static MemSpyFileBundle createDummyBundle(String folder) { + return new MemSpyFileBundle(folder); + } + + /** + * MainView can use this to get description for each column in the grid + * @param index index of the column + * @return value for asked column + */ + public String getText(int index) { + String retval = ""; + switch (index) { + case INDEX_TIME: + retval = this.getTime(); + break; + + case INDEX_FILE_NAME: + retval = this.getFileName(); + break; + + case INDEX_FILE_TYPE: + retval = this.getFileType(); + break; + + default: + break; + } + + return retval; + } + + /** + * Get file type. + * @return type of file. + */ + public String getFileType() { + if (emptyFile) + return bundleName; + + String retval = ""; + + if ( this.heapDumpFile != null) { + retval = heapDumpFile.getFileType(); + } + + if( swmtFile != null ){ + retval = this.swmtFile.getFileType(); + } + + return retval; + } + + + /** + * Returns the file name for this bundle. File name depends on what types + * of files this bundle contains (or if this bundle is an empty or waiting bundle). + * + * @return the file name for this bundle. + */ + public String getFileName() { + if (emptyFile) + return bundleName; + + String retval = ""; + + if ( this.heapDumpFile != null) { + retval = heapDumpFile.getFileName(); + } + else if( swmtFile != null ){ + retval = this.swmtFile.getFileName(); + } + + return retval; + } + + /** + * Get the Cycle number from FileName. + * E.g. if file name is: "MemSpy SWMT-log 12.08.2009 08-40-22 Cycle 3" + * will return '3'. + * + * @return the cycle number from file name for this bundle, or -1 if can't found. + */ + public int getCycleNumberFromFileName() { + int retval = -1; + if (emptyFile){ + return retval; + } + + String fileName = ""; + + if ( this.heapDumpFile != null) { + fileName = heapDumpFile.getFileName(); + } + else if( swmtFile != null ){ + fileName = this.swmtFile.getFileName(); + } + + if(fileName != null && fileName.indexOf(MemSpyFileOperations.CYCLE) != -1){ + int index = fileName.indexOf(MemSpyFileOperations.CYCLE); + String cycle = fileName.substring((index + MemSpyFileOperations.CYCLE.length())).trim(); + cycle = cycle.substring(0, cycle.indexOf('.')); + try { + retval = Integer.parseInt(cycle); + } catch (NumberFormatException e) { + e.printStackTrace(); + retval = -1; + } + } + + return retval; + } + + /** + * Get Time + * @return time of file creation. + */ + public String getTime() { + if (emptyFile) + return ""; + String retval = ""; + + if( heapDumpFile != null ){ + retval = this.heapDumpFile.getTime(); + } + else if( swmtFile != null ){ + retval = this.swmtFile.getTime(); + } + + + return retval; + } + + /** + * Get time as long + * @return time of file creation as long. + */ + public long getTimeAsLong(){ + long time = -1; + Date date = null; + if( heapDumpFile != null ){ + date = this.heapDumpFile.getDateTime(); + } + else if( swmtFile != null ){ + date = this.swmtFile.getDateTime(); + } + + if(date != null){ + time = date.getTime(); + } + + return time; + } + + + /** + * Get XML file. + * @return XML-files path + */ + public String getXMLFilePath() { + if( heapDumpFile != null ){ + return this.heapDumpFile.getXmlPath(); + } + else{ + return null; + } + } + + /** + * Get file path. + * @return Files complete path. + */ + public String getFilePath(){ + if (emptyFile) + return ""; + String retval = ""; + + if( heapDumpFile != null ){ + retval = this.heapDumpFile.getFilePath(); + } + + if( swmtFile != null ){ + retval = this.swmtFile.getFilePath(); + } + + + return retval; + } + + + /** + * Returns whether this is an empty or waiting bundle. + * @return true if bundle is empty or waiting, false if not. + */ + public boolean isEmpty() { + return emptyFile; + } + + + + /** + * Returns whether this bundle contains any files. + * @return true if bundle contains files, false if not + */ + public boolean hasFiles() { + if ( heapDumpFile != null || swmtFile != null ) + return true; + + return false; + } + + + + /** + * Tests whether this bundle still exists in the drive. + * If bundle is empty or waiting, true is always returned. + * + * @return true if bundle exists, false if not. + */ + public boolean exists() { + if (isEmpty()) + return true; + + try { + File f = new File(bundleFolder); + if (f.isDirectory() && f.exists()) + return true; + } catch (Exception e) { + return false; + } + + return false; + } + + + + /** + * Returns this bundle's folder + * @return bundle's folder or empty + */ + protected String getBundleFolder() { + return bundleFolder; + } + + + /** + * Has this bundle a SWMT log file. + * @return true if this bundle has SWMT-log false otherwise. + */ + public boolean hasSWMTLogFile(){ + if( swmtFile != null ){ + return true; + } + return false; + } + + /** + * Has this bundle a heap dump file + * @return true if this bundle has Heap Dump false otherwise. + */ + public boolean hasHeapDumpFile(){ + + if( heapDumpFile != null ){ + return true; + + } + return false; + + } + + /** + * Deletes this bundle. I.e deletes all files under this + * bundle's folder and finally deletes the bundle folder. + */ + public boolean delete() { + if (!"".equals(bundleFolder)) { + return !MemSpyFileOperations.deleteDir( new File( bundleFolder ) ); + } + else{ + return false; + } + + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString(){ + if(swmtFile != null){ + return swmtFile.getFilePath(); + } + else{ + return null; + } + } + + /** + * Checks if bundles are equal. Two bundles are equal if + * their bundleFolder is the same. + */ + public boolean equals(Object other) { + if (this == other) + return true; + + if (!(other instanceof MemSpyFileBundle)) + return false; + + MemSpyFileBundle othr = (MemSpyFileBundle)other; + if (bundleFolder.compareToIgnoreCase(othr.getBundleFolder()) == 0) + return true; + return false; + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileManager.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.model; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ILock; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver; + + +/** + * This class is responsible for providing MemSpy files to MainView's content provider. + * This class read workspace specific files from disk and prepares them for main view. + */ +public class MemSpyFileManager extends Job { + private List memSpyFiles = null; + private INewMemSpyFilesObserver filesObserver = null; + private ILock accessLock = null; + private boolean restart = false; + private boolean jobRunning = false; + + + /** + * Constructor. + * @param observer, which is notified when reading is finished. + */ + public MemSpyFileManager( INewMemSpyFilesObserver observer ) { + super("MemSpy - Reading Files"); + filesObserver = observer; + memSpyFiles = null; + accessLock = Job.getJobManager().newLock(); + } + + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + accessLock.acquire(); + try { + jobRunning = true; + if (memSpyFiles == null) { + memSpyFiles = new ArrayList(); + } else { + + // remove no longer existing files + for (int i = 0; i < memSpyFiles.size(); i++) { + MemSpyFileBundle file = memSpyFiles.get(i); + if (!file.exists()) { + memSpyFiles.remove(i); + i--; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + accessLock.release(); + } + + //get directory + File cFilesFolder = new File( MemSpyFileOperations.getImportedDirectory() ); + + if (cFilesFolder.exists() && cFilesFolder.isDirectory()) { + + // get folders and files in imported directory + File[] folders = cFilesFolder.listFiles(); + if (folders != null) { + for (int j = 0; j < folders.length; j++) { + File cFolder = folders[j]; + if (cFolder.isDirectory()) { + accessLock.acquire(); + try { + + MemSpyFileBundle dummy = MemSpyFileBundle.createDummyBundle(cFolder.getAbsolutePath()); + if (!memSpyFiles.contains(dummy)) { + accessLock.release(); + MemSpyFileBundle bundle = new MemSpyFileBundle(cFolder.getAbsolutePath()); + if (bundle.hasFiles()) { + accessLock.acquire(); + memSpyFiles.add(bundle); + } + } + else { + accessLock.release(); + MemSpyFileBundle bundle = new MemSpyFileBundle(cFolder.getAbsolutePath()); + if (bundle.hasFiles()) { + accessLock.acquire(); + memSpyFiles.remove(dummy); + memSpyFiles.add(bundle); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + finally { + accessLock.release(); + } + } + } + } + } + + filesObserver.memSpyFilesUpdated(); + + accessLock.acquire(); + if (restart) { + restart = false; + accessLock.release(); + reSchedule(); + } + else { + jobRunning = false; + accessLock.release(); + } + + return Status.OK_STATUS; + } + + /** + * Re schelude this job + * @see Job#schedule() + */ + void reSchedule() { + Runnable refreshRunnable = new Runnable(){ + public void run(){ + schedule(100); + } + }; + + Display.getDefault().asyncExec(refreshRunnable); + } + + /** + * Get all MemSpy files for main view to use + * @return files + */ + public MemSpyFileBundle[] getmemSpyFiles() { + // files have not yet been read, start reading process + if (memSpyFiles == null) { + if(jobRunning == false){ + jobRunning = true; + setPriority(Job.LONG); + setUser(false); + schedule(100); + } + MemSpyFileBundle[] cFiles = new MemSpyFileBundle[1]; + cFiles[0] = new MemSpyFileBundle(false); + return cFiles; + } + else{ + return memSpyFiles.toArray(new MemSpyFileBundle[memSpyFiles.size()]); + } + + } + + + /** + * Refresh content. Reads files from disk again. + * @see MemSpyFileManager#run(IProgressMonitor) + */ + public void refresh() { + + accessLock.acquire(); + try { + if (jobRunning) { + restart = true; + } else { + setPriority(Job.LONG); + setUser(false); + schedule(100); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + accessLock.release(); + } + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileNameFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileNameFilter.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.File; +import java.io.FilenameFilter; + +/** + * File name filter for MemSpy log files(*.log, *.txt) + */ +public class MemSpyFileNameFilter implements FilenameFilter{ + + /* (non-Javadoc) + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) + */ + public boolean accept(File dir, String name) { + if( name.endsWith(".txt") || name.endsWith(".log") ){ + return true; + } + else{ + return false; + } + } +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileOperations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileOperations.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,372 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; + +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; + +/** + * Utilities for handling MemSpy specific file operation + */ +public class MemSpyFileOperations { + + private static final String TEMP = "\\Temp"; + + /** + * Cycle + */ + public static final String CYCLE = "Cycle"; + + /** + * Date format "dd.MM.yyyy HH:mm:ss" + */ + public final static String DATEFORMAT = "dd.MM.yyyy HH:mm:ss"; + + private final static String SWMT_LOG_TEXT = "MemSpy SWMT-log"; + private final static String CONFIGURATION_DIRECTORY_NAME = "ConfigurationFiles"; + private final static String IMPORTED_DIRECTORY_NAME = "ImportedData"; + + + /** + * Generates file name for new temporary heap dump file based on threads name and current time + * @param threadName Name of the thread + * @param date date when log has been imported + * @return new file name + */ + public static String getFileNameForTempHeapDump( String threadName, Date date){ + + + // Format the current time. + SimpleDateFormat formatter = new SimpleDateFormat ( DATEFORMAT ); + String dateString = formatter.format(date); + String threadFileName = threadName + " " + dateString + ".txt" ; + + // replace :'s with -'s as :'s cannot be on file names. + threadFileName = threadFileName.replace(':', '-'); + + //String folder = Platform.getConfigurationLocation().getURL().getFile() + "memspy\\Temp"; + String folder = MemSpyFileOperations.getPluginWorkingLocation() + TEMP; + + // create directory if needed + File file1 = new File(folder); + if( !file1.exists() ){ + if( !file1.mkdirs() ){ + return null; + } + } + + // combine directory and filename + String filePath = folder + "\\"+ threadFileName; + return filePath; + } + + + + + /** + * Copies file into another location + * @param inputFile input file where file is currently found + * @param outputFile output file where file is copied + * @return true if file operations were successful + */ + public static boolean copyFile( File inputFile, File outputFile ){ + FileReader in; + try { + + // create file reader and writer + in = new FileReader(inputFile); + FileWriter out = new FileWriter(outputFile); + int c; + + // Read line from input file and write it into output file. + while ((c = in.read()) != -1){ + out.write(c); + } + + // close files + in.close(); + out.close(); + } + catch (FileNotFoundException e) { + return false; + } + catch (IOException e) { + return false; + } + return true; + + } + + + /** + * Moves file into another location + * @param inputFile input file where file is currently found + * @param outputFile output file where file is moved + * @return true if file operations were successful false otherwise. + * @see File#renameTo(File) + */ + public static boolean moveFile(File inputFile, File outputFile ){ + + // Move file into new directory + return inputFile.renameTo(outputFile); + } + + + /** + * Generates file name for new heap dump file based on threads name and current time + * @param currentFileName current temporary file name + * @return new file name + */ + public static String getFileNameForHeapDump(String currentFileName){ + + // Get Filename + String threadFileName = currentFileName.substring( currentFileName.lastIndexOf("\\") +1 ); + String folder = MemSpyFileOperations.getNextFreeDirectory(); + if( folder == null){ + return null; + } + + folder = addSlashToEnd( folder ); + folder = folder + threadFileName; + + return folder; + } + + /** + * Returns a path where Crash Analyser plugin can do various tasks (located under workspace). + * @return E.g. C:\My_Workspace\.metadata\.plugins\[plugin name]\ + */ + public static String getPluginWorkingLocation() { + IPath location = Platform.getStateLocation( MemSpyPlugin.getDefault().getBundle()); + return location.toOSString(); + } + + /** + * Deletes directory and everything inside. + * @param dir directory name + * @return true if file operations were successful + */ + public static boolean deleteDir(File dir) { + boolean isAllDeleted = deleteFiles(dir); + // after everything inside directory is deleted, remove directory itself. + return dir.delete() && isAllDeleted; + } + + + + + /** + * Delete files from dir, but leave the dir as it is. + * @param dir + * @return true if all files and subdirectories was deleted successfully, false otherwise. + */ + public static boolean deleteFiles(File dir) { + boolean isAllDeleted = true; + if ( dir.isDirectory() ) { + + // get list of everything inside file. + String[] children = dir.list(); + + // go thru file list and call this function recursively. + for ( int i=0; i < children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + isAllDeleted = false; + } + } + } + return isAllDeleted; + } + + /** + * Returns all list of all log files(*.txt and *.log) from directory + * @param directory where from list is received + * @return files found in directory + */ + public static File[] getFilesFromDirectory(File directory){ + FilenameFilter filter = new MemSpyFileNameFilter(); + return directory.listFiles( filter ); + } + + /** + * Get temporary SWMT file name with path + * @param cycleNumber cycle number or received heap + * @param date current date + * @return temp file name, null if operation was failed. + */ + public static String getTempFileNameForSWMTLog( int cycleNumber, Date date ) { + + + // Format the current time. + SimpleDateFormat formatter = new SimpleDateFormat ( DATEFORMAT ); + String dateString = formatter.format(date); + + String fileName = SWMT_LOG_TEXT + " " + dateString + " " + CYCLE + " " + Integer.toString(cycleNumber) + ".txt"; + + // replace :'s with -'s as :'s cannot be on file names. + fileName = fileName.replace(':', '-'); + + String folder = MemSpyFileOperations.getPluginWorkingLocation() + TEMP; + + // create directory if needed + File file1 = new File(folder); + if( !file1.exists() ){ + if( !file1.mkdirs() ){ + return null; + } + } + String filePath = file1.toString() + "\\"+ fileName; + return filePath; + } + + /** + * Deletes MemSpy's temp directory and everything inside it + * @return true if operation was successful false otherwise. + */ + public static boolean deleteTempMemSpyFiles(){ + File folder = new File( MemSpyFileOperations.getPluginWorkingLocation() + TEMP ); + return deleteDir(folder); + + } + + + /** + * Creates next free directory for MemSpy data files + * @return next free directory where files can be copied. + */ + public static String getNextFreeDirectory(){ + + // Get fileList from importedHeaps-directory + String directory = MemSpyFileOperations.getImportedDirectory(); + File file = new File( directory ); + String[] fileList = file.list(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + + + int i = 0; + + File newFile = null; + + + // if ImportedHeaps-directory is found + if( fileList != null ){ + // Go thru directory in a loop and find search for first free integer value for directory name. + while( i <= fileList.length ){ + + newFile = new File( directory + Integer.toString(i) ); + if ( !newFile.isDirectory() ) + { + break; + } + i++; + } + } + else{ + newFile = new File( directory + "0" ); + } + + // if directories are created successfully, return path, if not return null + if( newFile.mkdirs() ){ + String newFileString = MemSpyFileOperations.addSlashToEnd( newFile.toString() ); + return newFileString; + } + else{ + return null; + } + + } + + /** + * If the last character of the given path is not backslash, it is added + * and path with backslash is returned. + * @param path Path to which backslash is added + * @return Path which last character is backslash + */ + public static String addSlashToEnd(String path) { + if (path.endsWith(File.separator)){ + return path; + } + else{ + return path + File.separator; + } + } + + /** + * Get imported files directory + * @return path of the imported-directory + */ + public static String getImportedDirectory(){ + // get imported-directory + String directory = MemSpyFileOperations.getPluginWorkingLocation(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + return directory + IMPORTED_DIRECTORY_NAME; + } + + /** + * Get configuration file path + * @return path of the configuration file, if file does not exist yet, method creates it. + */ + public static String getCompareConfigurationFilePath(){ + // get imported-directory + String directory = MemSpyFileOperations.getPluginWorkingLocation(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + directory = directory + CONFIGURATION_DIRECTORY_NAME; + + File file = new File(directory); + if( !file.exists() ){ + if( !file.mkdirs() ){ + return null; + } + } + directory = MemSpyFileOperations.addSlashToEnd(directory); + directory = directory + "input.xml"; + return directory; + + } + + /** + * Copies file to another directory with same filename + * @param filePath file that is copied + * @param directory output directory + * @return true if operation was successful false otherwise. + */ + public static boolean copyFileToDirectory( String filePath, String directory){ + + String fileName = filePath.substring( filePath.lastIndexOf("\\") +1 ); + String directoryTo = directory + fileName; + + return copyFile( new File( filePath ), new File( directoryTo ) ); + + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyLogParserEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyLogParserEngine.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html". + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: + * + */ + +package com.nokia.s60tools.memspy.model; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Date; + +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo.HeapDumpType; + +/** + * Heap Dump parser that is used when parsing heap dump file. + */ +public class MemSpyLogParserEngine { + + // Writer that writes into file + private PrintWriter plainOutput; + + private boolean fileOpen; + + /** + * + * Checks that at least one heap info with binary data information is found from file given as parameter. + * Function also saves thread names from heap dump file into ArrayList what + * was given as parameter threadNames. + * + * @param file + * @param threadNames + * Arraylist where thread names are saved. + * @return true if threads containing binary data information were found from this file. + */ + public boolean isFileHeapDumpFile(File file, + ArrayList threadNames) { + + boolean heapFound = false; + boolean heapDataFound = false; + boolean heapDataErrorFound = false; + + try { + String heapInfo = "HEAP INFO FOR THREAD"; + String heapData = "Heap Data"; + String heapDataError = "Heap error"; + + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = ""; + + // Go thru file in loop and search for lines that contain HEAP + // INFO-text. If text is found, save thread names into array list + // threadNames. If the thread doesn't contain any binary heap data information, + // the thread is removed from this array list. + + while (reader.ready()) { + line = reader.readLine(); + if (line.contains(heapInfo)) { + + if ((heapDataFound && heapDataErrorFound) || !heapDataFound) { + if (threadNames.size() > 0) { + threadNames.remove(threadNames.size() - 1); + } + } + + heapDataFound = false; + heapDataErrorFound = false; + + if (line.contains("'")) { + String name = line.substring(line.indexOf("'") + 1); + if (name.contains("'")) { + String thread = name + .substring(0, name.indexOf("'")); + ThreadInfo threadInfo = new ThreadInfo(); + threadInfo.setThreadName(thread); + Date date = new Date(); + threadInfo.setDate(date); + threadInfo.setType(HeapDumpType.FILE); + String fName = MemSpyFileOperations + .getFileNameForTempHeapDump(thread, date); + threadInfo.setThreadFilePath(fName); + threadNames.add(threadInfo); + + if (fileOpen) { + plainOutput.flush(); + plainOutput.close(); + } + if (!this.openFile(fName)) { + return false; + } + } + } + } + + // Checking if the line contains binary heap data header + if (line.contains(heapData)) { + heapDataFound = true; + } + + // Checking if the line contains binary heap data error + if (line.contains(heapDataError)) { + heapDataErrorFound = true; + } + + if (fileOpen) { + plainOutput.write(line + "\n"); + } + } + + // Check for the last thread in file, because if the last thread is found and if it + // contains heap data with error or no heap data at all, it wouldn't be removed + // so it needs to be done here + if ((heapDataFound && heapDataErrorFound) || !heapDataFound) { + if (threadNames.size() > 0) { + threadNames.remove(threadNames.size() - 1); + } + } + + if (threadNames.size() > 0) { + heapFound = true; + } else { + heapFound = false; + } + + if (fileOpen) { + plainOutput.close(); + fileOpen = false; + } + } catch (Exception e) { + return false; + } + return heapFound; + } + + /** + * openFile creates new print writer into given path and saves it into + * member variable plainOutput + * + * @param fName + * file name + * @return true if file operation was successful + */ + private boolean openFile(String fName) { + // If file needs to be opened, open it. + + try { + plainOutput = new PrintWriter(new FileWriter(fName)); + } catch (IOException e) { + return false; + } + this.fileOpen = true; + return true; + } + + /** + * Check if this file is a SWMT log file + * + * @param file + * @return true if file contains a SWMT tag: + * {@link TraceCoreDataHandler#LAUNCHER_SWMT_LOG_START} + * false otherwise. + */ + static public boolean isFileSWMTLog(File file) { + try { + String SWMTTag = TraceCoreDataHandler.LAUNCHER_SWMT_LOG_START; + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = ""; + int count = 0; + + // Go thru file in loop and check if first line of file contains + // swmt-tag. + + while (reader.ready() && count < 200) { + line = reader.readLine(); + count++; + + // if line contains tag, conclude that file is swmt-log + if (line.contains(SWMTTag)) { + return true; + } + + // if line is other than empty, conclude that file is not + // swmt-log + if (line.length() > 0) { + return false; + } + } + + } catch (Exception e) { + return false; + } + + // if first 200 lines were empty, conclude that file is not SWMT-log + return false; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategoryConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategoryConstants.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.model; + +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Lists all the category constants that can be used with SWMT + */ +public class SWMTCategoryConstants { + public static final int CATEGORY_NONE = 0x0; // This is not used currently anywhere, but however available for use + public static final int CATEGORY_FILESERVERCACHE = 0x0001; + public static final int CATEGORY_BITMAPHANDLES = 0x0002; + public static final int CATEGORY_USERHEAP = 0x0004; + public static final int CATEGORY_KERNELHEAP = 0x0008; + public static final int CATEGORY_LOCALCHUNKS = 0x0010; + public static final int CATEGORY_GLOBALCHUNKS = 0x0020; + public static final int CATEGORY_RAMDRIVE = 0x0040; + public static final int CATEGORY_USERSTACKS = 0x0080; + public static final int CATEGORY_GLOBALDATA = 0x0100; + public static final int CATEGORY_RAMLOADEDCODE = 0x0200; + public static final int CATEGORY_KERNELHANDLES = 0x0400; + public static final int CATEGORY_OPENFILES = 0x0800; + public static final int CATEGORY_DISKUSAGE = 0x1000; + public static final int CATEGORY_SYSTEMMEMORY = 0x2000; + public static final int CATEGORY_WINDOWGROUPS = 0x4000; + public static final int CATEGORY_ALL = 0xFFFF; // This is default value in case user has not skipped any categories + + /** + * Category profile constant for Basic Profile + */ + public static final int PROFILE_BASIC = CATEGORY_USERHEAP | CATEGORY_USERSTACKS | CATEGORY_GLOBALDATA | CATEGORY_SYSTEMMEMORY; + + /** + * Category profile constant for Ram & Disk Profile + */ + public static final int PROFILE_RAM_DISK = CATEGORY_DISKUSAGE | CATEGORY_OPENFILES | CATEGORY_RAMLOADEDCODE | CATEGORY_RAMDRIVE; + + /** + * Category profile constant for Ram, Disk & Heap Profile + */ + public static final int PROFILE_RAM_DISK_HEAP = PROFILE_RAM_DISK | CATEGORY_USERHEAP | CATEGORY_KERNELHEAP; + + /** + * Category profile constant for Ram, Disk, Heap & Handles Profile + */ + public static final int PROFILE_RAM_DISK_HEAP_HANDLES = PROFILE_RAM_DISK_HEAP | CATEGORY_BITMAPHANDLES | CATEGORY_FILESERVERCACHE | CATEGORY_SYSTEMMEMORY; + + /** + * Window Groups + */ + public static final String WINDOW_GROUPS_TXT = "Window Groups"; + /** + * Bitmap Handles + */ + public static final String BITMAP_HANDLES_TXT = "Bitmap Handles"; + /** + * FileServer Cache + */ + public static final String FILE_SERVER_CACHE_TXT = "FileServer Cache"; + /** + * RAM Drive + */ + public static final String RAM_DRIVE_TXT = "RAM Drive"; + /** + * Global Chunks + */ + public static final String GLOBAL_CHUNKS_TXT = "Global Chunks"; + /** + * Local Chunks + */ + public static final String LOCAL_CHUNKS_TXT = "Local Chunks"; + /** + * System Memory + */ + public static final String SYSTEM_MEMORY_TXT = "System Memory"; + /** + * RAM-loaded code + */ + public static final String RAM_LOADED_CODE_TXT = "RAM-loaded code"; + /** + * Open Files + */ + public static final String OPEN_FILES_TXT = "Open Files"; + /** + * Disk usage + */ + public static final String DISK_USAGE_TXT = "Disk usage"; + /** + * Global Data + */ + public static final String GLOBAL_DATA_TXT = "Global Data"; + /** + * User Stacks + */ + public static final String USER_STACKS_TXT = "User Stacks"; + /** + * Kernel Heap + */ + public static final String KERNEL_HEAP_TXT = "Kernel Heap"; + /** + * User Heap + */ + public static final String USER_HEAP_TXT = "User Heap"; + + + /** + * Debug prints those bits that are set in the category setting + * @param categories category settings to be debugged. + */ + public static void debugPrintSWMTCategorySetting(int categories){ + if((categories & CATEGORY_FILESERVERCACHE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_FILESERVERCACHE"); //$NON-NLS-1$ + if((categories & CATEGORY_BITMAPHANDLES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_BITMAPHANDLES"); //$NON-NLS-1$ + if((categories & CATEGORY_USERHEAP) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_USERHEAP"); //$NON-NLS-1$ + if((categories & CATEGORY_KERNELHEAP) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_KERNELHEAP"); //$NON-NLS-1$ + if((categories & CATEGORY_LOCALCHUNKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_LOCALCHUNKS"); //$NON-NLS-1$ + if((categories & CATEGORY_GLOBALCHUNKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_GLOBALCHUNKS"); //$NON-NLS-1$ + if((categories & CATEGORY_RAMDRIVE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_RAMDRIVE"); //$NON-NLS-1$ + if((categories & CATEGORY_USERSTACKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_USERSTACKS"); //$NON-NLS-1$ + if((categories & CATEGORY_GLOBALDATA) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_GLOBALDATA"); //$NON-NLS-1$ + if((categories & CATEGORY_RAMLOADEDCODE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_RAMLOADEDCODE"); //$NON-NLS-1$ + if((categories & CATEGORY_KERNELHANDLES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_KERNELHANDLES"); //$NON-NLS-1$ + if((categories & CATEGORY_OPENFILES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_OPENFILES"); //$NON-NLS-1$ + if((categories & CATEGORY_DISKUSAGE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_DISKUSAGE"); //$NON-NLS-1$ + if((categories & CATEGORY_SYSTEMMEMORY) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_SYSTEMMEMORY"); //$NON-NLS-1$ + if((categories & CATEGORY_WINDOWGROUPS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_WINDOWGROUPS"); //$NON-NLS-1$ + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategorys.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategorys.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.model; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoryEntry; + +/** + * Singleton Class for holding SWMT Category profiles + */ +public class SWMTCategorys { + + + private static SWMTCategorys instance=null; + + + /** + * Private constructor + */ + private SWMTCategorys(){ + initializeCategoryEntries(); + initializeCategoryProfiles(); + } + + + + /** + * Stores the category entries. + */ + private List categoryEntries; + + private List categoryProfiles; + + /** + * Get only instance of this object + * @return instance + */ + public static SWMTCategorys getInstance(){ + if(instance==null){ + instance = new SWMTCategorys(); + } + return instance; + } + + private void initializeCategoryProfiles() { + categoryProfiles = new ArrayList(); + + CategoryProfile profile0 = new CategoryProfile("Basic", SWMTCategoryConstants.PROFILE_BASIC); + getCategoryProfiles().add(profile0); + + CategoryProfile profile1 = new CategoryProfile("RAM & Disk Profile", SWMTCategoryConstants.PROFILE_RAM_DISK); + getCategoryProfiles().add(profile1); + + CategoryProfile profile2 = new CategoryProfile("RAM, Disk & Heap Profile", SWMTCategoryConstants.PROFILE_RAM_DISK_HEAP); + getCategoryProfiles().add(profile2); + + CategoryProfile profile3 = new CategoryProfile("RAM, Disk, Heap & Handles Profile", SWMTCategoryConstants.PROFILE_RAM_DISK_HEAP_HANDLES); + getCategoryProfiles().add(profile3); + + CategoryProfile profile4 = new CategoryProfile("All", SWMTCategoryConstants.CATEGORY_ALL); + getCategoryProfiles().add(profile4); + + } + + + + /** + * Initializes category entry list. + */ + private void initializeCategoryEntries() { + // Creating entry array + categoryEntries = new ArrayList< SWMTCategoryEntry>(); + // Initializing value for the array + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_USERHEAP, SWMTCategoryConstants.USER_HEAP_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_KERNELHEAP, SWMTCategoryConstants.KERNEL_HEAP_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_USERSTACKS, SWMTCategoryConstants.USER_STACKS_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_GLOBALDATA, SWMTCategoryConstants.GLOBAL_DATA_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_DISKUSAGE, SWMTCategoryConstants.DISK_USAGE_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_OPENFILES, SWMTCategoryConstants.OPEN_FILES_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_RAMLOADEDCODE, SWMTCategoryConstants.RAM_LOADED_CODE_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_SYSTEMMEMORY, SWMTCategoryConstants.SYSTEM_MEMORY_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_LOCALCHUNKS, SWMTCategoryConstants.LOCAL_CHUNKS_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_GLOBALCHUNKS, SWMTCategoryConstants.GLOBAL_CHUNKS_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_RAMDRIVE, SWMTCategoryConstants.RAM_DRIVE_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_FILESERVERCACHE, SWMTCategoryConstants.FILE_SERVER_CACHE_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_BITMAPHANDLES, SWMTCategoryConstants.BITMAP_HANDLES_TXT)); + categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_WINDOWGROUPS, SWMTCategoryConstants.WINDOW_GROUPS_TXT)); + + } + + + /** + * Get all category entries exist + * @return the categoryEntries + */ + public List getCategoryEntries() { + return categoryEntries; + } + + /** + * Get a category entry by ID + * @return the categoryEntry or null if not found + */ + public SWMTCategoryEntry getCategoryEntry(int entryID) { + + + for (Iterator iterator = categoryEntries.iterator(); iterator.hasNext();) { + SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator.next(); + if(entry.getCategoryId() == entryID){ + return entry; + } + } + + return null; + } + + + /** + * Get all category profiles created + * @return the categoryProfiles + */ + public List getCategoryProfiles() { + return categoryProfiles; + } + + /** + * Get wanted SWMT Categorys by IDs + * @param categories + * @return {@link List} of {@link SWMTCategoryEntry}'s + */ + public List getCategoryEntries(int categories) { + + List wantedCategories = new ArrayList(); + for (Iterator iterator = categoryEntries.iterator(); iterator.hasNext();) { + SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator.next(); + if((entry.getCategoryId() & categories) != 0){ + wantedCategories.add(entry); + } + } + return wantedCategories; + } + + /** + * Get profile by it's name + * @param profileName + * @return profile int or null if not found + */ + public CategoryProfile getProfile(String profileName){ + + for (Iterator iterator = categoryProfiles.iterator(); iterator + .hasNext();) { + CategoryProfile profile = (CategoryProfile) iterator.next(); + if(profileName.equals(profile.getName())){ + return profile; + } + + } + return null; + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreDataHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreDataHandler.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,595 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.regex.Pattern; + +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.export.ITraceDataProcessor; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.util.debug.DbgUtility; + + +/** + * Monitors data received from TraceCore and acts based on it. + */ +public final class TraceCoreDataHandler implements ITraceDataProcessor { + + // Count of lines + private int lineCount; + + // boolean value that is used when parsing thread list + private boolean lastWasName; + + // Array, where found thread names and id's are written + private ArrayList threadArray = null; + + // ThreadInfo-object where info is collected + private ThreadInfo threadInfo; + + // boolean value that is set to true, when trace-lines are lost + private boolean dumpedTraces; + + // boolean value that is set to false, when heap type is not symbian OS Rheap + private boolean heapTypeCorrect; + + // boolean value that is true when some information is written to file + private boolean writeFile; + + // boolean value that true when file is open + private boolean fileOpen; + + + // Writer that writes to file + private PrintWriter plainOutput; + + // Writer that writes to file + private PrintWriter swmtHeadDumpOutput = null; + + + // boolean value that is true when some memspy operations are on-going. + private boolean logging; + + // Trace engine. + private TraceCoreEngine engine; + + + //Strings + private final static String LAUNCHER_READY = ""; + private final static String MEMSPY_LAUNCHER_VERSION_PREFIX = " + private final static String END_TAG = ">"; + private final static String LAUNCHER_COLON = "::"; + private final static String LAUNCHER_THREAD_ID = "Thread Id"; + private final static String LAUNCHER_TYPE = "Type:"; + private final static String LAUNCHER_SYMBIAN_OS_RHEAP = "Symbian OS RHeap"; + private final static String LAUNCHER_HEAP_DUMP_START = "SYSTEM WIDE MEMORY TRACKER tag + */ + public final static String LAUNCHER_SWMT_LOG_START = ""; + + private final static String LAUNCHER_SWMT_LOG_END = ""; + private final static String LAUNCHER_SWMTDATA = "[SMT "; + private final static String LAUNCHER_CATEGORY_NOT_SUPPORTED = ""; + + private ThreadInfo swmtHeadDumpThreadInfo; + + /** + * Constructor. + * @param engine engine that uses handler + */ + public TraceCoreDataHandler(TraceCoreEngine engine){ + this.engine = engine; + lastWasName = false; + heapTypeCorrect = false; + writeFile = false; + lineCount = 0; + } + + /** + * Method that is called when trace logging is started. + * @param fName Name of the file, where needed information is printed. + * @param fileOpen boolean value that is true when file needs to be opened. + */ + public boolean startLogging(String fName, boolean fileOpen) { + logging = true; + lineCount = 0; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.startLogging/fName=" + fName + ", fileOpen=" + fileOpen); //$NON-NLS-1$ //$NON-NLS-2$ + + // If file needs to be opened, open it. + this.fileOpen = fileOpen; + if( fileOpen ){ + try { + plainOutput = new PrintWriter(new FileWriter( fName )); + } + catch (IOException e) { + + engine.launcherError(LauncherErrorType.FILE); + return false; + } + + } + return true; + } + + /** + * Stops logging and closes file if needed. + */ + public void stopLogging() { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.stopLogging"); //$NON-NLS-1$ + this.logging = false; + if( this.fileOpen ){ + plainOutput.flush(); + plainOutput.close(); + } + stopSWMTHeadDumpLogging(); + } + + /** + * Flush and Close swmtHeadDumpOutput + */ + private void stopSWMTHeadDumpLogging() { + if(swmtHeadDumpOutput != null){ + swmtHeadDumpOutput.flush(); + swmtHeadDumpOutput.close(); + } + } + + /** + * Open FileWriter for swmtHeadDumpOutput + */ + private void startSWMTHeadDumpLogging(){ + try { + File file = new File(swmtHeadDumpThreadInfo.getThreadFilePath()); + File path = file.getParentFile(); + if(!path.exists()){ + path.mkdirs(); + } + file.createNewFile(); + if(swmtHeadDumpThreadInfo != null){ + swmtHeadDumpOutput = new PrintWriter(new FileWriter( swmtHeadDumpThreadInfo.getThreadFilePath() )); + } + } + catch (IOException e) { + engine.launcherError(LauncherErrorType.FILE); + } + } + + /** + * Processes trace data that is received. This method is called every time trace + * data is received when logging is on. + * @param traceLineStr trace data line + */ + public void processDataLine(String traceLineStr) { + + if (logging) { + + if (traceLineStr != null) { + + if(isMemSpyRelatedLine(traceLineStr)){ + lineCount++; + } + // Reset timer every 10 MemSpy related lines. + if( lineCount > 10 ){ + engine.restartErrorTimer(); + lineCount = 0; + } + + // If Line contains launcher error message + if( traceLineStr.contains( LAUNCHER_ERROR ) ){ + handleLauncherErrorLine(traceLineStr); + } + + // If line contains message of dumped traces + else if( traceLineStr.contains( DUMPED_TC_TRACES )){ + handleDumpTCTracesLine(); + } + + // If line contains confirmation that Launcher is ready to receive new command + else if ( traceLineStr.contains(LAUNCHER_READY) ) { + handleLauncherReadyLine(); + } + else if(traceLineStr.contains(MEMSPY_LAUNCHER_VERSION_PREFIX)){ + handleLauncherVersionLine(traceLineStr); + } + //If launcher sends an progress message, restarting error timer so the timer wont reset progress + //this is done because of long taking progress was causing time outs. + else if(traceLineStr.contains(MEMSPY_PROGRESS)){ + engine.restartErrorTimer(); + } + + // If receiving heap dump + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_GET_HEAP_DUMP ){ + handleHeadDumpLine(traceLineStr); + } + + // If receiving SWMT log + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SWMT_UPDATE + || engine.getFirstTask() == TraceCoreEngine.MEMSPY_SWMT_RESET ){ + handleSWMTLine(traceLineStr); + } + + // If receiving thread info + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_THREAD_INFO ){ + handleThreadInfoLine(traceLineStr); + } + + // Setting SWMT category low bits + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SET_CATEGORIES_LOW ){ + handleCategoriesLowLine(traceLineStr); + } + + // Setting SWMT category high bits + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SET_CATEGORIES_HIGH ){ + handleCategoriesHighLine(traceLineStr); + } + + // If Receiving thread list + else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_THREAD_LIST ){ + handleThreadListLine(traceLineStr); + } + + } + } + + } + + /** + * Checks that line has something to do with MemSpy related data. + * @param str line sting + * @return true if MemSpy related data, otherwise false. + */ + private boolean isMemSpyRelatedLine(String str) { + return str.contains("HeapData") || str.contains("MemSpy"); + } + + private void handleLauncherVersionLine(String str) { + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/MEMSPY_LAUNCHER_VERSION_PREFIX"); //$NON-NLS-1$ + String version = cutString(MEMSPY_LAUNCHER_VERSION_PREFIX, END_TAG, str); + engine.setMemSpyLauncherVersion(version); + } + + private void handleLauncherReadyLine() { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_READY"); //$NON-NLS-1$ + engine.memSpyReady(); + } + + private void handleDumpTCTracesLine() { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/DUMPED_TC_TRACES"); //$NON-NLS-1$ + this.dumpedTraces = true; + } + + private void handleLauncherErrorLine(String str) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_ERROR"); //$NON-NLS-1$ + if( str.contains("'") ){ + str = str.substring( str.indexOf("'")+1 ); + if( str.contains("'") ){ + String error = str.substring( 0, str.indexOf("'") ); + LauncherErrorType type = getErrorById(error); + engine.launcherError(type); + } + } + else{ + // If no error code present, then parsing custom error message and sending information to console + String additionalErrorInfo = ""; + // Getting error message string portion + String[] splitArr = str.split(Pattern.quote(":")); + if(splitArr.length == 2){ + additionalErrorInfo = additionalErrorInfo + splitArr[1].trim(); + } + // Passing launcher error forwards generic launcher error + engine.launcherError(LauncherErrorType.GENERAL_LAUNCHER_ERROR, additionalErrorInfo); + } + } + + private void handleThreadListLine(String str) { + // If line contains "::" create new ThreadInfo-object + if ( str.contains( LAUNCHER_COLON ) ) { + + threadInfo = new ThreadInfo(); + threadInfo.setThreadName(str); + lastWasName = true; + + } + + // Save threadID into latest ThreadInfo-object and add info into thread list + if ( str.contains( LAUNCHER_THREAD_ID ) ){ + if ( lastWasName ){ + String threadID = str.substring( str.indexOf( LAUNCHER_THREAD_ID ) + LAUNCHER_THREAD_ID.length() ); + threadID = threadID.trim(); + threadInfo.setThreadID( threadID ); + threadArray.add( threadInfo ); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_THREAD_ID/id=" + threadInfo.getThreadID() + ", name=" + threadInfo.getThreadName()); //$NON-NLS-1$ //$NON-NLS-2$ + lastWasName = false; + } + } + } + + private void handleCategoriesHighLine(String str) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_SET_CATEGORIES_HIGH: " + str); //$NON-NLS-1$ + } + + private void handleCategoriesLowLine(String str) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_SET_CATEGORIES_LOW: " + str); //$NON-NLS-1$ + if(str.contains(LAUNCHER_CATEGORY_NOT_SUPPORTED)){ + //LAUNCHER_CATEGORY_NOT_SUPPORTED error + engine.launcherError(LauncherErrorType.CATEGORIES_NOT_SUPPORTED); + } + } + + private void handleThreadInfoLine(String str) { + // Check for threads heap type + if ( str.contains( LAUNCHER_TYPE ) ){ + if ( str.contains(LAUNCHER_SYMBIAN_OS_RHEAP) ){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_THREAD_INFO"); //$NON-NLS-1$ + heapTypeCorrect = true; + } + } + } + + private void handleSWMTLine(String str) { + // Check for start tag + if ( str.contains( LAUNCHER_SWMT_LOG_START ) ) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_SWMT_LOG_START"); //$NON-NLS-1$ + this.writeFile = true; + engine.restartErrorTimer(); // Resetting error time instantly when getting start event of the logging + } + + // If writing to file + if ( this.writeFile && str.contains(LAUNCHER_SWMTDATA) ){ + this.writeLine( str ); + } + + + // If we receive a Heap Dump line during SWMT logging + if ( this.writeFile && + (str.contains(LAUNCHER_HEAPDATA) + || str.contains(LAUNCHER_HEAP_DUMP_START) || str.contains(LAUNCHER_HEAP_DUMP_END))){ + handleHeapDumpDuringSWMTLogging(str); + } + + // Check for end tag + if ( str.contains( LAUNCHER_SWMT_LOG_END ) ) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_SWMT_LOG_END"); //$NON-NLS-1$ + this.writeFile = false; + engine.restartErrorTimer(); // Resetting error time instantly when getting end event of the logging + } + } + + /** + * Handling a Heap Dump line during SWMT logging + * @param str + */ + private void handleHeapDumpDuringSWMTLogging(String str) { + + //If we receiving a start point of Dump.. + if(str.contains(LAUNCHER_HEAP_DUMP_START)){ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/Start SWMT Head Dump"); //$NON-NLS-1$ + swmtHeadDumpThreadInfo = new ThreadInfo(); + if(threadArray == null){ + setThreadArray(new ArrayList()); + } + } + //If we receiving a Thread name of Dump, we create a new file for dump, and start dumping it + else if(str.contains(LAUNCHER_HEAP_INFO_FOR_THREAD)){ + + String threadName = getThreadNameFromInfo(str); + swmtHeadDumpThreadInfo.setThreadName(threadName); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/SWMT Head Dump Thread name received: " +threadName); //$NON-NLS-1$ + + //String threadName, String threadID, String threadFilePath, Date date, HeapDumpType type + // Get file name for heap dump from engine + String filePath = MemSpyFileOperations.getFileNameForTempHeapDump( + swmtHeadDumpThreadInfo.getThreadName(), swmtHeadDumpThreadInfo.getDate()); + swmtHeadDumpThreadInfo.setThreadFilePath(filePath); + startSWMTHeadDumpLogging(); + writeSWMTHeadDumpLine(str); + + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/SWMT Head Dump Thread file created: " +filePath); //$NON-NLS-1$ + + //Heap info's will act as start point for new Head dump, when Head Dumps are received during SWMT logging + //E.g. following Heap info is received: + //HeapData - mc_isiserver::Main - HEAP INFO FOR THREAD 'mc_isiserver::Main' + } + + //If we receiving a end point of Dump... + else if(str.contains(LAUNCHER_HEAP_DUMP_END)){ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/End SWMT Head Dump"); //$NON-NLS-1$ + threadArray.add( swmtHeadDumpThreadInfo ); + stopSWMTHeadDumpLogging(); + } + + //Else we receiving a dump line, and writing it to the Dump file, not to SWMT file + else if(swmtHeadDumpThreadInfo != null && swmtHeadDumpOutput != null){ + writeSWMTHeadDumpLine(str); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/LAUNCHER_HEAPDATA & MEMSPY_SWMT_UPDATE unknown line occured: " +str); + } + } + + /** + * Get Thread name from Heap Info line + * @param str + * @return Thread name + */ + private String getThreadNameFromInfo(String str) { + String name = str.substring( + (str.indexOf(LAUNCHER_HEAP_INFO_FOR_THREAD) + LAUNCHER_HEAP_INFO_FOR_THREAD.length())); + String separator = "'"; + name = name.substring((name.indexOf(separator) + separator.length()), name.lastIndexOf(separator)).trim(); + return name; + } + + private void handleHeadDumpLine(String str) { + // Check for heap end tag + if ( str.contains( LAUNCHER_HEAP_DUMP_END ) ) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_GET_HEAP_DUMP/LAUNCHER_HEAP_DUMP_END"); //$NON-NLS-1$ + this.writeFile = false; + } + + // If writing to file + if ( this.writeFile && str.contains(LAUNCHER_HEAPDATA) ){ + this.writeLine( str ); + } + + // Check for heap start tag + if ( str.contains( LAUNCHER_HEAP_DUMP_START ) ) { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_GET_HEAP_DUMP/LAUNCHER_HEAP_DUMP_START"); //$NON-NLS-1$ + this.writeFile = true; + } + } + + /** + * Cut string from startTag to endTag + * @param startTag + * @param endTag + * @param str + * @return cutted string or str given if start and end tags does not found from given str + */ + private static String cutString(String startTag, String endTag, + String str) { + if(!str.contains(startTag) && !str.contains(endTag)){ + return str; + } + String ret = str.substring(str.indexOf(startTag) + startTag.length()); + ret = ret.substring(0,ret.indexOf(endTag)); + return ret; + } + + /** + * Writes one line into opened file. + * @param line, Line that is written to file + */ + private void writeLine(String line){ + plainOutput.write(line + "\n"); + } + + /** + * Writes one line into opened file. + * @param line, Line that is written to file + */ + private void writeSWMTHeadDumpLine(String line){ + swmtHeadDumpOutput.write(line + "\n"); + } + + + // + // Getters and setters for member variables + // + + /** + * Set thread array + * @param threadArray + */ + public void setThreadArray(ArrayList threadArray) { + this.threadArray = threadArray; + } + + /** + * Check if {@link TraceCoreDataHandler#LAUNCHER_COLON} was found in line + * @param lastWasName + */ + public void setLastWasName(boolean lastWasName) { + this.lastWasName = lastWasName; + } + + /** + * Check if heap type was correct + * @return true if heap type was correct, false otherwise. + */ + public boolean isHeapTypeCorrect() { + return heapTypeCorrect; + } + + /** + * Set heap type as correct + * @param heapTypeCorrect + */ + public void setHeapTypeCorrect(boolean heapTypeCorrect) { + this.heapTypeCorrect = heapTypeCorrect; + } + + /** + * Set dump traces + * @param dumpedTraces + */ + public void setDumpedTraces(boolean dumpedTraces) { + this.dumpedTraces = dumpedTraces; + } + + /** + * Check if trace was containing {@link TraceCoreDataHandler#DUMPED_TC_TRACES} lines + * @return true if dumped lines was found, false otherwise. + */ + public boolean isDumpedTraces() { + return dumpedTraces; + } + + /** + * Returns {@link LauncherErrorType} by its ordinal + * @param errorCodeAsString Error number as string + * @return {@link LauncherErrorType} or {@link LauncherErrorType#ACTIVATION} if no matching item found. + */ + private LauncherErrorType getErrorById(String errorCodeAsString){ + + try { + int errorCode = Integer.parseInt(errorCodeAsString); + LauncherErrorType [] values = LauncherErrorType.values(); + for (int i = 0; i < values.length; i++) { + if(errorCode == values[i].ordinal()){ + return values[i]; + } + } + } catch (NumberFormatException e) { + //If occurs, it's an internal error, MemSpy S60 side is giving id in wrong format. + e.printStackTrace(); + MemSpyConsole.getInstance().printStackTrace(e); + } + + return LauncherErrorType.ACTIVATION; + } + + /** + * Get imported SWMT Heap Dumps + * @return imported SWMT Heap Dumps + */ + public ArrayList getImportedSWMTHeaps() { + return threadArray; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreEngine.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1093 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Date; + +import javax.swing.Timer; + +import com.nokia.s60tools.memspy.common.ProductInfoRegistry; +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType; +import com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherAction; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.preferences.MemSpyPreferences; +import com.nokia.s60tools.memspy.ui.wizards.DeviceOrFileSelectionPage; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.util.console.IConsolePrintUtility; +import com.nokia.s60tools.util.debug.DbgUtility; + + +/** + * TraceCoreEngine class offers public services for starting operations for + * getting heap dump and SWMT log data. It creates and manages list of sub tasks + * are requested sequentially until main operation chain is over (either successfully + * or with error). + * + * This class is tightly coupled with TraceCoreDataHandler class + * that parses trace data and passes flow control back to TraceCoreEngine + * between individual sub tasks. + * + * @see com.nokia.s60tools.memspy.model.TraceCoreDataHandler.java + */ +public class TraceCoreEngine implements ActionListener, ITraceClientNotificationsIf { + + /** + * Enumerator for upper level operation progress status. Ordinal order of the operations should not be changed. + * Once operation status is advanced to EProgressMemSpyOperationDone + * the progress status is not initialized until wizard re-start, connection setting are changed, or an error occurs. + * + * The enumerator is used in order being able to give user best possible guidance on time-out error when we know + * the context in which the error has occurred. + */ + public enum ProgressStatus{ + EPROGRESS_INITIAL, // Initial status with no progress so far during current session + EPROGRESS_MEMSPY_LAUNCHED, // MemSpy has been launched successfully + EPROGRESS_FIRST_TASK_LAUNCHED, // First actual task for MemSpy is triggered (i.e. non-MemSpy launch task) + EPROGRESS_FIRST_TASK_DONE // First actual task for MemSpy completed successfully (i.e. non-MemSpy launch task) + } + + // GroupIDs that are used + public final static String MEMSPY_LAUNCH = "10"; + public final static String MEMSPY_THREAD_LIST = "11"; + public final static String MEMSPY_THREAD_INFO = "12"; + public final static String MEMSPY_GET_HEAP_DUMP = "13"; + public final static String MEMSPY_SWMT_UPDATE = "14"; + public final static String MEMSPY_SWMT_RESET = "16"; + public final static String MEMSPY_STOP = "17"; + public final static String MEMSPY_SET_CATEGORIES_LOW = "19"; + public final static String MEMSPY_SET_CATEGORIES_HIGH = "20"; + public final static String MEMSPY_SET_SWMT_HEAP_DUMP = "21"; + public final static String MEMSPY_SET_HEAP_NAME_FILTER = "SUBSCRIBE_COMM_EVENT_SET_HEAP_NAME_FILTER"; + + // Time that device waits for line. + private final int SECOND = 1000; + private final int DEFAULT_WAIT_TIME = 20 * SECOND; // seconds + private final int MAX_WAIT_TIME = 60 * SECOND; // seconds + private int currentWaitTime; + + /** + * Indicate that MemSpy Launcher data version is not received. + */ + private static final int MEMSPY_LAUNCHER_VERSION_NOT_DEFINED = -1; + + /* timer that is used in error correction */ + private Timer errorTimer; + + /* boolean value that is true when MemSpy is running */ + private boolean MemSpyRunning; + + /* Cycle number of swmt logs that is received next time */ + private int cycleNumber; + + /* interval between swmt logs */ + private int interval; + + /* timer that is used when receiving SWMT-logs via timer */ + private Timer intervalTimer; + + /* info of swmt-log that is currently received */ + private SWMTLogInfo swmtLogInfo; + + // Trace data handler + private TraceCoreDataHandler handler; + + // Id of threads that is currently received + int threadID; + + // Task list + private ArrayList taskList; + + // WizardPage, that is notified when operations are done. + private IMemSpyTraceListener wizardPage; + + // Name of the file where heap dumps and SWMT-logs are written. + private String currentFile; + + /** + * If S60 MemSpy is to be closed between cycles + */ + private boolean resetBetweenCycles = false; + + /** + * Stores MemSpy launcher communication version. + */ + private int receivedMemSpyLauncherDataVersion = MEMSPY_LAUNCHER_VERSION_NOT_DEFINED; + + /** + * Upper level operation progress status. Ordinal order of the operations should not be changed. + * Once operation status is advanced to EProgressMemSpyOperationDone + * the progress status is not initialized until wizard re-start, connection setting are changed, or an error occurs. + */ + private ProgressStatus progressStatus = ProgressStatus.EPROGRESS_INITIAL; + + /** + * Provides possibly additional error information about the occurred error. + */ + private String additionalErrorInformation; + + /** + * Constructor. + */ + public TraceCoreEngine(){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine() Construct START"); //$NON-NLS-1$ + this.MemSpyRunning = false; + this.handler = new TraceCoreDataHandler(this); + this.taskList = new ArrayList(); + this.errorTimer = null; + this.cycleNumber = 1; + this.interval = 0; + this.swmtLogInfo = null; + this.currentWaitTime = DEFAULT_WAIT_TIME; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine() Construct END"); //$NON-NLS-1$ + } + + /** + * Request thread list from MemSpyLauncher. + * @param threadArray array where thread names and id's are written + * @param wizard page which is notified when request is finished + * @return true, if connection to TraceCore established successfully, else false + */ + + public boolean requestThreadList( ArrayList threadArray, DeviceOrFileSelectionPage wizard ){ + this.wizardPage = wizard; + + // Set handler values correct + handler.setLastWasName( false ); + handler.setThreadArray( threadArray ); + + // if connection established successfully, return true + if( this.connect() ){ + + // Set handler values correct + handler.setLastWasName( false ); + handler.setThreadArray( threadArray ); + + if( !this.MemSpyRunning ){ + taskList.add( MEMSPY_LAUNCH ); + } + taskList.add( MEMSPY_THREAD_LIST ); + return this.runNextTask(); + } + else{ + return false; + } + + + } + + /** + * Request Heap Dump from device and write it into text file + * @param threadID ID of thread which is requested from device + * @param wizardPage page which is notified when request is finished + * @param currentFile path of the file where Heap Dump is written + * @return true, if connection to TraceCore established successfully, else false + */ + public boolean requestHeapDump( int threadID, IMemSpyTraceListener wizardPage, String currentFile ){ + + this.currentFile = currentFile; + this.wizardPage = wizardPage; + this.threadID = threadID; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestHeapDump/threadID=" + threadID); //$NON-NLS-1$ + + if( this.connect() ){ + + // Reset heap type value + handler.setHeapTypeCorrect( false ); + + // Send id to trace, + if( !this.sendIntegerDataToLauncher(threadID) ){ + launcherError(LauncherErrorType.ACTIVATION); + return false; + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestHeapDump/activateId => OK"); //$NON-NLS-1$ + } + + if( !this.MemSpyRunning ){ + taskList.add( MEMSPY_LAUNCH ); + } + + // Add tasks into task list + taskList.add( MEMSPY_THREAD_INFO ); + taskList.add( MEMSPY_GET_HEAP_DUMP ); + + // start running tasks + return this.runNextTask(); + } + else{ + return false; + } + } + + /** + * Request Heap Dump from device and write it into text file + * @param threadID ID of thread which is requested from device + * @param wizardPage page which is notified when request is finished + * @param currentFile path of the file where Heap Dump is written + * @return true, if connection to TraceCore established successfully, else false + */ + public boolean requestHeapDump( String threadID, IMemSpyTraceListener wizardPage, String currentFile ){ + + return requestHeapDump( Integer.parseInt(threadID), wizardPage, currentFile ); + + } + + /** + * Request SWMT-log from device and write it into file + * @param wizardPage page which is notified when request is finished + * @param currentFile path of the file where Heap Dump is written + * @param resetCycles should cycles be reseted + * @return true, if connection to TraceCore established successfully, else false + */ + public boolean requestSWMTLog( IMemSpyTraceListener wizardPage, String currentFile, boolean resetCycles){ + this.currentFile = currentFile; + this.wizardPage = wizardPage; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestSWMTLog(resetCycles=" + resetCycles + ")/currentFile: " + currentFile); //$NON-NLS-1$ //$NON-NLS-2$ + + // if connection established successfully, return true + if( this.connect() ){ + + // stop and start MemSpy so that logging is reseted. + if( resetCycles == true ){ + taskList.add( MEMSPY_STOP ); + taskList.add( MEMSPY_LAUNCH ); + } + + // If MemSpy is not running launch it + if( !this.MemSpyRunning ){ + taskList.add( MEMSPY_LAUNCH ); + } + + //Adding category settings requests, if the feature is supported + if(MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()){ + taskList.add( MEMSPY_SET_CATEGORIES_LOW ); //LOW bytes has to be written always before high bytes + taskList.add( MEMSPY_SET_CATEGORIES_HIGH ); //HIGH bytes has to be written always after low bytes + } + + + // Set the name filter for User Heap SWMT category + if(MemSpyPreferences.isSWMTHeapDumpSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected()) { + taskList.add( MEMSPY_SET_SWMT_HEAP_DUMP ); + taskList.add( MEMSPY_SET_HEAP_NAME_FILTER ); + } + + taskList.add( MEMSPY_SWMT_UPDATE ); + + // start running tasks + return this.runNextTask(); + } + else{ + return false; + } + } + + /** + * Starts timer based SWMT logging. + * @param wizardPage page which is notified when request is finished + * @param currentFile path of the file where Heap Dump is written + * @param resetInStart should cycles be reseted + * @param resetBetweenCycles if MemSpy S60 application is to be reseted between every cycle + * @param interval poll interval + * @return true, if connection to TraceCore established successfully, else false + */ + public boolean startSWMTTimer( IMemSpyTraceListener wizardPage, int cycleNumber, + boolean resetInStart, boolean resetBetweenCycles, int interval ){ + this.wizardPage = wizardPage; + this.resetBetweenCycles = resetBetweenCycles; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.startSWMTTimer"); //$NON-NLS-1$ + + // if connection established successfully, return true + if( this.connect() ){ + this.cycleNumber = cycleNumber - 1; + this.interval = interval; + + + if( resetInStart == true ){ + taskList.add( MEMSPY_STOP ); + taskList.add( MEMSPY_LAUNCH ); + + } + + this.runNextTimedTask(); + + return true; + } + else{ + return false; + } + + + } + + + /** + * Stops SWMT timer + * @return true if timer was stopped immediately, false if MemSpy operation was on-going and timer is stopped after after operations are done. + */ + public boolean stopSWMTTimer(){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.stopSWMTTimer"); //$NON-NLS-1$ + + // other variables to zero. + this.interval = 0; + this.cycleNumber = 1; + + // if timer is, running stop it + if( intervalTimer != null && intervalTimer.isRunning() ){ + intervalTimer.stop(); + this.swmtLogInfo = null; + return true; + } + else{ + return false; + } + } + + /** + * addNextTimedTask. + * Adds next timed tasks into taskList if needed + */ + private void runNextTimedTask(){ + + cycleNumber++; + + // get new SWMT-object and set filename correct + swmtLogInfo = this.getNewSWMTInfo(); + this.currentFile = swmtLogInfo.getPath(); + + // If MemSpy is not running launch it + if( !this.MemSpyRunning ){ + taskList.add( MEMSPY_LAUNCH ); + } + //If memSpy is running and we want to reset it between cycles + else if(this.MemSpyRunning && resetBetweenCycles == true ){ + taskList.add( MEMSPY_STOP ); + taskList.add( MEMSPY_LAUNCH ); + + } + + //Adding category settings requests, if the feature is supported + if(MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()){ + taskList.add( MEMSPY_SET_CATEGORIES_LOW ); //LOW bytes has to be written always before high bytes + taskList.add( MEMSPY_SET_CATEGORIES_HIGH ); //HIGH bytes has to be written always after low bytes + } + + // Set the name filter for User Heap SWMT category + if(MemSpyPreferences.isSWMTHeapDumpSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected()) { + taskList.add( MEMSPY_SET_SWMT_HEAP_DUMP ); + taskList.add( MEMSPY_SET_HEAP_NAME_FILTER ); + } + + + // Requesting SWMT update + taskList.add( MEMSPY_SWMT_UPDATE ); + + // start runnings tasks + this.runNextTask(); + } + + /** + * Function that handles calls when MemSpys operation is finished successfully + * This method is called from DataHandler every time tag -tag received. + */ + public void memSpyReady(){ + + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady"); //$NON-NLS-1$ + + //Check Launcher data version + checkMemSpyLauncherDataVersion(); + //MemSpy launcher data version is received always before -tag is received + //When version number is checked, returning -1 to received value + receivedMemSpyLauncherDataVersion = MEMSPY_LAUNCHER_VERSION_NOT_DEFINED; + + // Stop logging trace data + handler.stopLogging(); + // Stop listening trace data + MemSpyPlugin.getTraceProvider().stopListenTraceData(); + // Stop timer + errorTimer.stop(); + + // Checking an updating progress status based on the completed task type + checkTaskForCurrentProgressStatus(this.taskList.get(0)); + + if( this.taskList.get(0) == MEMSPY_LAUNCH ){ + //Setting timer value to MAX here when known that MemSpy Launcher in S60 target is OK + //(last successfully run command is MemSpy launch). + this.currentWaitTime = MAX_WAIT_TIME; + + // MemSpy started successfully, update status + this.MemSpyRunning = true; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_LAUNCH/MemSpyRunning=true"); //$NON-NLS-1$ + if( this.taskList.size() >= 2 && this.taskList.get(1) == MEMSPY_THREAD_INFO ){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_LAUNCH/activateId( threadID: "+ threadID); //$NON-NLS-1$ + if( !this.sendIntegerDataToLauncher(threadID) ){ + launcherError(LauncherErrorType.ACTIVATION); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "T raceCoreEngine.memSpyReady/MEMSPY_LAUNCH/activateId => OK"); //$NON-NLS-1$ + } + } + } + else if( this.taskList.get(0) == MEMSPY_THREAD_LIST ){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_THREAD_LIST"); //$NON-NLS-1$ + this.wizardPage.operationFinished( LauncherAction.GET_THREAD_LIST ); + } + else if( this.taskList.get(0) == MEMSPY_THREAD_INFO ){ + // Heap info received + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_THREAD_INFO"); //$NON-NLS-1$ + + // If heap type is not correct, reset tasklist and return error + if( !handler.isHeapTypeCorrect() ){ + this.taskList.clear(); + this.wizardPage.deviceError( LauncherErrorType.HEAP_TYPE_WRONG ); + } + + // ignore dumped traces-messages. + if( handler.isDumpedTraces() ){ + handler.setDumpedTraces( false ); + } + } + else if( this.taskList.get(0) == MEMSPY_GET_HEAP_DUMP ){ + // Heap Dump received + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_GET_HEAP_DUMP"); //$NON-NLS-1$ + + if( handler.isDumpedTraces() == false ){ + // Tell wizard that request is finished + this.wizardPage.operationFinished( LauncherAction.GET_HEAP_DUMP ); + } + else{ + handler.setDumpedTraces( false ); + this.launcherError(LauncherErrorType.HEAP_NOT_FOUND); + } + } + else if( this.taskList.get(0) == MEMSPY_SWMT_UPDATE || this.taskList.get(0) == MEMSPY_SWMT_RESET ){ + // if SWMT log received + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SWMT_UPDATE || MEMSPY_SWMT_RESET"); //$NON-NLS-1$ + + if( handler.isDumpedTraces() == false ){ + // Tell wizard that request is finished + + // if timed swmt-logging is on request notification after interval + if( swmtLogInfo != null ){ + + boolean timerRunning = false; + + // if interval is more that zero, start counter and set timerRunning variable correct. + if( interval > 0 ){ + intervalTimer = new Timer( interval * SECOND, this ); + intervalTimer.start(); + timerRunning = true; + } + + // tell wizard that one log file has been received. + this.wizardPage.operationFinished( LauncherAction.TIMED_SWMT_UPDATE, swmtLogInfo, timerRunning); + swmtLogInfo = null; + + } + else{ + this.wizardPage.operationFinished( LauncherAction.SWMT_UPDATE ); + } + } + else{ + //Reset SWMT timer values. + this.stopSWMTTimer(); + + handler.setDumpedTraces( false ); + this.launcherError(LauncherErrorType.HEAP_NOT_FOUND); + } + } + else if( this.taskList.get(0) == MEMSPY_STOP ){ + MemSpyRunning = false; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_STOP"); //$NON-NLS-1$ + } + + // Remove first task from list. + if(taskList.size() > 0){ + this.taskList.remove(0); + // Updating progress status to next task launched status + // (only updated in case this is progress to previous situation). + setProgressStatus(ProgressStatus.EPROGRESS_FIRST_TASK_LAUNCHED); + } + // run next task + this.runNextTask(); + + + } + + /** + * Updates progress status based on given task id. + * Used setter method takes care that update is done only + * if there has been progress compared to previous situation. + * @param taskId task event for the task that was just completed + */ + private void checkTaskForCurrentProgressStatus(String taskId) { + if( taskId == MEMSPY_LAUNCH ){ + setProgressStatus(ProgressStatus.EPROGRESS_MEMSPY_LAUNCHED); + } + else{ + // In case of other than launch task first task has been executed properly + setProgressStatus(ProgressStatus.EPROGRESS_FIRST_TASK_DONE); + } + } + + /** + * Handles calls when launcher prints error message into trace. + * @param error error code + * @param clientContextErrorString provides optionally additional information about the error occurred + */ + public void launcherError( LauncherErrorType error, String clientContextErrorString ){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.launcherError/error: " + error); //$NON-NLS-1$ + + additionalErrorInformation = clientContextErrorString;; + + handler.stopLogging(); + // Stop listening trace data + MemSpyPlugin.getTraceProvider().stopListenTraceData(); + + // Stop timer + if( errorTimer != null ){ + errorTimer.stop(); + //Setting timer value to default when error occurred + this.currentWaitTime = DEFAULT_WAIT_TIME; + } + + // if wizard has been shut down, don't send error message. + if( taskList.size() == 1 && taskList.get(0) == MEMSPY_STOP ){ + return; + } + this.taskList.clear(); + // Stop logging trace data + + // + //When there are special handling about error, founding error codes and then call the wizard. + //But in default case, we just pass the error code to wizard to show the error. + // + + // MemSpy not running. + if( error == LauncherErrorType.MEMSPY_NOT_RUNNING ){ + wizardPage.deviceError( LauncherErrorType.MEMSPY_NOT_RUNNING ); + this.MemSpyRunning = false; + } + else if( error == LauncherErrorType.NO_ANSWER_FROM_DEVICE ){ + // No answer from device can happen because + if( handler.isDumpedTraces() ){ + // Input data is corrupted and traces are dumped... + handler.setDumpedTraces( false ); + wizardPage.deviceError( LauncherErrorType.DUMPED_TRACES ); + } + else{ + //..or connection is broken and we really has'nt got any response from device + wizardPage.deviceError( LauncherErrorType.NO_ANSWER_FROM_DEVICE ); + } + } + else { + wizardPage.deviceError( error); + } + + } + + + /** + * Function that is called when response from launcher is not received within reasonable time. + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent e) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.actionPerformed/e.getSource(): " + e.getSource().toString()); //$NON-NLS-1$ + + if( e.getSource() == errorTimer ){ + // This function is called if MemSpy operation does not respond in time stored in currentWaitTime member variable. + // I.e. no answer has been received from the device in expected maximum time. + this.launcherError(LauncherErrorType.NO_ANSWER_FROM_DEVICE); + } + else if( e.getSource() == intervalTimer ){ + this.runNextTimedTask(); + // Notify wizard that SWMT receiving is started + wizardPage.startedReceivingSWMTLog(); + intervalTimer.stop(); + } + + } + + + /** + * Shuts down MemSpy application. If some MemSpy operation is on-going schedule shutdown after that. + */ + public void shutDownMemSpy(){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.shutDownMemSpy"); //$NON-NLS-1$ + + // if MemSpy is running, send stop request + if( this.MemSpyRunning ) { + this.taskList.add( MEMSPY_STOP ); + } + + // If timer is not running( MemSpy is not currently operating ), run next task + if( errorTimer != null && !errorTimer.isRunning() ){ + this.runNextTask(); + } + disconnectTrace(); + } + + /** + * Check if MemSpy is running + * @return true if MemSpy is Running false otherwise. + */ + public boolean isMemSpyRunning() { + return MemSpyRunning; + } + + /** + * Establishes connection between plugin and device. + * @return true, is connection established successfully + */ + private boolean connect(){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.connect"); //$NON-NLS-1$ + return MemSpyPlugin.getTraceProvider().connectTraceSource(this); + } + + /** + * Disconnects connection between plugin and device if connection was started + * for this MemSpy run. Leaving connection up, if TraceViewer was already connected. + */ + public void disconnectTrace() { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.disconnectTrace"); //$NON-NLS-1$ + MemSpyPlugin.getTraceProvider().disconnectTraceSource(); + } + + /** + * Sends current usage context-specific integer data to launcher. + * Integer data can contain values that can be expressed with 10 bytes + * i.e. only 10 lower bytes are taken into account when setting data. + * @param integerData integer data to be sent + * @return false if failed to send integer data, otherwise true + */ + private boolean sendIntegerDataToLauncher(int integerData) + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "sendIntegerDataToLauncher: id=" + integerData); //$NON-NLS-1$ + return MemSpyPlugin.getTraceProvider().sendIntData(integerData); + } + + /** + * Sends current usage context-specific string message to launcher. + * @param stringData string data to send + * @param writesFile set to true if set trace handler needs to write some data into file + * @return true on success, otherwise false + */ + private boolean sendStringDataToLauncher(String stringData, boolean writesFile){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.sendMessage/message=" + stringData); //$NON-NLS-1$ + + if(! addDataProcessorAndSetupLogging(writesFile)){ + return false; + } + + if(! MemSpyPlugin.getTraceProvider().sendStringData(stringData)){ + return false; + } + + startErrorTimer(); + return true; + } + + /** + * activateTrace + * Sends activation/deactivation message via TraceCore + * @param group GroupID + * @param writesFile true, if set trace handler needs to write some data into file. + * return false if trace activation was not successful. + */ + private boolean activateTrace( String group, boolean writesFile ){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.activateTrace/group=" + group + ", writesFile=" + writesFile); //$NON-NLS-1$ //$NON-NLS-2$ + + if(! addDataProcessorAndSetupLogging(writesFile)){ + return false; + } + + if(! MemSpyPlugin.getTraceProvider().activateTrace(group)){ + return false; + } + + startErrorTimer(); + return true; + + } + + /** + * Starts error time after request. + */ + private void startErrorTimer() { + // Start Timer + errorTimer = new Timer( currentWaitTime, this ); + errorTimer.start(); + } + + /** + * Adds dataprocessor and sets-up logging. + * @param writesFile true, if set trace handler needs to write some data into file. + * @return true in case of success, and false in case of some failure. + */ + private boolean addDataProcessorAndSetupLogging(boolean writesFile) { + + //Add DataProcessor to TraceViewer + if(! MemSpyPlugin.getTraceProvider().startListenTraceData(handler)){ + return false; + } + + // Start logging + if( !handler.startLogging(currentFile, writesFile ) ){ + return false; + } + + return true; + } + + /** + * runNextTask + * Gets next task from list and sends it to TraceCore. + * @return false if operation fails. + */ + private boolean runNextTask(){ + + try { + if( taskList.size() > 0 ){ + String nextTask = taskList.get(0); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.runNextTask/taskList.get(0)=" + nextTask); //$NON-NLS-1$ + + // Confirming that all necessary preparations for running the next task has been done. + prepareRunNextTask(); + + // Set writeFile value as false when task needs to write some data into file + if( nextTask == MEMSPY_GET_HEAP_DUMP || nextTask == MEMSPY_SWMT_UPDATE || nextTask == MEMSPY_SWMT_RESET ){ + if( !activateTrace( nextTask, true ) ){ + this.launcherError(LauncherErrorType.ACTIVATION); + return false; + } + } + else if(nextTask == MEMSPY_SET_HEAP_NAME_FILTER){ + // This task used subscribe communication, instead of group IDs + // Send SWMT heap filter before activating command group + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SET_HEAP_NAME_FILTER/sendMessage"); //$NON-NLS-1$ + if( !this.sendStringDataToLauncher(getHeapNameFilterForSWMT(), false)){ + launcherError(LauncherErrorType.ACTIVATION); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SET_HEAP_NAME_FILTER/sendMessage => OK"); //$NON-NLS-1$ + } + } + else{ + if( !activateTrace( nextTask, false) ){ + this.launcherError(LauncherErrorType.ACTIVATION); + return false; + }; + + } + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreEngine.runNextTask/empty taskList"); //$NON-NLS-1$ + //Setting timer value to default when there are no tasks to run + this.currentWaitTime = DEFAULT_WAIT_TIME; + } + return true; + + } catch (Exception e) { + String errMsg = "Unexpected exception in encountered in TraceCoreEngine.runNextTask: " + e; + MemSpyConsole.getInstance().println(errMsg , IConsolePrintUtility.MSG_ERROR); + return false; + } + + } + + + /** + * Confirms that all necessary preparations for running the next task has been done. + */ + private void prepareRunNextTask() { + if(this.taskList.get(0) == MEMSPY_SET_CATEGORIES_LOW ){ + // Setting SWMT low bits data before activating command group + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/activateId( getCategoriesForSWMTLowBits(): "+ getCategoriesForSWMTLowBits()); //$NON-NLS-1$ + if( !this.sendIntegerDataToLauncher( getCategoriesForSWMTLowBits()) ){ + launcherError(LauncherErrorType.ACTIVATION ); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId => OK"); //$NON-NLS-1$ + } + } + else if( this.taskList.get(0) == MEMSPY_SET_CATEGORIES_HIGH ){ + // Setting SWMT high bits data before activating command group + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId( getCategoriesForSWMTHighBits(): "+ getCategoriesForSWMTHighBits()); //$NON-NLS-1$ + if( !this.sendIntegerDataToLauncher( getCategoriesForSWMTHighBits()) ){ + launcherError(LauncherErrorType.ACTIVATION ); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId => OK"); //$NON-NLS-1$ + } + } + } + + /** + * getNewSWMTInfo. + * Creates a new SWMTLogInfo object and sets correct filename and time into it. + * @return SWMTLogInfo-object + */ + private SWMTLogInfo getNewSWMTInfo(){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.getNewSWMTInfo"); //$NON-NLS-1$ + + // Create new SWMTLogInfo item. + SWMTLogInfo newItem = new SWMTLogInfo(); + + // set date correct + Date date = new Date(); + newItem.setDate(date); + + + // set filename correct + newItem.setPath( MemSpyFileOperations.getTempFileNameForSWMTLog(cycleNumber, date) ); + + // set type + newItem.setType( SWMTLogType.DEVICE ); + + return newItem; + } + + /** + * Get first task. + * @return first task from taskList. + */ + public String getFirstTask(){ + if( taskList.size() > 0 ){ + return taskList.get(0); + } + else{ + return null; + } + } + + /** + * Gets lower 10 bits for SWMT categories that user wants to include into SWMT log. + * @return lower 10 bits for SWMT categories that user wants to include into SWMT log. + */ + public int getCategoriesForSWMTLowBits() { + int lowBits = getCategoriesForSWMTWithKernelHandles() & 0x3ff; // ANDs away all the other that lower 10 bits + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMTLowBits(): " + String.format("0x%x", lowBits)); //$NON-NLS-1$ + return lowBits; + } + + /** + * Gets higher bits for SWMT categories that user wants to include into SWMT log. + * @return higher bits for SWMT categories that user wants to include into SWMT log. + */ + public int getCategoriesForSWMTHighBits() { + int highBits = getCategoriesForSWMTWithKernelHandles()>>10; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMTHighBits(): " + String.format("0x%x", highBits)); //$NON-NLS-1$ + return highBits; + } + + /** + * Gets SWMT categories that user wants to include into SWMT log. + * Includes always {@link SWMTCategoryConstants#CATEGORY_KERNELHANDLES} with it because SWMT Analyser + * needs it to be functional + * @return SWMT categories that user wants to include into SWMT log. + */ + private int getCategoriesForSWMTWithKernelHandles() { + // CATEGORY_KERNELHANDLES is always included into fetched categories because data is required by SWMT analyser plug-in + //If SWMT Analyzer is modified so that Kernel Handles is not always needed then SWMTCategoryConstants.CATEGORY_KERNELHANDLES can be removed. + return getCategoriesForSWMT() | SWMTCategoryConstants.CATEGORY_KERNELHANDLES; + } + + + /** + * Gets SWMT categories that user wants to include into SWMT log. + * @return SWMT categories that user wants to include into SWMT log. + */ + public int getCategoriesForSWMT() { + int sessionSpecificSWMTCategorySetting = MemSpyPreferences.getSWMTCategorySetting(); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMT(): " + String.format("0x%x", sessionSpecificSWMTCategorySetting)); //$NON-NLS-1$ + SWMTCategoryConstants.debugPrintSWMTCategorySetting(sessionSpecificSWMTCategorySetting); + return sessionSpecificSWMTCategorySetting; + } + + /** + * Sets SWMT categories that user wants to include into SWMT log. + * @param categoriesForSWMT SWMT categories that user wants to include into SWMT log. + * @param isProfileSettings true if these settings are profile settings + * false if these are custom settings + */ + public void setCategoriesForSWMT(int categoriesForSWMT, boolean isProfileSettings) { + MemSpyPreferences.setSWMTCategorySetting(categoriesForSWMT, isProfileSettings); + } + + /** + * Sets if User has select a Profile or not + * @param isProfileCategoriesSelected + */ + public void setProfileTrackedCategoriesSelected(boolean isProfileCategoriesSelected) { + MemSpyPreferences.setProfileTrackedCategoriesSelected(isProfileCategoriesSelected); + } + + /** + * Gets if User has select a Profile or not + * @return true if one of the profiles has been selected + */ + public boolean isProfileTrackedCategoriesSelected() { + return MemSpyPreferences.isProfileTrackedCategoriesSelected(); + } + + /** + * Gets SWMT HeapNameFilter to filter User Heaps in SWMT log. + * @return SWMT HeapNameFilter that user wants to include into SWMT log. + */ + public String getHeapNameFilterForSWMT() { + String filter = MemSpyPreferences.getSWMTHeapNameFilter(); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getHeapNameFilterForSWMT(): " + filter); //$NON-NLS-1$ + return filter; + } + + /** + * Sets SWMT HeapNameFilter to filter User Heaps in SWMT log. + * @param HeapNameFilter SWMT HeapNameFilter that user wants to include into SWMT log. + */ + public void setHeapNameFilterForSWMT(String heapNameFilterForSWMT) { + MemSpyPreferences.setSWMTHeapNameFilter(heapNameFilterForSWMT); + } + + /** + * Restarts error timer + */ + public void restartErrorTimer() { + if( errorTimer != null && errorTimer.isRunning() ){ + errorTimer.restart(); + } + } + + /** + * Notify about MemSpy Launcher S60 application version + * @param version in format "x", e.g "1". + */ + public void setMemSpyLauncherVersion(String version) { + String msg = "MemSpy Launcher data version: '" +version +"' detected in S60 target."; + DbgUtility.println(DbgUtility.PRIORITY_LOOP, msg); + MemSpyConsole.getInstance().println(msg); + + receivedMemSpyLauncherDataVersion = Integer.parseInt(version); + } + + /** + * Check if received MemSpy Launcher data version is at least required version + */ + private void checkMemSpyLauncherDataVersion() { + int requiredVersion = ProductInfoRegistry.getRequiredMemSpyLauncherDataVersion(); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Required MemSpy Launcher data version: " +requiredVersion); + if(requiredVersion > receivedMemSpyLauncherDataVersion){ + this.launcherError(LauncherErrorType.TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION); + } + } + + /** + * Get Heap Dump files that has been imported during SWMT logging. + * @return list about imported Heap Dumps. + */ + public ArrayList getImportedSWMTHeaps() { + return handler.getImportedSWMTHeaps(); + } + + /** + * Gets progress status for current wizard session with current connection settings. + * @return Progress status for current wizard session with current connection settings. + */ + public ProgressStatus getProgressStatus() { + return progressStatus; + } + + /** + * Sets progress status if there has been further progress after recent progress status update. + * @param progressStatus the progressStatus to set + */ + private void setProgressStatus(ProgressStatus progressStatus) { + if(progressStatus.ordinal() > this.progressStatus.ordinal()){ + this.progressStatus = progressStatus; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "setProgressStatus: " + this.progressStatus.name()); //$NON-NLS-1$ + } + } + + /** + * Resets progress status back into initial value. + */ + public void resetProgressStatus() { + this.progressStatus = ProgressStatus.EPROGRESS_INITIAL; + } + + /** + * Delegates launcher error info further without any additional information + * @param generalLauncherError launcher error occurred + */ + public void launcherError(LauncherErrorType launcherError) { + launcherError(launcherError, ""); + } + + /** + * Gets possible additional information related to occurred error. + * @return string containing additional information related to occurred error + */ + public String getAdditionalErrorInformation() { + return additionalErrorInformation; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyError(java.lang.String) + */ + public void notifyError(String message) { + // Currently only showing trace errors on console + MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_ERROR); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyInformation(java.lang.String) + */ + public void notifyInformation(String message) { + // Currently only showing trace informative messages on console + MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_NORMAL); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyWarning(java.lang.String) + */ + public void notifyWarning(String message) { + // Currently only showing trace warnings on console + MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_WARNING); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/UserEnteredData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/UserEnteredData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,373 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.model; + +import org.eclipse.jface.dialogs.IDialogSettings; + +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; + +/** + * This class is used to save and restore data which is entered by user in + * wizard pages. + * + */ +public class UserEnteredData { + + // sections names for each wizard page + private static final String SECTION_SELECT_ACTION = "SelectActionPage"; + private static final String SECTION_IMPORT_HEAP = "SelectDeviceOrFile"; + private static final String SECTION_COMPARE_HEAPS_FIRST = "CompareHeapsFirst"; + private static final String SECTION_COMPARE_HEAPS_SECOND = "CompareHeapsSecond"; + private static final String SECTION_DEFINE_OUTPUT = "OutputFile"; + private static final String SECTION_IMPORT_SWMT = "SWMT"; + private static final String SECTION_PARAMETER_FILES = "ParameterFiles"; + + + // Item key names. + private static final String PREVIOUS_RADIO_BUTTON_SELECTION = "PreviousRadioButtonSelection"; + private static final String PREVIOUS_IMPORTED_FILES = "PreviousFiles"; + private static final String PREVIOUS_INTERVAL = "Interval"; + + /** + * How many previously entered values are saved + */ + public static final int MAX_SAVED_VALUES = 5; + + + /** + * Enumeration for actions available + */ + public static enum ValueTypes { SELECT_ACTION, + IMPORT_HEAP, + COMPARE_HEAP_FIRST_HEAP, + COMPARE_HEAP_SECOND_HEAP, + SWMT, + OUTPUT_FILE} + + /** + * Returns previous radio button selection from given valuetype + * @param valueType what radio button selection is requested + * @return previous radio button selection + */ + public int getPreviousRadioButtonSelection( ValueTypes valueType) { + try { + int retval = 0; + + // Get int from that section where value is saved. + + switch(valueType){ + case SELECT_ACTION:{ + IDialogSettings section = getSection(SECTION_SELECT_ACTION); + if (section != null) { + retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION); + + } + break; + } + case IMPORT_HEAP:{ + IDialogSettings section = getSection(SECTION_IMPORT_HEAP); + if (section != null) { + retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION); + } + break; + } + case COMPARE_HEAP_FIRST_HEAP:{ + IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_FIRST); + if (section != null) { + retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION); + + } + break; + } + case COMPARE_HEAP_SECOND_HEAP:{ + IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_SECOND); + if (section != null) { + retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION); + + } + break; + } + case SWMT:{ + IDialogSettings section = getSection(SECTION_IMPORT_SWMT); + if (section != null) { + retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION); + + } + break; + } + default:{ + break; + } + } + return retval; + } catch (Exception e) { + return 0; + } + } + + /** + * Saves radio button selection into correct section + * @param valueType type of radio button + * @param value radio button value + */ + public void saveRadioButtonSelection(ValueTypes valueType, int value) { + try { + + // Save integer into correct section. + + switch(valueType){ + case SELECT_ACTION:{ + IDialogSettings section = getSection(SECTION_SELECT_ACTION); + if (section != null) { + section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value); + } + break; + } + case IMPORT_HEAP:{ + IDialogSettings section = getSection(SECTION_IMPORT_HEAP); + if (section != null) { + section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value); + } + break; + } + case COMPARE_HEAP_FIRST_HEAP:{ + IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_FIRST); + if (section != null) { + section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value); + } + break; + } + case COMPARE_HEAP_SECOND_HEAP:{ + IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_SECOND); + if (section != null) { + section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value); + } + + break; + } + case SWMT:{ + IDialogSettings section = getSection(SECTION_IMPORT_SWMT); + if (section != null) { + section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value); + } + break; + } + default:{ + break; + } + } + + + } catch (Exception E) { + // No actions needed + } + } + + /** + * Returns wanted section + * @param section name of the wanted section + * @return wanted section + */ + protected IDialogSettings getSection(String section) { + IDialogSettings retVal = null; + if (MemSpyPlugin.getDefault().getDialogSettings() != null) { + retVal = MemSpyPlugin.getDefault().getDialogSettings().getSection(section); + if (retVal == null) { + retVal = MemSpyPlugin.getDefault().getDialogSettings().addNewSection(section); + } + } + return retVal; + } + + + /** + * Returns values user has previously entered to wizard pages. + * @param valueType type of the values + * @return user's previous values + */ + public String[] getPreviousValues(ValueTypes valueType) { + try { + String[] retVal = null; + + // get value from correct section + switch (valueType) { + case IMPORT_HEAP: { + retVal = getPreviousPaths(SECTION_IMPORT_HEAP, PREVIOUS_IMPORTED_FILES); + break; + } + case COMPARE_HEAP_FIRST_HEAP: { + retVal = getPreviousPaths(SECTION_COMPARE_HEAPS_FIRST, PREVIOUS_IMPORTED_FILES); + break; + } + case COMPARE_HEAP_SECOND_HEAP: { + retVal = getPreviousPaths(SECTION_COMPARE_HEAPS_SECOND, PREVIOUS_IMPORTED_FILES); + break; + } + case OUTPUT_FILE:{ + retVal = getPreviousPaths(SECTION_DEFINE_OUTPUT, PREVIOUS_IMPORTED_FILES); + break; + } + case SWMT:{ + retVal = getPreviousPaths(SECTION_IMPORT_SWMT, PREVIOUS_INTERVAL); + break; + } + default:{ + break; + } + } + + return retVal; + } catch (Exception e) { + return null; + } + } + + /** + * Saves user's latest value. + * @param pathType value type + * @param value value to be saved + */ + public void saveValue(ValueTypes pathType, String value) { + if (value.trim().length() < 1) + return; + + try { + switch (pathType) { + case IMPORT_HEAP: { + savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_IMPORT_HEAP)); + break; + } + + case COMPARE_HEAP_FIRST_HEAP: { + savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_COMPARE_HEAPS_FIRST)); + + break; + } + case COMPARE_HEAP_SECOND_HEAP:{ + savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_COMPARE_HEAPS_SECOND)); + + break; + } + case OUTPUT_FILE:{ + savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_DEFINE_OUTPUT)); + break; + } + case SWMT:{ + savePath(value, PREVIOUS_INTERVAL, getSection(SECTION_IMPORT_SWMT)); + break; + } + default:{ + break; + } + } + } catch (Exception E) { + // No actions needed + } + } + + + /** + * Returns previously entered values of wanted context (i.e. wizard page). + * @param section section which contains array + * @param array name of the array whose values are needed + * @return previously entered paths of given section + */ + protected String[] getPreviousPaths(String section, String array) { + String[] retVal = null; + IDialogSettings sect = getSection(section); + if (sect != null) { + retVal = sect.getArray(array); + } + + return retVal; + } + + /** + * Saves given path to correct section in dialog_settings.xml + * @param path path to save + * @param array name of the array which contains correct values + * @param section section which has array + */ + protected void savePath(String path, String array, IDialogSettings section) { + if (section != null) { + String[] previousValues = section.getArray(array); + + // No previous values exist + if (previousValues == null) { + previousValues = new String[1]; + previousValues[0] = path; + // Previous values exists + } else { + int valuesCount = previousValues.length; + + boolean valueExisted = false; + // see if passed value already exist. + for (int i = 0; i < valuesCount; i++) { + if (previousValues[i].compareToIgnoreCase(path) == 0) { + valueExisted = true; + + // passed value exists, move it to first position + for (int j = i; j > 0; j--) { + previousValues[j] = previousValues[j-1]; + } + previousValues[0] = path; + + break; + } + } + + // passed value did not exist, add it to first position (and move older values "down") + if (!valueExisted) { + if (valuesCount >= MAX_SAVED_VALUES) { + for (int i = valuesCount-1; i > 0; i--) { + previousValues[i] = previousValues[i-1]; + } + previousValues[0] = path; + } else { + String[] values = new String[valuesCount + 1]; + values[0] = path; + for (int i = 0; i < valuesCount; i++) { + values[i+1] = previousValues[i]; + } + previousValues = values; + } + } + } + section.put(array, previousValues); + } + } + + + /** + * Get selections for dialog + * @return parameter files section + */ + public static IDialogSettings getParameterFilesSection() { + IDialogSettings retVal = null; + if (MemSpyPlugin.getDefault().getDialogSettings() != null) { + retVal = MemSpyPlugin.getDefault().getDialogSettings().getSection(SECTION_PARAMETER_FILES); + if (retVal == null) { + retVal = MemSpyPlugin.getDefault().getDialogSettings().addNewSection(SECTION_PARAMETER_FILES); + } + } + return retVal; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/plugin/MemSpyPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/plugin/MemSpyPlugin.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,363 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.plugin; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +import com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf; +import com.nokia.s60tools.memspy.export.ITraceDataProcessor; +import com.nokia.s60tools.memspy.export.ITraceProvider; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.util.debug.DbgUtility; + + +/** + * The activator class controls the plug-in life cycle. + */ +public class MemSpyPlugin extends AbstractUIPlugin { + + /** + * Plug-in ID for Launcher plug-in. + */ + public static final String MEMSPY_TRACE_PLUGIN_ID = "com.nokia.s60tools.memspy.trace";//$NON-NLS-1$ + /** + * Launcher plug-in binaries directory name. + */ + public static final String LAUNCHER_BINARIES_DIR_NAME = "Launcher.binaries";//$NON-NLS-1$ + + /** + * Trace provider extension name. + */ + final String EXTENSION_TRACE_PROVIDER = "traceprovider"; //$NON-NLS-1$ + + /** + * Plug-in ID constant. + */ + public static final String PLUGIN_ID = "com.nokia.s60tools.memspy"; + + /** + * Member for storing plug-in install path. + */ + private String pluginInstallPath = ""; + + /** + * Shared plug-in instance + */ + private static MemSpyPlugin plugin; + + /** + * Storing reference to possibly installed trace provider plug-in. + */ + private static ITraceProvider traceProvider; + + /** + * Preferences store instance reference. + */ + private static IPreferenceStore prefsStore; + + /** + * SWMT category setting feature is enabled by default, but may be disabled in case device does not support it. + */ + boolean isSWMTCategorySettingFeatureEnabled = true; + + /** + * The constructor + */ + public MemSpyPlugin() { + plugin = this; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + String pluginInstallLocation = getPluginInstallPath(); + String imagesPath = getImagesPath(pluginInstallLocation); + + // Loading images required by this plug-in + ImageResourceManager.loadImages(imagesPath); + + // Getting installed trace provider plug-in if available + traceProvider = findTraceProviderExtension(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static MemSpyPlugin getDefault() { + return plugin; + } + + /** + * Get plugin installation path + * @return the path where this plugin is installed + */ + public static String getPluginInstallPath() { + try { + if ( plugin.pluginInstallPath.equals("") ) { //$NON-NLS-1$ + // URL to the plugin's root ("/") + URL relativeURL = plugin.getBundle().getEntry("/"); //$NON-NLS-1$ + // Converting into local path + URL localURL = FileLocator.toFileURL(relativeURL); + // Getting install location in correct form + File f = new File(localURL.getPath()); + plugin.pluginInstallPath = f.getAbsolutePath(); + } + return plugin.pluginInstallPath; + } catch (Exception e) { + return ""; //$NON-NLS-1$ + } + } + + /** + * Gets images path relative to given plugin install path. + * @param pluginInstallPath Plugin installation path. + * @return Path were image resources are located. + * @throws IOException + */ + private String getImagesPath(String pluginInstallPath) throws IOException{ + return pluginInstallPath + + File.separatorChar + "icons"; //$NON-NLS-1$ + } + + /** + * This must be called from UI thread. If called + * from non-ui thread this returns null. + * @return Currently active workbench page. + */ + public static IWorkbenchPage getCurrentlyActivePage(){ + return getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); + } + + /** + * This must be called from UI thread. If called + * from non-UI thread this returns null. + * @return The shell of the currently active workbench window.. + */ + public static Shell getCurrentlyActiveWbWindowShell(){ + IWorkbenchPage page = getCurrentlyActivePage(); + if(page != null){ + return page.getWorkbenchWindow().getShell(); + } + return null; + } + + /** + * Checks if SWMT category setting feature is enabled. + * @return true if enabled, otherwise false. + */ + public boolean isSWMTCategorySettingFeatureEnabled() { + return isSWMTCategorySettingFeatureEnabled; + } + + /** + * Sets if SWMT category setting feature is enabled. + * @param isSWMTCategorySettingFeatureEnabled true if enabled, otherwise false. + */ + public void setSWMTCategorySettingFeatureEnabled( + boolean isSWMTCategorySettingFeatureEnabled) { + this.isSWMTCategorySettingFeatureEnabled = isSWMTCategorySettingFeatureEnabled; + } + + /** + * Gets MemSpy Launcher plugin's binaries directory path + * @return path were Launcher binaries are located. + */ + public String getMemspyLauncherBinDir(){ + + Bundle bundle = Platform + .getBundle(MEMSPY_TRACE_PLUGIN_ID); //$NON-NLS-1$ + + String launcherBinDir = null; + try { + // URL to the Launcher binaries + URL relativeURL = bundle.getEntry(LAUNCHER_BINARIES_DIR_NAME); //$NON-NLS-1$ + // Converting into local path + URL localURL = FileLocator.toFileURL(relativeURL); + // Getting install location in correct form + File file = new File(localURL.getPath()); + launcherBinDir = file.getAbsolutePath(); + MemSpyConsole.getInstance().println("MemSpyLauncher binaries dir detected: " +launcherBinDir); + + } catch (IOException e) { + MemSpyConsole.getInstance().println("MemSpyLauncher binaries dir detection failed, reason: " +e); + e.printStackTrace(); + } + return launcherBinDir; + + } + + /** + * Returns PreferenceStore where plugin preferences are stored. + * @return PreferenceStore where plugin preferences are stored + */ + public static IPreferenceStore getPrefsStore() { + if (prefsStore == null){ + prefsStore = getDefault().getPreferenceStore(); + } + + return prefsStore; + } + + /** + * Gets trace provider interface instance if available. + * @return trace provider interface instance or null if not available + */ + public static ITraceProvider getTraceProvider(){ + if(isTraceProviderAvailable()){ + return traceProvider; + } + // Otherwise returning a dummy provider instance + return createDummyTraceProviderInstance(); + } + + /** + * Creates a dummy trace provider instance. + * Client can safely reference to this dummy instance without any NullPointerException + * problems etc. However the corresponding functionalities from UI should be disables. + * @return dummy trace provider instance. + */ + private static ITraceProvider createDummyTraceProviderInstance() { + // Creating just a dummy provider instance that does not do anything + return new ITraceProvider() { + + public void stopListenTraceData() { + // dummy provider does not take any actions + } + + public boolean startListenTraceData(ITraceDataProcessor dataProcessor) { + // dummy provider does not take any actions + return false; + } + + public boolean sendStringData(String stringData) { + // dummy provider does not take any actions + return false; + } + + public boolean sendIntData(int integerData) { + // dummy provider does not take any actions + return false; + } + + public String getTraceSourcePreferencePageId() { + // dummy provider does not take any actions + return null; + } + + public String getDisplayNameForCurrentConnection() { + return ""; + } + + public void disconnectTraceSource() { + // dummy provider does not take any actions + } + + public boolean connectTraceSource( + ITraceClientNotificationsIf traceClient) { + // dummy provider does not take any actions + return false; + } + + public boolean activateTrace(String traceGroupID) { + // dummy provider does not take any actions + return false; + } + + }; + } + + /** + * Checks if trace provider plug-in is available. + * @return true if trace provider interface available, otherwise false + */ + public static boolean isTraceProviderAvailable(){ + return (traceProvider != null); + } + + /** + * Tries to find trace provider plug-ins. Selecting the first found one. + * @return reference to trace provider instance if found, otherwise null + */ + ITraceProvider findTraceProviderExtension() { + try { + IExtensionRegistry er = Platform.getExtensionRegistry(); + IExtensionPoint ep = er.getExtensionPoint(PLUGIN_ID, EXTENSION_TRACE_PROVIDER); + String uniqueIdentifier = ep.getUniqueIdentifier(); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Found extension point: " + uniqueIdentifier); //$NON-NLS-1$ + IExtension[] extensions = ep.getExtensions(); + + // if plug-ins were found. + if (extensions != null && extensions.length > 0) { + + // read all found trace providers + for (int i = 0; i < extensions.length; i++) { + IConfigurationElement[] ce = extensions[i].getConfigurationElements(); + if (ce != null && ce.length > 0) { + try { + ITraceProvider provider = (ITraceProvider)ce[0].createExecutableExtension("class"); //$NON-NLS-1$ + // We support only one trace provider + if (provider != null) { + return provider; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceConstants.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.preferences; + + +/** + * Class for storing keys to preferences. + */ +public class MemSpyPreferenceConstants { + + /** + * preference DB key for SWMT Category Setting + */ + public static final String SWMT_CATEGORY_SETTING = "SWMTCategorySetting"; //$NON-NLS-1$ + + /** + * preference DB key for SWMT Category Setting + */ + public static final String SWMT_CATEGORY_SETTINGS_CUSTOM = "SWMTCategorySettingsCustom"; //$NON-NLS-1$ + + /** + * preference DB key for SWMT Category Setting + */ + public static final String SWMT_CATEGORY_SETTING_PROFILE_SELECTED = "SWMTCategorySettingProfileSelected"; //$NON-NLS-1$ + + /** + * preference DB key for SWMT Heap Dump selection + */ + public static final String SWMT_HEAP_DUMP_SELECTED = "SWMTHeapDumpSelected"; //$NON-NLS-1$ + + /** + * preference DB key for SWMT Heap filter Setting + */ + public static final String SWMT_HEAPFILTER_SETTING = "SWMTHeapFilter"; //$NON-NLS-1$ + + /** + * preference DB key for closing S60 device between cycles + */ + public static final String CLOSE_BETWEEN_CYCLES = "CloseS60DeviceBetweenCycles";//$NON-NLS-1$ + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceInitializer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceInitializer.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.preferences; + + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; + +import com.nokia.s60tools.memspy.model.SWMTCategoryConstants; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; + +/** + * Class used to initialize default preference values. + */ +public class MemSpyPreferenceInitializer extends AbstractPreferenceInitializer { + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences() + */ + public void initializeDefaultPreferences() { + + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM, SWMTCategoryConstants.PROFILE_BASIC); + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING, SWMTCategoryConstants.PROFILE_BASIC); + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED, true); + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING, ""); + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED, false); + MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES, true); + + } +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferences.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferences.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.preferences; + +import org.eclipse.jface.preference.IPreferenceStore; + +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; + +/** + * Helper class to use Dependency Explorer preferences. Use this class for accessing DE preferences + * instead of accessing directly through {@link org.eclipse.jface.util.IPropertyChangeListener.IPreferenceStore}. + */ +public class MemSpyPreferences { + + + /** + * Gets SWMT category settings for this session. + * @return SWMT category settings for this session + */ + public static int getSWMTCategorySetting() { + + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + + boolean isProfileSelected = store.getBoolean(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED); + int value; + if(isProfileSelected){ + value = getSWMTCategorySettingForProfile(); + }else{ + value = store.getInt(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM); + } + return value ; + } + + /** + * Gets SWMT category settings for Profile selection. + * @return SWMT category settings for profile + */ + public static int getSWMTCategorySettingForProfile() { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + return store.getInt(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING); + } + + /** + * Sets SWMT category settings for this session. + * @param sessionSpecificSWMTCategorySetting SWMT category settings to set for this session + */ + public static void setSWMTCategorySetting(int sessionSpecificSWMTCategorySetting, boolean isProfileSettings) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + setProfileTrackedCategoriesSelected(isProfileSettings); + if(isProfileSettings){ + store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING, sessionSpecificSWMTCategorySetting); + }else{ + store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM, sessionSpecificSWMTCategorySetting); + } + } + + + /** + * Sets SWMT category settings for this session. + * @param sessionSpecificSWMTCategorySetting SWMT category settings to set for this session + */ + public static void setProfileTrackedCategoriesSelected(boolean isAllCategoriesSelected) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED, isAllCategoriesSelected); + } + + /** + * Get if All Tracke Categories is selected. + * @param true if All is selected false otherwise. + */ + public static boolean isProfileTrackedCategoriesSelected() { + + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + boolean isAllSelected = store.getBoolean(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED); + return isAllSelected; + + } + + /** + * Sets the SWMT Heap Dump selection on/off + * @param selection + */ + public static void setSWMTHeapDumpSelected(boolean selection) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + store.setValue(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED, selection); + } + + /** + * Gets the SWMT Heap Dump selection + * @param true if Heap Dumps should receive with SWMT logging, false otherwise. + */ + public static boolean isSWMTHeapDumpSelected( ) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + return store.getBoolean(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED); + } + + /** + * Gets SWMT category settings for this session. + * @return SWMT HeapNameFilter setting for this session. + */ + public static String getSWMTHeapNameFilter() { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + String filter = store.getString(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING); + return filter; + } + + /** + * Sets SWMT HeapNameFilter setting for this session. + * @param heapNameFilter SWMT HeapNameFilter settings to set for this session. + */ + public static void setSWMTHeapNameFilter(String heapNameFilter) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + store.setValue(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING, heapNameFilter); + } + + /** + * Sets the user selection if S60 device is closed between cycles + * @param selection + */ + public static void setCloseSymbianAgentBetweenCycles(boolean selection) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + store.setValue(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES, selection); + } + + /** + * Gets the user selection if S60 device is closed between cycles + * @param true if S60 Device is about to close between cycles, false otherwise. + */ + public static boolean isCloseSymbianAgentBetweenCyclesSelected( ) { + IPreferenceStore store = MemSpyPlugin.getPrefsStore(); + return store.getBoolean(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/HelpContextIDs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/HelpContextIDs.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.resources; + +/** + * IDs for context sensitive help. + * @see contexts.xml -file IDs links to + */ +public class HelpContextIDs { + + /** + * The plug-in ID. + */ + private static final String MEMSPY_HELP_PROJECT_PLUGIN_ID = "com.nokia.s60tools.memspy.help"; + + // + // ID's to MemSpy Help TOC + // + + /** + * Id to Importing and analyzing heap dump files + */ + public static final String MEMSPY_IMPORT_HEAP = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_HEAP"; + + /** + * Id to MemSpy Main View + */ + public static final String MEMSPY_MAIN_VIEW = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_MAIN_VIEW"; + + /** + * Id to MemSpy Tasks + */ + public static final String MEMSPY_SELECT_ACTION = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SELECT_ACTION"; + + /** + * Id to Symbol and Map files + */ + public static final String MEMSPY_IMPORT_SYMBOLS = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SYMBOLS"; + + /** + * Id to Importing and comparing two heap dump files + */ + public static final String MEMSPY_IMPORT_COMPARE = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_COMPARE"; + + /** + * Id to Importing and analyzing System Wide Memory Tracking log files + */ + public static final String MEMSPY_IMPORT_SWMT = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SWMT"; + + /** + * Id to Setting System Wide Memory Tracking tracked categories + */ + public static final String MEMSPY_IMPORT_SWMT_CATEGORIES_DIALOG = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SWMT_CATEGORIES_DIALOG"; + + /** + * Id to Configuring connection settings + */ + public static final String MEMSPY_IMPORT_CONNECTION_SETTINGS = + MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_CONNECTION_SETTINGS"; + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageKeys.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageKeys.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.resources; + +/** + * Keys to images with in application + */ +public class ImageKeys { + /** + * ID to MemSpy application icon + */ + public static final String IMG_APP_ICON = "MEMSPY_IMG_APP_ICON"; + /** + * ID to launch Heap Analyser icon + */ + public static final String IMG_ANALYZE_HEAP = "MEMSPY_IMG_ANALYZE_HEAP"; + /** + * ID to compare two heaps icon + */ + public static final String IMG_COMPARE_2_HEAP = "MEMSPY_IMG_COMPARE_2_HEAP"; + /** + * ID to export to HTML icon + */ + public static final String IMG_EXPORT_TO_HTML = "MEMSPY_IMG_EXPORT_TO_HTML"; + /** + * ID to Launch SWMT icon + */ + public static final String IMG_LAUNCH_SWMT = "MEMSPY_IMG_LAUNCH_SWMT"; + /** + * ID to Heap Dump icon + */ + public static final String IMG_HEAP_DUMP = "MEMSPY_IMG_HEAP_DUMP"; + /** + * ID to SWMT icon + */ + public static final String IMG_SWMT_LOG = "MEMSPY_IMG_SWMT_LOG"; + /** + * ID to Wizard icon + */ + public static final String IMG_WIZARD = "MEMSPY_IMG_WIZARD"; + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageResourceManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageResourceManager.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.resources; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + + +/** + * Class for handling MemSpy icons. + * + */ +public class ImageResourceManager { + + /** + * Load images + * @param imagesPath + */ + public static void loadImages(String imagesPath){ + + Display disp = Display.getCurrent(); + + ImageRegistry imgReg = JFaceResources.getImageRegistry(); + + // + // Storing images to image registry + // + Image img = new Image( disp, imagesPath + "\\memspy_16.png" ); + imgReg.put( ImageKeys.IMG_APP_ICON, img ); + + img = new Image( disp, imagesPath + "\\Launch_SWMT.png" ); + imgReg.put( ImageKeys.IMG_LAUNCH_SWMT, img ); + + img = new Image( disp, imagesPath + "\\Export_To_html.png" ); + imgReg.put( ImageKeys.IMG_EXPORT_TO_HTML, img ); + + img = new Image( disp, imagesPath + "\\Compare_2_Heaps.png" ); + imgReg.put( ImageKeys.IMG_COMPARE_2_HEAP, img ); + + img = new Image( disp, imagesPath + "\\Analyse_Heap.png" ); + imgReg.put( ImageKeys.IMG_ANALYZE_HEAP, img ); + + img = new Image( disp, imagesPath + "\\Launch_SWMT.png" ); + imgReg.put( ImageKeys.IMG_SWMT_LOG, img ); + + img = new Image( disp, imagesPath + "\\Analyse_Heap.png" ); + imgReg.put( ImageKeys.IMG_HEAP_DUMP, img ); + + img = new Image( disp, imagesPath + "\\Memspy_45.png" ); + imgReg.put( ImageKeys.IMG_WIZARD, img ); + + } + + public static ImageDescriptor getImageDescriptor( String key ){ + ImageRegistry imgReg = JFaceResources.getImageRegistry(); + return imgReg.getDescriptor( key ); + } + + public static Image getImage( String key ){ + ImageRegistry imgReg = JFaceResources.getImageRegistry(); + return imgReg.get(key); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/UiUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/UiUtils.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,255 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.ui; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType; +import com.nokia.s60tools.memspy.model.TraceCoreEngine.ProgressStatus; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Static UI utility methods that are needed more than one place + * are located here in order to prevent code duplication. + */ +public class UiUtils { + + + /** + * Launcher SIS file name + */ + private static final String MEM_SPY_LAUNCHER_S60_50_RN_D_SIGNED_SIS_FILE_NAME = "MemSpyLauncher_S60-50_RnD-signed.sis"; + + /** + * Shows error dialog that gives error context related information and guidance. + * E.g. Advises user to install launcher component to the device if it is needed. + * @param error Launcher error encountered + * @param errorMessage Error message to be shown to user + * @param progressStatus + */ + public static void showErrorDialogToUser(final LauncherErrorType error, final String errorMessage, final ProgressStatus progressStatus) { + + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + + // If no answer from device received, display dialog that allows user to install MemSpy Launcher. + if( error == LauncherErrorType.NO_ANSWER_FROM_DEVICE || error == LauncherErrorType.TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION ){ + + switch (progressStatus) { + // Flow through on purpose 1 + case EPROGRESS_MEMSPY_LAUNCHED: // MemSpy is launched but not yet actual task + case EPROGRESS_FIRST_TASK_LAUNCHED: // MemSpy is launched and also 1st real task is done + case EPROGRESS_FIRST_TASK_DONE: // Trace data has been received successfully at least once + showStandardErrorMessageDialog(errorMessage); + break; + // Flow through on purpose 2 + case EPROGRESS_INITIAL: // MemSpy has not been launched successfully, so no progress at all + default: + adviceUserToInstallLauncherComponent(errorMessage); + break; + } + } + else{ + showStandardErrorMessageDialog(errorMessage); + } + + } + + }; + + Display.getDefault().asyncExec(updateUiRunnable); + } + + /** + * Shows standard eclipse error dialog with given error message + * @param errorMessage error message + */ + private static void showStandardErrorMessageDialog(String errorMessage) { + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, errorMessage, null); + // Display the dialog + ErrorDialog.openError(Display.getCurrent().getActiveShell(),IMemSpyTraceListener.ERROR_MEMSPY, null, status); + } + + /** + * Advises used to install MemSpy launcher component and provides necessary action alternatives. + * @param errorMessage error message + */ + private static void adviceUserToInstallLauncherComponent(final String errorMessage) { + + MessageDialog dialog = new MessageDialog( Display.getCurrent().getActiveShell(), + IMemSpyTraceListener.ERROR_MEMSPY, null, errorMessage, MessageDialog.ERROR, + new String[]{ "Install RnD-signed MemSpy Launcher", "Open sis-file's directory in Explorer", "Don't install" }, 1); + dialog.open(); + + String launcherFolder = MemSpyPlugin.getDefault().getMemspyLauncherBinDir(); + String launcherLocation = launcherFolder + File.separatorChar + MEM_SPY_LAUNCHER_S60_50_RN_D_SIGNED_SIS_FILE_NAME; + + // if user wants to install launcher: + if( dialog.getReturnCode() == 0 ){ + // find program for xls-filetype + Program p=Program.findProgram(".sis"); + // if found, launch it. + if(p!=null){ + // Check that found program was Nokia PC Suite. + p.execute( launcherLocation ); + } + else{ + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, + "Unable to locate PC suite or other suitable software for installing .sis -file from computer. You can try installing MemSpy launcher manually from:\n" + + launcherLocation, null); + ErrorDialog.openError(Display.getCurrent().getActiveShell(),"MemSpy Error", null, status); + } + + } + + // Open directory in explorer + else if( dialog.getReturnCode() == 1 ){ + try { + String directory = Platform.getConfigurationLocation().getURL().getFile(); + directory = directory.substring(1); + Runtime.getRuntime().exec("explorer " + launcherFolder); + } catch (IOException e) { + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "Unable to open Explorer", null); + ErrorDialog.openError(Display.getCurrent().getActiveShell(),IMemSpyTraceListener.ERROR_MEMSPY, null, status); + e.printStackTrace(); + } + } + + } + + /** + * Maps given launcher error to corresponding error message. + * @param error error enumerator + * @param clientContextString client context string for giving usage context info. Used only for possible console logging. + * @param progressStatus current progress status for giving extra information on the possible error condition. + * @return error message string + */ + public static String getErrorMessageForLauncherError(LauncherErrorType error, String clientContextString, ProgressStatus progressStatus) { + + String errorMessage; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getErrorMessageForLauncherError/progressStatus: " + progressStatus); //$NON-NLS-1$ + + switch (error){ + case NO_ANSWER_FROM_DEVICE:{ + errorMessage = getErrorDescriptionForNoAnswerFromDeviceError(progressStatus, clientContextString); + break; + } + case MEMSPY_NOT_RUNNING:{ + errorMessage = IMemSpyTraceListener.ERROR_MEMSPY_NOT_RUNNING; + break; + } + case MEMSPY_NOT_FOUND:{ + errorMessage = IMemSpyTraceListener.ERROR_MEMSPY_NOT_FOUND; + break; + } + case ACTIVATION:{ + errorMessage = IMemSpyTraceListener.ERROR_ACTIVATION_NOT_SUCCESFUL; + break; + } + case FILE:{ + errorMessage = IMemSpyTraceListener.ERROR_FILE_OPERATIONS_NOT_SUCCESSFUL; + break; + } + case TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION:{ + errorMessage = IMemSpyTraceListener.ERROR_TOO_OLD_MEMSPY_LAUNCHER_VERSION; + break; + } + case DUMPED_TRACES:{ + errorMessage = IMemSpyTraceListener.ERROR_DUMPED_TRACES; + break; + } + case CATEGORIES_NOT_SUPPORTED:{ + errorMessage = IMemSpyTraceListener.ERROR_CATEGORIES_NOT_SUPPORTED; + break; + } + case GENERAL_LAUNCHER_ERROR:{ + errorMessage = IMemSpyTraceListener.ERROR_GENERAL_LAUNCHER_ERROR; + break; + } + // default handling in case new launcher error has been added but not handled appropriately + default:{ + MemSpyConsole.getInstance().println(clientContextString + " error: '" //$NON-NLS-1$ + + error.name() + "' occurrence." //$NON-NLS-1$ + , MemSpyConsole.MSG_ERROR); //$NON-NLS-1$ + errorMessage = IMemSpyTraceListener.ERROR_ACTIVATION_NOT_SUCCESFUL; + break; + } + } + + return errorMessage; + } + + /** + * Forms error description in no answer from device error situation. + * @param progressStatus progress status at the moment when error occurred. + * @param clientContextString Possibly more context-specific information + * @return + */ + private static String getErrorDescriptionForNoAnswerFromDeviceError(ProgressStatus progressStatus, String clientContextString) { + + // Default message start portion + String errorMessage = IMemSpyTraceListener.ERROR_NO_RESPONSE + " " + IMemSpyTraceListener.ERROR_POSSIBLE_REASONS; + + switch (progressStatus) { + + // Flow through on purpose 1 + case EPROGRESS_MEMSPY_LAUNCHED: // MemSpy is launched but not yet actual task + case EPROGRESS_FIRST_TASK_DONE: // Trace data has been received successfully at least once + case EPROGRESS_FIRST_TASK_LAUNCHED: // MemSpy is launched and also 1st real task is done + // add USB error note. + errorMessage = errorMessage + IMemSpyTraceListener.ERROR_USB_TRACE_ENABLED; + // add check for connection information message + errorMessage = errorMessage + IMemSpyTraceListener.ERROR_CONNECTION_BROKEN; + break; + + // Flow through on purpose 2 + case EPROGRESS_INITIAL: // MemSpy has not been launched successfully, so no progress at all + default: + errorMessage = IMemSpyTraceListener.ERROR_NO_RESPONSE + " " + IMemSpyTraceListener.ERROR_POSSIBLE_REASONS; + // add USB error note. + errorMessage = errorMessage + IMemSpyTraceListener.ERROR_USB_TRACE_ENABLED; + // add install note for MemSpy Launcher + errorMessage = errorMessage + IMemSpyTraceListener.ERROR_INSTALL_MEMSPY_LAUNCHER; + break; + } + + if(clientContextString.length() > 0){ + MemSpyConsole.getInstance().println(IMemSpyTraceListener.ERROR_NO_RESPONSE + + IMemSpyTraceListener.ERROR_LAUNCHER_ERROR_DETAILS + clientContextString //$NON-NLS-1$ + , MemSpyConsole.MSG_ERROR); + errorMessage = errorMessage + IMemSpyTraceListener.ERROR_SEE_CONSOLE_LOG; + } + + return errorMessage; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/actions/ToolbarShortcutAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/actions/ToolbarShortcutAction.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +import com.nokia.s60tools.memspy.ui.views.MemSpyMainView; +import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard.MemSpyWizardType; +import com.nokia.s60tools.util.debug.DbgUtility; + + + + + +/** + * Action for toolbar and import shortcuts that launch MemSpy + * @see IWorkbenchWindowActionDelegate + */ +public class ToolbarShortcutAction implements IWorkbenchWindowActionDelegate { + + /** + * The action has been activated. The argument of the + * method represents the 'real' action sitting + * in the workbench UI. + * @see IWorkbenchWindowActionDelegate#run + */ + public void run(IAction action) { + // Open MemSpy's Main View + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Show main view"); + MemSpyMainView mainView = MemSpyMainView.showAndReturnYourself(); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Run wizard"); + mainView.runWizard( MemSpyWizardType.FULL, null ); + + } + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) { + // Not needed + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + // Not needed + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) { + // Not needed + } +} \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoriesDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoriesDialog.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,679 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.ui.dialogs; + +import java.util.ArrayList; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.memspy.model.SWMTCategoryConstants; +import com.nokia.s60tools.memspy.model.SWMTCategorys; +import com.nokia.s60tools.memspy.preferences.MemSpyPreferences; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.memspy.resources.ImageKeys; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.ui.S60ToolsTable; +import com.nokia.s60tools.ui.S60ToolsTableColumnData; +import com.nokia.s60tools.ui.S60ToolsTableFactory; +import com.nokia.s60tools.ui.S60ToolsUIConstants; + + + +/** + * Dialog for selecting SWMT categories to be tracked. + */ +public class SWMTCategoriesDialog extends TitleAreaDialog{ + + + + // + // Private classes + // + + private static final String HEAP_DATA_THREAD_FILTER_TXT = "Heap Data Thread Filter"; + + /** + * Label provider for table viewer component. + */ + class SWMTCategoryViewerLabelProvider extends LabelProvider implements ITableLabelProvider{ + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) + */ + public Image getColumnImage(Object element, int columnIndex) { + return null; // No images used + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) + */ + public String getColumnText(Object element, int columnIndex) { + String label = element.toString(); + + SWMTCategoryEntry entryData = (SWMTCategoryEntry) element; + + switch (columnIndex) { + + case SWMTCategoryEntry.NAME_COLUMN_INDEX: + label = entryData.getCategoryName(); + break; + + default: + MemSpyConsole.getInstance().println("Unexpected column index: " + columnIndex, MemSpyConsole.MSG_ERROR); //$NON-NLS-1$ //$NON-NLS-2$ + break; + } + + return label; + } + + } + + // + // Private constants + // + + /** + * Columns in the container area. + */ + private static final int COLUMN_COUNT = 1; + + /** + * Dialog width. + */ + private static final int DIALOG_WIDTH = 425; + + /** + * Dialog height. + */ + private static final int DIALOG_HEIGHT = 550; + + /** + * Percentage as decimal number how much table viewer is taking space horizontally. + */ + private static final double TABLE_VIEWER_WIDTH_PERCENTAGE = 0.8; + + /** + * Default guiding message shown to the user in add new mode. + */ + private static final String DEFAULT_MESSAGE = "Set advanced options and tracked SWMT categories."; + + /** + * Complete message shown to the user in add new mode. + */ + private static final String COMPLETE_MESSAGE = "Press OK to save advanced options and set categories to be tracked"; + + /** + * Error message shown to the user in case no categories are selected. + */ + private static final String ERROR_MESSAGE = "At least single category must be selected"; + + /** + * UI text for closing Symbian agent + */ + private static final String CLOSE_MEM_SPY_BETWEEN_CYCLES_TEXT = "Close MemSpy Symbian Agent Between Cycles"; + + /** + * Tip text for closing Symbian agent + */ + private static final String CLOSE_MEM_SPY_BETWEEN_CYCLES_TIP_TEXT = "Choose if the MemSpy Symbian agent in S60 target is closed between cycles. That is more realistic use case for memory usage point of view."; + + + // + // Member data + // + + /** + * Flag used to make sure that create() and open() are called in correct order. + */ + private boolean isCreateCalled = false; + + + // + // UI Controls + // + + /** + * Container area for individual fields for the user for entering information. + */ + private Composite container; + + /** + * Reference to OK button that can be disabled/enabled + * due to current category selection- + */ + private Button okActionBtn; + + /** + * Viewer showing currently selected category file entries. + */ + private CheckboxTableViewer categoryViewer; + + /** + * Selected categories as a result of bitwise OR. + */ + private int categorySelection = SWMTCategoryConstants.CATEGORY_ALL; + + //User Heap filter text field + private Text heapText; + + private Button closeBetweenCyclesButton; + + private Button heapDumpBtn; + + /** + * Constructor. Used to open dialog in order to add new entry. + * @param parentShell Parent shell for the dialog. + * @param categorySelection integer containing initially selected categories as a result of bitwise OR. + */ + public SWMTCategoriesDialog(Shell parentShell, int categorySelection) { + super(parentShell); + this.categorySelection = categorySelection; + // Setting banner image + String bannerImage = ImageKeys.IMG_WIZARD; + setTitleImage(ImageResourceManager.getImage(bannerImage)); + } + + + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) + */ + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, + true); + okActionBtn = getButton(IDialogConstants.OK_ID); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("SWMT Categories and Advanced Options"); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + + Composite dialogAreaComposite = (Composite) super.createDialogArea(parent); + + // + // Creating container and layout for it + // + container = new Composite(dialogAreaComposite, SWT.NONE); + GridLayout gdl = new GridLayout(COLUMN_COUNT, false); + // Settings margins according Carbide branding guideline + gdl.marginLeft = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS; + gdl.marginRight = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS; + gdl.marginTop = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS; + gdl.marginBottom = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS; + container.setLayout(gdl); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // + // Symbian agent options group + // + + createSymbianAgentOptionsGroup(); + + // + // Head dump group + // + createHeapDumpGroup(); + + + // + // Creating table viewer for showing category file entries + // + + categoryViewer = createCategoryCheckBoxTableViewer(container); + GridData categoryViewerGd = new GridData(GridData.FILL_BOTH); + // Spanning as many rows as there are actions buttons on the right + categoryViewerGd.verticalSpan = 3; + categoryViewerGd.widthHint = (int) (TABLE_VIEWER_WIDTH_PERCENTAGE * DIALOG_WIDTH); + categoryViewer.getControl().setLayoutData(categoryViewerGd); + categoryViewer.setSorter(new SWMTCategoryEntryTableViewerSorter()); + // Adding selection change listener + categoryViewer.addSelectionChangedListener(new ISelectionChangedListener(){ + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + notifySelectionChanged(); + } + + }); + + // + // Setting providers for table viewer + // + + // Creating content provider + GategoryProvider categoryViewerContentProvider = new GategoryProvider(); + // Setting content provider + categoryViewer.setContentProvider(categoryViewerContentProvider); + categoryViewer.setInput(categoryViewerContentProvider); + + // Label provider + categoryViewer.setLabelProvider(new SWMTCategoryViewerLabelProvider()); + + // Setting initial category selection state + InitializeSelectionState(); + + // Setting context-sensitive help ID + PlatformUI.getWorkbench().getHelpSystem().setHelp( dialogAreaComposite, HelpContextIDs.MEMSPY_IMPORT_SWMT_CATEGORIES_DIALOG); + + // Dialog are composite ready + return dialogAreaComposite; + } + + + /** + * Private class to provide content for category viewer + */ + class GategoryProvider implements IStructuredContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return SWMTCategorys.getInstance().getCategoryEntries().toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + // Not needed but needs to be implemented + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + // Not used but needs to be implemented + } + + }; + + /** + * Creates group for Symbian agent options + */ + private void createSymbianAgentOptionsGroup() { + Group closeSymbianGroup = new Group(container, SWT.SHADOW_NONE); + closeSymbianGroup.setText("Symbian Agent Options"); + GridLayout closegl = new GridLayout(2, false); + GridData closegd = new GridData(GridData.FILL_BOTH); + closeSymbianGroup.setLayout(closegl); + closeSymbianGroup.setLayoutData(closegd); + + closeBetweenCyclesButton = new Button(closeSymbianGroup, SWT.CHECK); + GridData closeLayoutData = new GridData(GridData.VERTICAL_ALIGN_END); + closeBetweenCyclesButton.setLayoutData( closeLayoutData); + closeBetweenCyclesButton.setToolTipText(CLOSE_MEM_SPY_BETWEEN_CYCLES_TIP_TEXT); + boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected(); + closeBetweenCyclesButton.setSelection(isToBeClosedBetweenCycles); + + //Label for button, separate label is used because setting text to button wont align text to same vertical + //position than next label. + Label closeBetweenIntervalsLabel = new Label(closeSymbianGroup, SWT.LEFT ); + GridData closeBetweenLabelData = new GridData(GridData.VERTICAL_ALIGN_CENTER); + closeBetweenIntervalsLabel.setText( CLOSE_MEM_SPY_BETWEEN_CYCLES_TEXT ); + closeBetweenIntervalsLabel.setLayoutData(closeBetweenLabelData); + + } + + + /** + * Creates group for Head Dumps + */ + private void createHeapDumpGroup() { + // + // Head dump group + // + Group headDumpGroup = new Group(container, SWT.SHADOW_NONE); + headDumpGroup.setText("Heap Dumps During SWMT Logging"); + GridLayout hdgl = new GridLayout(2, false); + GridData hdgd = new GridData(GridData.FILL_BOTH); + headDumpGroup.setLayout(hdgl); + headDumpGroup.setLayoutData(hdgd); + + heapDumpBtn = new Button(headDumpGroup, SWT.CHECK); + heapDumpBtn.setText("Get Heap Dumps for Threads to Analyse with Heap Analyser"); + heapDumpBtn.setToolTipText("Set if Heap Dumps is to be received for Threads during SWMT logging"); + heapDumpBtn.addSelectionListener(new HeadDumpSelectionListener()); + heapDumpBtn.setSelection(MemSpyPreferences.isSWMTHeapDumpSelected()); + GridData hdBtnGd = new GridData(); + hdBtnGd.horizontalSpan = 2; + heapDumpBtn.setLayoutData(hdBtnGd); + + //Label for Heap gategory limit + Label heapTextLabel = new Label(headDumpGroup, SWT.LEFT ); + heapTextLabel.setText(HEAP_DATA_THREAD_FILTER_TXT + ":"); + String heapFilterToolTipText = "When filter string is specified, only Threads that contain text specified will be tracked."; + heapTextLabel.setToolTipText(heapFilterToolTipText); + GridData heapTextLimitLayoutData = new GridData(GridData.VERTICAL_ALIGN_CENTER); + heapTextLabel.setLayoutData( heapTextLimitLayoutData ); + + //heap limit text + heapText = new Text(headDumpGroup, SWT.LEFT | SWT.BORDER | SWT.BORDER); + heapText.setTextLimit(120);//Text limit 128 specified in S60 side + GridData heapTextLayoutData = new GridData(GridData.VERTICAL_ALIGN_CENTER); + heapTextLayoutData.widthHint = 140; + heapText.setLayoutData( heapTextLayoutData ); + heapText.setToolTipText(heapFilterToolTipText); + if(heapDumpBtn.getSelection()){ + heapText.setText(MemSpyPreferences.getSWMTHeapNameFilter()); + }else{ + heapText.setEnabled(false); + } + } + + /** + * Listener for Heap Dumps button, updates preferences and text in Heap Dumps group. + */ + private class HeadDumpSelectionListener implements SelectionListener{ + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + // not needed + + } + + /* + * Change heapText and save preferences + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + boolean selection = heapDumpBtn.getSelection(); + if(selection){ + heapText.setEnabled(true); + heapText.setText(MemSpyPreferences.getSWMTHeapNameFilter()); + }else{ + heapText.setText(""); + heapText.setEnabled(false); + } + } + + + } + + /** + * Save the heap filter text if enabled + */ + private void saveHeapFilterText() { + //Check if heaptext is enabled, if it is, saving text to preferences + if(heapText.isEnabled()){ + String heapFilterText = heapText.getText().trim(); + MemSpyPreferences.setSWMTHeapNameFilter(heapFilterText); + } + } + /** + * Save the Close between cycles selection + */ + private void saveCloseS60AgentBetweenCycles() { + boolean selection = closeBetweenCyclesButton.getSelection(); + // User selects to close MemSpy S60 application between cycles + MemSpyPreferences.setCloseSymbianAgentBetweenCycles(selection); + } + /** + * Save the heap dump selection + */ + private void saveHeapDumpSelection() { + boolean selection = heapDumpBtn.getSelection(); + MemSpyPreferences.setSWMTHeapDumpSelected(selection); + } + + + + /** + * Sets initial selection state for entries + */ + private void InitializeSelectionState() { + int size = SWMTCategorys.getInstance().getCategoryEntries().size(); + for (int i = 0; i < size; i++) { + SWMTCategoryEntry entry = (SWMTCategoryEntry) categoryViewer.getElementAt(i); + int isCategoryBitUp = categorySelection & entry.getCategoryId(); + if(isCategoryBitUp != 0){ + categoryViewer.setChecked(entry, true); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.TitleAreaDialog#getInitialSize() + */ + protected Point getInitialSize() { + return new Point(DIALOG_WIDTH, DIALOG_HEIGHT); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#create() + */ + public void create() { + super.create(); + // Currently just does creation by super call and stores status + isCreateCalled = true; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed() { + + if(heapDumpBtn.getSelection()){ + if(heapText.getText().trim().equals("")){ + System.out.println("DEBUG: WARNING! Empty heap filter text!"); + MessageBox box = new MessageBox(getShell(),SWT.ICON_WARNING | SWT.YES | SWT.NO); + String warningMsg = "Empty \"" +HEAP_DATA_THREAD_FILTER_TXT + + "\" field causes huge amount of data to be traced and tracing may take a very long time. " + +"It is highly recommended to use \"" +HEAP_DATA_THREAD_FILTER_TXT + + "\"." + +"\n\nDo you want to continue anyway?"; + box.setMessage(warningMsg); + box.setText("Using \"" +HEAP_DATA_THREAD_FILTER_TXT + + "\" is recommended"); + int yes_no = box.open(); + //If user does not want to continue but cancel, returning, otherwise just continue to save all data and exit + if(yes_no == SWT.NO){ + return; + } + + } + } + + saveHeapFilterText(); + saveCloseS60AgentBetweenCycles(); + saveHeapDumpSelection(); + super.close(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#open() + */ + public int open(){ + try { + // Making sure that create is called + if(!isCreateCalled){ + create(); + } + showDefaultMessage(); + } catch (Exception e) { + e.printStackTrace(); + } + return super.open(); + } + + /** + * Resets possible error messages and show the default message. + */ + private void showDefaultMessage() { + setErrorMessage(null); + setMessage(DEFAULT_MESSAGE, IMessageProvider.INFORMATION); + } + + /** + * Informs user that parameters are valid and dialog can be + * dismissed with OK button.. + */ + private void setCompleteOkMessage() { + setErrorMessage(null); + setMessage(COMPLETE_MESSAGE, IMessageProvider.INFORMATION); + } + + /** + * Shows error message in case no categories are selected. + */ + private void showErrorMessage() { + setErrorMessage(ERROR_MESSAGE); + setMessage(null); + } + + /** + * Disables OK button. + * This method is guarded against call during construction + * when button row has not been created yet and widget is null. + */ + private void disableOk() { + if(okActionBtn != null){ + okActionBtn.setEnabled(false); + } + } + + /** + * Enables OK button. + * This method is guarded against call during construction + * when button row has not been created yet and widget is null. + */ + private void enableOk() { + if(okActionBtn != null){ + okActionBtn.setEnabled(true); + } + } + + /** + * Updates buttons statuses according the current selection + * status of table entry viewer contents and refreshes contents. + */ + private void notifySelectionChanged() { + Object[] selectedCategoryEntries = getSelectedCategoryEntries(); + if(selectedCategoryEntries.length > 0){ + updateSelectedCategories(selectedCategoryEntries); + enableOk(); + setCompleteOkMessage(); + } + else{ + disableOk(); + showErrorMessage(); + } + categoryViewer.refresh(); + } + + /** + * Creates checkbox viewer component for showing available SWMT categories. + * @param parent Parent composite for the created composite. + * @return New CheckboxTableViewer object instance. + */ + protected CheckboxTableViewer createCategoryCheckBoxTableViewer(Composite parent) { + + ArrayList columnDataArr = new ArrayList(); + + // + // NOTE: Column indices must start from zero (0) and + // the columns must be added in ascending numeric + // order. + // + columnDataArr.add(new S60ToolsTableColumnData("Category", //$NON-NLS-1$ + 350, + SWMTCategoryEntry.NAME_COLUMN_INDEX, + SWMTCategoryEntryTableViewerSorter.CRITERIA_NAME)); + + S60ToolsTableColumnData[] arr + = columnDataArr.toArray( + new S60ToolsTableColumnData[0]); + + S60ToolsTable tbl = S60ToolsTableFactory.createCheckboxTable(parent, arr); + + CheckboxTableViewer tblViewer = new CheckboxTableViewer(tbl.getTableInstance()); + tbl.setHostingViewer(tblViewer); + + return tblViewer; + } + + /** + * Returns currently selected categories. + * @return currently selected categories + */ + private Object[] getSelectedCategoryEntries() { + return categoryViewer.getCheckedElements(); + } + + /** + * Stores currently selected categories combined with bitwise as a single integer. + * @param selectedCategoryEntries array of selected category entries + */ + private void updateSelectedCategories(Object[] selectedCategoryEntries) { + // Re-initializing category selection + categorySelection = SWMTCategoryConstants.CATEGORY_NONE; + for (int i = 0; i < selectedCategoryEntries.length; i++) { + SWMTCategoryEntry categoryEntry = (SWMTCategoryEntry) selectedCategoryEntries[i]; + categorySelection = categorySelection | categoryEntry.getCategoryId(); + } + } + + /** + * Returns currently selected categories combined with bitwise as a single integer. + * @return currently selected categories combined with bitwise as a single integer. + */ + public int getSelectedCategories() { + return categorySelection; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntry.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.ui.dialogs; + +import com.nokia.s60tools.memspy.model.SWMTCategoryConstants; + + +/** + * Stores information on a single SIS file entry. + */ +public class SWMTCategoryEntry { + + // + // Column sorting indices for table column sorter + // + public static final int NAME_COLUMN_INDEX = 0; + + /** + * Category id listed in SWMT category constants + * @see SWMTCategoryConstants + */ + private final int categoryId; + + /** + * Name of the SWMT category. + */ + private final String categoryName; + + /** + * Constructor. + * @param categoryId path name of the directory SIS file is locating. + * @param categoryName name of the SIS file without path. + */ + public SWMTCategoryEntry(int categoryId, String categoryName){ + this.categoryId = categoryId; + this.categoryName = categoryName; + } + + /** + * Gets path name of the directory SIS file is locating. + * @return path name of the directory SIS file is locating. + */ + public int getCategoryId() { + return categoryId; + } + + /** + * Gets name SWMT category. + * @return name SWMT category entry + */ + public String getCategoryName() { + return categoryName; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntryTableViewerSorter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntryTableViewerSorter.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.memspy.ui.dialogs; + +import org.eclipse.jface.viewers.Viewer; + +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.ui.S60ToolsViewerSorter; + +/** + * Sorter implementation for SWMT category entry data. + */ +public class SWMTCategoryEntryTableViewerSorter extends S60ToolsViewerSorter { + + // + // Sorting criteria constants + // + public static final int CRITERIA_NAME = 1; + + /** + * Constructor + */ + public SWMTCategoryEntryTableViewerSorter() { + super(); + // By default we are not sorting the information + setSortCriteria(CRITERIA_NO_SORT); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public int compare(Viewer viewer, Object e1, Object e2) { + + // By default comparison does not do any ordering + int compRes = 0; + + SWMTCategoryEntry entry1 = (SWMTCategoryEntry) e1; + SWMTCategoryEntry entry2 = (SWMTCategoryEntry) e2; + + switch (sortCriteria) { + + case CRITERIA_NAME: + compRes = alphabeticSort(entry1.getCategoryName(), entry2.getCategoryName()); + break; + + case CRITERIA_NO_SORT: + // No sorting criteria defined. + break; + + default: + MemSpyConsole.getInstance() + .println( + "Unexpected sort criteria for a catecory entriey encountered: " + sortCriteria, //$NON-NLS-1$ + MemSpyConsole.MSG_ERROR); + break; + } + + return compRes; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyDataSorter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyDataSorter.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.ui.views; + +import org.eclipse.jface.viewers.Viewer; + +import com.nokia.s60tools.memspy.model.MemSpyFileBundle; +import com.nokia.s60tools.ui.S60ToolsViewerSorter; + +/** + * class MemSpyDataSorter + * Data sorter for MemSpy's main view. + */ + +public class MemSpyDataSorter extends S60ToolsViewerSorter { + + /** + * Import function data is sorted by file type + */ + public static final int FILE_TYPE = 1; + /** + * Import function data is sorted by file name + */ + public static final int FILENAME = 2; + + /** + * Import function data is sorted by time + */ + public static final int TIME = 3; + + /** + * Constructor + */ + public MemSpyDataSorter() { + super(); + // By default set sorting to time + setSortCriteria(TIME); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public int compare(Viewer viewer, Object e1, Object e2) { + + + // By default comparison does not do any ordering + int comparisonResult = 0; + + MemSpyFileBundle f1 = (MemSpyFileBundle) e1; + MemSpyFileBundle f2 = (MemSpyFileBundle) e2; + + switch (sortCriteria) { + + case FILE_TYPE: + comparisonResult = f1.getFileType().compareToIgnoreCase( f2.getFileType() ); + // when type is same, sort alphabetically + if( comparisonResult == 0 ){ + comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() ); + } + break; + case FILENAME: + comparisonResult = f1.getFileName().compareToIgnoreCase( f2.getFileName() ); + break; + case TIME: + comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() ); + if( comparisonResult == 0 ){ + comparisonResult = numericSort( f2.getCycleNumberFromFileName(), f1.getCycleNumberFromFileName() ); + } + + break; + case CRITERIA_NO_SORT: + comparisonResult = f2.getFileType().compareToIgnoreCase( f1.getFileType() ); + // when type is same, sort by file time + if( comparisonResult == 0 ){ + comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() ); + } + break; + default: + break; + } + + return comparisonResult; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainView.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1329 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.views; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.ViewPart; + +import com.nokia.s60tools.heapanalyser.interfaces.HeapAnalyserLauncher; +import com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener; +import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver; +import com.nokia.s60tools.memspy.model.AnalyseHeapJob; +import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator; +import com.nokia.s60tools.memspy.model.AnalyserXMLParser; +import com.nokia.s60tools.memspy.model.ImportEngine; +import com.nokia.s60tools.memspy.model.MemSpyFileBundle; +import com.nokia.s60tools.memspy.model.MemSpyFileOperations; +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.memspy.resources.ImageKeys; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; +import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard; +import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizardDialog; +import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard.MemSpyWizardType; +import com.nokia.s60tools.memspy.util.MemSpyConsole; +import com.nokia.s60tools.swmtanalyser.ui.actions.SwmtAnalyser; +import com.nokia.s60tools.ui.S60ToolsTable; +import com.nokia.s60tools.ui.S60ToolsTableColumnData; +import com.nokia.s60tools.ui.S60ToolsTableFactory; +import com.nokia.s60tools.ui.S60ToolsViewerSorter; +import com.nokia.s60tools.util.debug.DbgUtility; + + + +/** + *

+ * MemSpyMainView. + * The main view of MemSpy Carbide extension. Shows imported MemSpy data files in a table and allows user to: + * - Launch Heap Analyser to analyse one Heap Dump file. + * - Launch Heap Analyser to compare two Heap Dump files. + * - Launch SWMT-analyser and analyse one System Wide Memory Tracking log. + *

+ */ + +public class MemSpyMainView extends ViewPart implements INewMemSpyFilesObserver, SelectionListener, IAnalyseHeapJobListener, KeyListener { + + + /** + * Enumeration for actions for a MemSpy file + */ + private enum FileActionType{NONE, ANALYSE_SWMT_ONE, ANALYSE_SWMT_MULTIPLE, ANALYSE_HEAP, COMPARE_HEAPS, DELETE}; + + /** + * TraceViewers ID com.nokia.traceviewer.view.TraceViewerView + */ + private static final String TRACE_VIEWER_VIEW_ID = "com.nokia.traceviewer.view.TraceViewerView"; + + /** + * Main view's ID com.nokia.s60tools.memspy.ui.views.MemSpyMainView + */ + private static final String ID = "com.nokia.s60tools.memspy.ui.views.MemSpyMainView"; + + /* viewer for table */ + private TableViewer viewer; + + /* contentProvider for table */ + private MemSpyMainViewContentProvider contentProvider; + + /* Launch Heap Analyser - action */ + private Action launchHeapAnalyserAction; + + /* Launch Wizard - action */ + private Action launchWizardAction; + + /* compare two heaps - action */ + private Action compareTwoHeapsAction; + + /* import and compare two heaps - action */ + private Action importAndCompareHeapsAction; + + /* import and compare two heaps - toolbar action + that changes based on selection*/ + private Action compareHeapsToolbarAction; + + /* Launch SWMT-analyser - action */ + private Action launchSWMTAction; + + /* delete selected files - action */ + private Action deleteAction; + + /* import engine */ + private ImportEngine importEngine; + + /* doubleClick - action */ + private Action doubleClickAction; + + /* open file in text editor */ + private Action openFile; + + /* edit symbol information */ + private Action editSymbols; + + + // + //Strings for error and info messages + // + + /** + * Error message for analysis startup + */ + public final static String ERROR_LAUNCH_SWMT_ANALYSER = "MemSpy was unable to start analysing imported files."; + /** + * Error message for Heap Dump import + */ + public final static String ERROR_HEAP_IMPORT_FAILED = "Some of the Heap Dumps were not imported successfully.( file operations were not successfull )"; + /** + * Error message for SWMT import + */ + public final static String ERROR_SWMT_IMPORT_FAILED = "SWMT-files were not imported successfully. ( file operations were not successfull )"; + /** + * Error message for import + */ + public final static String ERROR_IMPORT_HEADER = "Import error"; + /** + * Warning message for compare + */ + public final static String WARNING_COMPARE = "Compare Warning"; + /** + * Warning message for filea allready exist + */ + public final static String WARNING_FILE_EXISTS = "The file already exists. Do you want to replace the existing file?"; + + private final static String ERROR_COMPARE = "Compare error"; + private final static String ERROR_HEAP_THREADS_NOT_SAME = "Selected Heaps cannot be compared. Only two Heap Dumps that are from same thread can be compared."; + private final static String ERROR_TOPIC = "MemSpy Error"; + private final static String ERROR_CONFIGURATION_FILES_NOT_FOUND = "Configuration files for selected heaps cannot be found."; + private final static String ERROR_UNABLE_TO_GENERATE_CONFIGURATIONS = "Error was encountered when generating files that are needed when running Heap Analyser."; + private final static String ERROR_HEAP_ANALYSER = "Heap Analyser error."; + private final static String WARNING_SYMBOLS_NOT_SAME = "Selected files symbol definitions differ, do you wish to compare heaps anyway?"; + private final static String FILE_DIALOG_DEFINE_OUTPUT = "Define output file name"; + private final static String CONFIRMATION = "Confirmation"; + private final static String CONFIRMATION_OPEN_FILE = "Open generated xls-file with application that is assosiated for that file type?"; + + private final static String TOOLTIP_COMPARE_2_IMPORTED_FILE = "Compare selected heaps with Heap Analyser"; + private final static String TOOLTIP_TEXT_IMPORT_AND_COMPARE = "Import heap dump and compare it to selected heap"; + + + /** + * The constructor. + */ + public MemSpyMainView() { + importEngine = new ImportEngine( this ); + } + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + public void createPartControl(Composite parent) { + + + ArrayList columnDataArr = new ArrayList(); + + columnDataArr.add(new S60ToolsTableColumnData("File Type", 150, 0, MemSpyDataSorter.FILE_TYPE)); + columnDataArr.add(new S60ToolsTableColumnData("File Name", 300, 1, MemSpyDataSorter.FILENAME)); + columnDataArr.add(new S60ToolsTableColumnData("Time", 150, 2, MemSpyDataSorter.TIME)); + + + S60ToolsTableColumnData[] arr = columnDataArr.toArray(new S60ToolsTableColumnData[0]); + + S60ToolsTable tbl = S60ToolsTableFactory.create(parent, arr); + + viewer = new TableViewer( tbl.getTableInstance() ); + contentProvider = new MemSpyMainViewContentProvider( this ); + viewer.setContentProvider( contentProvider ); + viewer.setLabelProvider(new MemSpyMainViewLabelProvider()); + viewer.setComparator(new MemSpyDataSorter()); + viewer.setSorter(new MemSpyDataSorter()); + viewer.setInput(getViewSite()); + + tbl.addSelectionListener(this); + tbl.addKeyListener(this); + tbl.setHostingViewer(viewer); + + try { + PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),HelpContextIDs.MEMSPY_MAIN_VIEW); + } catch (Exception e) { + e.printStackTrace(); + } + // Make actions + makeActions(); + + // hook context menus + hookContextMenu(); + + // hook double click action + hookDoubleClickAction(); + + // contribute to action bars + contributeToActionBars(); + + // refresh view + this.refreshView(); + + // update toolbar items state + this.enableAndDisableToolbarItems(); + + + + } + + /** + * hookContextMenu. + * Creates context menu. + */ + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); + + // Adding all actions to menu. + menuMgr.add(launchHeapAnalyserAction); + menuMgr.add(compareTwoHeapsAction); + menuMgr.add(importAndCompareHeapsAction); + menuMgr.add(launchSWMTAction); + menuMgr.add(editSymbols); + menuMgr.add(openFile); + menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + menuMgr.add(deleteAction); + + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + MemSpyMainView.this.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + /** + * contributeToActionBars. + * fills pull down menu and local toolbar + */ + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalToolBar(bars.getToolBarManager()); + } + + + /** + * fillContextMenu. + * fills context menu depending what type of file or files are selected. + * @param manager menuManager + */ + private void fillContextMenu(IMenuManager manager) { + + FileActionType availableAction = this.getAvailableAction(); + + if( availableAction == FileActionType.ANALYSE_HEAP ){ + launchHeapAnalyserAction.setEnabled(true); + compareTwoHeapsAction.setEnabled(false); + importAndCompareHeapsAction.setEnabled(true); + launchSWMTAction.setEnabled(false); + editSymbols.setEnabled(true); + openFile.setEnabled(true); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.ANALYSE_SWMT_ONE ){ + launchHeapAnalyserAction.setEnabled(false); + compareTwoHeapsAction.setEnabled(false); + importAndCompareHeapsAction.setEnabled(false); + launchSWMTAction.setEnabled(true); + editSymbols.setEnabled(false); + openFile.setEnabled(true); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.ANALYSE_SWMT_MULTIPLE ){ + launchHeapAnalyserAction.setEnabled(false); + compareTwoHeapsAction.setEnabled(false); + importAndCompareHeapsAction.setEnabled(false); + launchSWMTAction.setEnabled(true); + editSymbols.setEnabled(false); + openFile.setEnabled(false); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.COMPARE_HEAPS ){ + launchHeapAnalyserAction.setEnabled(false); + compareTwoHeapsAction.setEnabled(true); + importAndCompareHeapsAction.setEnabled(false); + launchSWMTAction.setEnabled(false); + editSymbols.setEnabled(false); + openFile.setEnabled(false); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.DELETE ){ + launchHeapAnalyserAction.setEnabled(false); + compareTwoHeapsAction.setEnabled(false); + importAndCompareHeapsAction.setEnabled(false); + launchSWMTAction.setEnabled(false); + editSymbols.setEnabled(false); + openFile.setEnabled(false); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.NONE ){ + launchHeapAnalyserAction.setEnabled(false); + compareTwoHeapsAction.setEnabled(false); + importAndCompareHeapsAction.setEnabled(false); + launchSWMTAction.setEnabled(false); + editSymbols.setEnabled(false); + openFile.setEnabled(false); + deleteAction.setEnabled(false); + } + } + + + /** + * getAvailableAction. + * @return action type that is available for item or items that are currently selected. + */ + private FileActionType getAvailableAction(){ + + // get selected items + IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); + + @SuppressWarnings("unchecked") + List selectionList = selection.toList(); + + boolean swmtFileFound = false; + boolean heapFileFound = false; + + // go thru selected files-list + for(Object obj : selectionList){ + MemSpyFileBundle bundle = (MemSpyFileBundle) obj; + if( bundle.getFileType().equals("SWMT-Log") ){ + swmtFileFound = true; + } + else{ + heapFileFound = true; + } + } + + // if two files and no swmt files are found, compare heaps - action is available + if( selectionList.size() == 2 && heapFileFound && !swmtFileFound ){ + return FileActionType.COMPARE_HEAPS; + } + + // if swmt-files are found and no heap dumps are found, analyse swmt-action is available + else if( swmtFileFound && selectionList.size() == 1 ){ + return FileActionType.ANALYSE_SWMT_ONE; + } + else if( swmtFileFound && !heapFileFound){ + return FileActionType.ANALYSE_SWMT_MULTIPLE; + } + + // if heap one heap file is found, analyse heap - action is available + else if( heapFileFound && selectionList.size() == 1 ){ + return FileActionType.ANALYSE_HEAP; + } + + // There are files selected, but only available action is delete. + else if( selectionList.size() > 0 ){ + return FileActionType.DELETE; + } + + // No files selected - no actions are available + return FileActionType.NONE; + } + + + /** + * enableAndDisableToolbarItems. + * Enables and disable toolbar items according to type of the selected file. + */ + private void enableAndDisableToolbarItems(){ + FileActionType availableAction = this.getAvailableAction(); + + if( availableAction == FileActionType.ANALYSE_HEAP ){ + launchSWMTAction.setEnabled(false); + launchHeapAnalyserAction.setEnabled(true); + compareHeapsToolbarAction.setEnabled(true); + compareHeapsToolbarAction.setToolTipText(TOOLTIP_TEXT_IMPORT_AND_COMPARE); + deleteAction.setEnabled(true); + + + } + else if( availableAction == FileActionType.ANALYSE_SWMT_MULTIPLE || availableAction == FileActionType.ANALYSE_SWMT_ONE ){ + launchSWMTAction.setEnabled(true); + launchHeapAnalyserAction.setEnabled(false); + compareHeapsToolbarAction.setEnabled(false); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.COMPARE_HEAPS ){ + launchSWMTAction.setEnabled(false); + launchHeapAnalyserAction.setEnabled(false); + compareHeapsToolbarAction.setEnabled(true); + compareHeapsToolbarAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE); + deleteAction.setEnabled(true); + + } + else if( availableAction == FileActionType.DELETE ){ + launchSWMTAction.setEnabled(false); + launchHeapAnalyserAction.setEnabled(false); + compareHeapsToolbarAction.setEnabled(false); + deleteAction.setEnabled(true); + } + else if( availableAction == FileActionType.NONE ){ + launchSWMTAction.setEnabled(false); + launchHeapAnalyserAction.setEnabled(false); + compareHeapsToolbarAction.setEnabled(false); + deleteAction.setEnabled(false); + } + } + + + /** + * fillLocalToolBar. + * fills toolbar + * @param manager Toolbar manager + */ + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(launchSWMTAction); + manager.add(compareHeapsToolbarAction); + manager.add(launchHeapAnalyserAction); + manager.add(launchWizardAction); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + manager.add(deleteAction); + + } + + + /** + * makeActions. + * Creates actions + */ + private void makeActions() { + + launchSWMTAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + + // get selection list. + IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); + + // ensure that selected items are swmt-logs + if( !selection.isEmpty() ){ + + List list = selection.toList(); + ArrayList swmtLogs = new ArrayList(); + + boolean allFilesAreSwmtLogs = true; + + // Go thru bundle list and add all file paths into arraylist + for( MemSpyFileBundle item : list ){ + swmtLogs.add( item.getFilePath() ); + if( item.getFileType().equals("SWMT-log") ){ + allFilesAreSwmtLogs = false; + } + } + + // ensure that all selected files were swmt logs + if( allFilesAreSwmtLogs ){ + // launch swmt analyser for selected logs. + SwmtAnalyser analyser = new SwmtAnalyser(MemSpyConsole.getInstance()); + analyser.analyse( swmtLogs ); + } + } + } + }; + launchSWMTAction.setText("Launch SWMT-Analyser"); + launchSWMTAction.setToolTipText("Launch SWMT-Analyser"); + launchSWMTAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_LAUNCH_SWMT)); + + + compareTwoHeapsAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + + // get selected items: + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + //verify that to heap files are selected. + if( getAvailableAction() == FileActionType.COMPARE_HEAPS ){ + compareHeaps(selectionList); + } + } + }; + + compareTwoHeapsAction.setText(TOOLTIP_COMPARE_2_IMPORTED_FILE); + compareTwoHeapsAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE); + compareTwoHeapsAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP)); + + importAndCompareHeapsAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + + // get selected items: + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + //verify that only one file is selected. + if( getAvailableAction() == FileActionType.ANALYSE_HEAP ){ + importAndCompareHeaps(selectionList); + } + } + }; + + importAndCompareHeapsAction.setText(TOOLTIP_TEXT_IMPORT_AND_COMPARE); + importAndCompareHeapsAction.setToolTipText(TOOLTIP_TEXT_IMPORT_AND_COMPARE); + importAndCompareHeapsAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP)); + + compareHeapsToolbarAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + + // get selected items: + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + // check if only one file is selected. + if( getAvailableAction() == FileActionType.ANALYSE_HEAP ){ + importAndCompareHeaps(selectionList); + } + // or if two heaps are selected, then compare them. + else if( getAvailableAction() == FileActionType.COMPARE_HEAPS ){ + compareHeaps(selectionList); + } + } + }; + + compareHeapsToolbarAction.setText(TOOLTIP_COMPARE_2_IMPORTED_FILE); + compareHeapsToolbarAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE); + compareHeapsToolbarAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP)); + + launchHeapAnalyserAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + // Get thread name from xml-file + String xmlFile = selectionList.get(0).getXMLFilePath(); + AnalyserXMLGenerator xml = readXMLFile(xmlFile); + + //If Symbol files has not been set to data, before analyze, user have to set a Symbol file + if(!xml.hasXMLDebugMetaDataFile()){ + //verify that only one file is selected. + if( selectionList.size() == 1 ){ + //Make user to edit symbol files, and after that, continue to launch + int retCode = runWizard( MemSpyWizardType.SYMBOLS, xml ); + //Don't giving an error message if user presses Cancel, instead just return + if(retCode == Window.CANCEL){ + return; + } + } + } + + + String threadName = xml.getXMLThreadName(); + + //verify that only one file is selected. + if( selectionList.size() == 1 ){ + + //verify that heap dump file is selected. + if( selectionList.get(0).hasHeapDumpFile() ){ + + // get xml files path + String xmlPath = xmlFile; + + // launch heap analyser + launchHeapAnalyser( xmlPath, null, threadName, true ); + + } + + + } + } + }; + launchHeapAnalyserAction.setText("Analyse selected heap with Heap Analyser"); + launchHeapAnalyserAction.setToolTipText("Analyse selected heap with Heap Analyser"); + launchHeapAnalyserAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_ANALYZE_HEAP)); + + + launchWizardAction = new Action() { + public void run() { + runWizard( MemSpyWizardType.FULL, null ); + } + }; + + launchWizardAction.setText("Launch MemSpy's import Wizard"); + launchWizardAction.setToolTipText("Launch MemSpy's import Wizard"); + launchWizardAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_APP_ICON)); + + + doubleClickAction = new Action() { + public void run() { + FileActionType action = getAvailableAction(); + switch (action){ + case ANALYSE_HEAP:{ + launchHeapAnalyserAction.run(); + break; + } + case ANALYSE_SWMT_ONE: + case ANALYSE_SWMT_MULTIPLE:{ + launchSWMTAction.run(); + break; + } + case COMPARE_HEAPS:{ + compareTwoHeapsAction.run(); + break; + } + default:{ + // No need to do anything with other action. + break; + } + + } + } + }; + + + + deleteAction = new Action() { + @SuppressWarnings("unchecked") + public void run() { + // get selected items: + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + + List selectionList = (List)obj; + + // ensure that some item(s) is selected. + if( selectionList.size() >= 1 ){ + + // Display a Confirmation dialog + MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); + messageBox.setText("MemSpy - Delete Files"); + messageBox.setMessage("Are you sure you want to delete selected files?"); + int buttonID = messageBox.open(); + if (buttonID == SWT.YES) { + for( MemSpyFileBundle item : selectionList ){ + + // delete it + item.delete(); + + } + refreshContentAndView(); + } + + } + + } + }; + + deleteAction.setText("Delete"); + deleteAction.setToolTipText("Delete selected item"); + deleteAction.setImageDescriptor( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); + + + openFile = new Action() { + @SuppressWarnings("unchecked") + public void run() { + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + //verify that only one file is selected. + if( selectionList.size() == 1 ){ + + // open selected log file in editor. + File fileToOpen = new File(selectionList.get(0).getFilePath()); + if (fileToOpen.exists() && fileToOpen.isFile()) { + IFileStore fileStore = EFS.getLocalFileSystem().getStore(fileToOpen.toURI()); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + + try { + IDE.openEditorOnFileStore( page, fileStore ); + } catch ( PartInitException e ) { + showErrorMessage(ERROR_TOPIC, "MemSpy was unable to open file."); + } + } else { + showErrorMessage(ERROR_TOPIC, "File does not exists."); + + } + + } + } + }; + openFile.setText("Open selected file in text editor"); + openFile.setToolTipText("Open selected file in text editor"); + + editSymbols = new Action() { + @SuppressWarnings("unchecked") + public void run() { + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + + List selectionList = (List)obj; + + //verify that only one file is selected. + if( selectionList.size() == 1 ){ + AnalyserXMLGenerator info = readXMLFile(selectionList.get(0).getXMLFilePath()); + runWizard( MemSpyWizardType.SYMBOLS, info ); + } + } + }; + editSymbols.setText("Edit symbol definitions of selected Heap Dump"); + editSymbols.setToolTipText("Edit symbol definitions of selected Heap Dump"); + } + + + /** + * Starts wizard to compare currently selected heap file. + * @param selectionList List from which selected file is found. + */ + private void importAndCompareHeaps(List selectionList) { + // get info from xml-file + AnalyserXMLGenerator info = readXMLFile(selectionList.get(0).getXMLFilePath()); + + // set source files path into info + info.setXMLSourceFile(new String[]{ selectionList.get(0).getFilePath() }); + + // start wizard + runWizard( MemSpyWizardType.COMPARE, info); + } + + /** + * Starts Heap analyzer to compare two currently selected heaps. + * @param selectionList List from which selected heap files are found. + */ + private void compareHeaps(List selectionList) { + // get selected file bundles. + MemSpyFileBundle bundle1 = selectionList.get(0); + MemSpyFileBundle bundle2 = selectionList.get(1); + + // read both Heap Dumps configuration files + AnalyserXMLGenerator generator1 = readXMLFile(bundle1.getXMLFilePath()); + AnalyserXMLGenerator generator2 = readXMLFile(bundle2.getXMLFilePath()); + + // ensure that both generators were created successfully. + if( generator1 == null || generator2 == null ){ + MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_CONFIGURATION_FILES_NOT_FOUND ); + return; + } + + // if Heaps are not from same thread show error message + if( !generator1.getXMLThreadName().equals( generator2.getXMLThreadName() ) ){ + MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_HEAP_THREADS_NOT_SAME ); + return; + } + + boolean compare = true; + + // if symbol definitions are not same, confirm that user really wants continue comparing + if( !Arrays.equals(generator1.getXMLDebugMetaDataFile(), generator2.getXMLDebugMetaDataFile() ) ){ + // Display a Confirmation dialog + MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); + messageBox.setText( WARNING_COMPARE ); + messageBox.setMessage( WARNING_SYMBOLS_NOT_SAME ); + int buttonID = messageBox.open(); + if (buttonID == SWT.NO) { + compare = false; + } + } + if( compare ){ + + UserEnteredData data = new UserEnteredData(); + + // open file dialog for selecting a MemSpy file + FileDialog dialog = new FileDialog( getSite().getShell(), SWT.SAVE ); + dialog.setText(FILE_DIALOG_DEFINE_OUTPUT); + String[] filterExt = { "*.xls" }; + dialog.setFilterExtensions(filterExt); + + // Restore previous output filename + String[] lastUsedFiles = data.getPreviousValues(ValueTypes.OUTPUT_FILE); + if( lastUsedFiles != null && lastUsedFiles.length > 0 ){ + dialog.setFileName(lastUsedFiles[0]); + } + + String result = dialog.open(); + + + if( result != null ){ + + File file = new File( result ); + // If file already exists, confirm that user wants to rewrite it. + if( file.exists() ){ + + // Display a Confirmation dialog + MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); + messageBox.setText( WARNING_COMPARE ); + messageBox.setMessage( WARNING_FILE_EXISTS ); + int buttonID = messageBox.open(); + if (buttonID == SWT.NO) { + compare = false; + } + } + + if( compare ){ + + // Save output filename so that it can be restored later + data.saveValue(ValueTypes.OUTPUT_FILE, result); + + generator1.setXMLAnalyseFileOutput(result); + String[] sources = new String[]{ bundle1.getFilePath(), bundle2.getFilePath() }; + + // generate configuration file for comparison + if( importEngine.generateCompareConfigurationFile(sources, generator1.getXMLThreadName(), generator1)){ + launchHeapAnalyser( MemSpyFileOperations.getCompareConfigurationFilePath(), result, generator1.getXMLThreadName(), false ); + } + else{ + MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_UNABLE_TO_GENERATE_CONFIGURATIONS ); + return; + } + } + } + } + } + + /** + * hookDoubleClickAction + * adds double click listener + */ + private void hookDoubleClickAction() { + viewer.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + doubleClickAction.run(); + } + }); + } + + /** + * setFocus. + * Passing the focus request to the viewer's control. + */ + public void setFocus() { + viewer.getControl().setFocus(); + } + + + /** + * Makes main view visible and returns an instance of itself. Can be called from + * an UI thread only. + * @return instance of main view + */ + public static MemSpyMainView showAndReturnYourself() { + return showAndReturnYourself(false); + } + + /** + * Makes main view visible and returns an instance of itself. Can be called from + * an UI thread only. + * @return instance of main view + */ + public static MemSpyMainView showAndReturnYourself(boolean openOnly) { + try { + + IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (ww == null) + return null; + + IWorkbenchPage page = ww.getActivePage(); + IWorkbenchPart currentPart = page.getActivePart(); + + // Checking if view is already open + IViewReference[] viewRefs = page.getViewReferences(); + for (int i = 0; i < viewRefs.length; i++) { + IViewReference reference = viewRefs[i]; + String id = reference.getId(); + if(id.equalsIgnoreCase(MemSpyMainView.ID)){ + // Found, restoring the view + IViewPart viewPart = reference.getView(true); + if (!openOnly) + page.activate(viewPart); + return (MemSpyMainView)viewPart; + } + } + + // View was not found, opening it up as a new view. + MemSpyMainView mView = (MemSpyMainView)page.showView(MemSpyMainView.ID); + if (openOnly) + page.bringToTop(currentPart); + return mView; + + } catch (Exception e) { + e.printStackTrace(); + + return null; + } + } + + /** + * runWizard(). + * Starts MemSpy import wizard. + * @return {@link Window#OK} if Finish pressed, {@link Window#CANCEL} if Cancel was pressed. + */ + public int runWizard( MemSpyWizardType wizardType, AnalyserXMLGenerator info ){ + + + MemSpyWizard wizard = null; + if( wizardType == MemSpyWizardType.FULL ){ + wizard = new MemSpyWizard( wizardType, null ); + + } + else if( wizardType == MemSpyWizardType.COMPARE || wizardType == MemSpyWizardType.SYMBOLS ){ + wizard = new MemSpyWizard( wizardType, info ); + } + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Open wizard dialog"); + // Open wizard dialog + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Create Dialog"); + MemSpyWizardDialog wizDialog = new MemSpyWizardDialog(getViewSite().getShell(), wizard); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Set dialog data"); + wizard.setData(wizDialog); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Set dialog size"); + wizDialog.setPageSize(600, 600); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Add pagecnhangelistener"); + wizDialog.addPageChangedListener(wizard); + wizard.setWindowTitle("MemSpy Import Wizard"); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Creating wizaDialog"); + wizDialog.create(); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "open wizaDialog"); + + return wizDialog.open(); + } + + /** + * readXMLFile. + * Reads xml file from given path. + * @param XMLFilePath path of xml-file + * @return analyserXMLFile with read values. + */ + private AnalyserXMLGenerator readXMLFile(String XMLFilePath){ + + FileReader reader = null; + try { + File file = new File( XMLFilePath ); + reader = new FileReader(file ); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + BufferedReader bReader = new BufferedReader(reader); + AnalyserXMLGenerator xml = AnalyserXMLParser.parseXML( bReader ); + return xml; + + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver#memSpyFilesUpdated() + */ + public void memSpyFilesUpdated() { + Runnable refreshRunnable = new Runnable(){ + public void run(){ + refreshView(); + // Sort files so that newly imported files are in top + ((S60ToolsViewerSorter) viewer.getSorter()).setSortCriteria(MemSpyDataSorter.TIME); + } + }; + Display.getDefault().asyncExec(refreshRunnable); + + + } + + /** + * refreshView. + * Refreshes view asynchronously. + */ + private void refreshView() { + Runnable refreshRunnable = new Runnable(){ + public void run(){ + viewer.refresh(); + enableAndDisableToolbarItems(); + + } + }; + + // Has to be done in its own thread + // in order not to cause invalid thread access + Display.getDefault().asyncExec(refreshRunnable); + } + + /** + * refreshContentAndView. + * Refreshes content and view synchronously. + */ + private void refreshContentAndView(){ + contentProvider.refresh(); + viewer.refresh(); + this.enableAndDisableToolbarItems(); + } + + /** + * Refreshes content and view asynchronously. + */ + public void refreshContentAndViewAsync() { + Runnable refreshRunnable = new Runnable(){ + public void run(){ + refreshContentAndView(); + } + }; + + Display.getDefault().asyncExec(refreshRunnable); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent arg0) { + // can be left empty. + + } + public void widgetSelected(SelectionEvent arg0) { + this.enableAndDisableToolbarItems(); + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener#heapAnalyserReturnValue(int) + */ + public void heapAnalyserFinished(final int returnValue) { + + if( returnValue != 0 ){ + String errorMessage = HeapAnalyserLauncher.getErrorMessage(returnValue); + // Reporting error to console + String consoleErrMsg = "Heap Analyser launch failure with process exit value=" + returnValue + "." + + " " + errorMessage; + reportConsoleMessage(consoleErrMsg, MemSpyConsole.MSG_ERROR); + // Reporting error to user + showErrorMessage(ERROR_HEAP_ANALYSER, errorMessage ); + } + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener#heapAnalyserReturnValue(int, java.lang.String) + */ + public void heapAnalyserFinished(int returnValue, final String outputFilePath) { + + // if error occured + if( returnValue != 0 ){ + this.heapAnalyserFinished(returnValue); + } + + else{ + Runnable refreshRunnable = new Runnable(){ + public void run(){ + /*// Ask user if generated file should be opened on excel + boolean compare = MessageDialog.openConfirm(getSite().getShell(), CONFIRMATION, CONFIRMATION_OPEN_FILE ); + */ + boolean compare = true; + // Display a Confirmation dialog + MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); + messageBox.setText( CONFIRMATION ); + messageBox.setMessage( CONFIRMATION_OPEN_FILE ); + int buttonID = messageBox.open(); + if (buttonID == SWT.NO) { + compare = false; + } + if( compare ){ + + // find program for xls-filetype + Program p=Program.findProgram(".xls"); + + // if found, launch it. + if(p!=null){ + p.execute(outputFilePath); + } + } + + } + }; + + // Has to be done in its own thread + // in order not to cause invalid thread access + Display.getDefault().asyncExec(refreshRunnable); + + + } + } + + + /** + * Get import engine. + * @return importEngine + */ + public ImportEngine getImportEngine() { + return importEngine; + } + + /** + * Shows error message asynchronously. + * @param header header of message + * @param text error text + */ + public void showErrorMessage(final String header, final String text){ + Runnable showErrorMessageRunnable = new Runnable(){ + public void run(){ + MessageDialog.openError( getSite().getShell(), header, text); + } + }; + + // Has to be done in its own thread + // in order not to cause invalid thread access + Display.getDefault().asyncExec(showErrorMessageRunnable); + } + + /** + * Reports message to console asynchronously. + * @param consoleMsg console message. + * @param messageType console message type + */ + public void reportConsoleMessage(final String consoleMsg, final int messageType){ + Runnable reportConsoleMessageRunnable = new Runnable(){ + public void run(){ + MemSpyConsole.getInstance().println(consoleMsg, messageType); + } + }; + + // Has to be done in its own thread + // in order not to cause invalid thread access + Display.getDefault().asyncExec(reportConsoleMessageRunnable); + } + + /** + * Shows trace viewer plugin + */ + public static void showTraceViewer() { + try { + + IWorkbenchWindow ww = MemSpyPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); + if (ww == null) + return; + IWorkbenchPage page = ww.getActivePage(); + + // Checking if view is already open + IViewReference[] viewRefs = page.getViewReferences(); + for (int i = 0; i < viewRefs.length; i++) { + IViewReference reference = viewRefs[i]; + String id = reference.getId(); + if(id.equalsIgnoreCase(TRACE_VIEWER_VIEW_ID)){ + // Found, restoring the view + IViewPart viewPart = reference.getView(true); + page.activate(viewPart); + return; + } + } + + // View was not found, opening it up as a new view. + page.showView(TRACE_VIEWER_VIEW_ID); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * launchHeapAnalyser. + * Launches Heap Analyser. + * @param configurationFilePath path of the configuration file + * @param analyseOutputFilePath path of the output file + * @param threadName thread's name + * @param viewingHeap true, if action is view heap + */ + public void launchHeapAnalyser( String configurationFilePath, String analyseOutputFilePath, String threadName, boolean viewingHeap ){ + + AnalyseHeapJob analyseHeapJob; + + // set heap job's name correct + if( viewingHeap ){ + analyseHeapJob = new AnalyseHeapJob( "Heap Analyser Running, Viewing heap from thread: " + threadName, this ); + } + else{ + analyseHeapJob = new AnalyseHeapJob( "Heap Analyser Running, Comparing Heaps from thread: " + threadName , this ); + } + + // set output file path + analyseHeapJob.setAnalyseOutputFile( analyseOutputFilePath ); + + // launch Heap Analyser + analyseHeapJob.setConfigurationFile( configurationFilePath ); + analyseHeapJob.refresh(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) + */ + public void keyPressed(KeyEvent keyEvent) { + + // if delete key is pressed run delete -action. + if( keyEvent.keyCode == java.awt.event.KeyEvent.VK_DELETE){ + deleteAction.run(); + } + } + /* (non-Javadoc) + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + public void keyReleased(KeyEvent arg0) { + // can be left empty. + } + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver#setOutputFilePath(java.lang.String) + */ + public void setOutputFilePath(String outputFilePath) { + // can be left empty. + } + + /** + * Launch the SWMT analyser with given files + * @param files + */ + public void launchSWMTAnalyser( final ArrayList files ){ + Runnable showErrorMessageRunnable = new Runnable(){ + public void run(){ + // launch swmt analyser for selected logs. + SwmtAnalyser analyser = new SwmtAnalyser(MemSpyConsole.getInstance()); + analyser.analyse( files ); + } + }; + + // Has to be done in its own thread + // in order not to cause invalid thread access + Display.getDefault().asyncExec(showErrorMessageRunnable); + + } + + /** + * Callback called when symbol filea are updated by user + * @param symbols + */ + public void symbolsUpdated( final AnalyserXMLGenerator symbols ){ + Runnable editSymbolDefinitions = new Runnable(){ + @SuppressWarnings("unchecked") + public void run(){ + // get selected file bundle + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection)selection).toList(); + List selectionList = (List)obj; + //verify that only one file is selected. + if( selectionList.size() == 1 ){ + if( !importEngine.generateViewConfigurationFile(selectionList.get(0).getFilePath(), symbols.getXMLThreadName(), symbols) ){ + showErrorMessage(ERROR_TOPIC, "File operations were failed when trying to save new symbol definitions. Definitions may not be saved."); + } + } + } + }; + Display.getDefault().asyncExec(editSymbolDefinitions); + + } + +} \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewContentProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewContentProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.views; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver; +import com.nokia.s60tools.memspy.model.MemSpyFileManager; + +/** + * This class provides content for main view + */ +class MemSpyMainViewContentProvider implements IStructuredContentProvider { + + private final MemSpyFileManager memSpyFileManager; + + /** + * Create new content provider + * @param observer + */ + public MemSpyMainViewContentProvider( INewMemSpyFilesObserver observer ){ + memSpyFileManager = new MemSpyFileManager( observer ); + } + /** + * Refresh file manager + * @see MemSpyFileManager#refresh() + */ + public void refresh() { + memSpyFileManager.refresh(); + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object parent) { + return memSpyFileManager.getmemSpyFiles(); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewLabelProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewLabelProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.views; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.nokia.s60tools.memspy.model.MemSpyFileBundle; +import com.nokia.s60tools.memspy.resources.ImageKeys; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; + +class MemSpyMainViewLabelProvider extends LabelProvider implements ITableLabelProvider { + /** + * Returns text for a column defined by index + */ + public String getColumnText(Object obj, int index) { + MemSpyFileBundle cFileBundle = (MemSpyFileBundle)obj; + return cFileBundle.getText(index); + } + public Image getColumnImage(Object obj, int index) { + if (index == MemSpyFileBundle.INDEX_FILE_TYPE){ + return getImage(obj); + } + else{ + return null; + } + } + public Image getImage(Object obj) { + MemSpyFileBundle bundle = (MemSpyFileBundle)obj; + if( bundle.hasHeapDumpFile() ){ + return ImageResourceManager.getImage(ImageKeys.IMG_HEAP_DUMP); + } + else{ + return ImageResourceManager.getImage(ImageKeys.IMG_SWMT_LOG); + } + } +} \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/DeviceOrFileSelectionPage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/DeviceOrFileSelectionPage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1436 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo.HeapDumpType; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener; +import com.nokia.s60tools.memspy.model.MemSpyFileOperations; +import com.nokia.s60tools.memspy.model.MemSpyLogParserEngine; +import com.nokia.s60tools.memspy.model.TraceCoreEngine; +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.memspy.ui.UiUtils; +import com.nokia.s60tools.ui.preferences.PreferenceUtils; +import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; +import com.nokia.s60tools.util.debug.DbgUtility; + + +public class DeviceOrFileSelectionPage extends S60ToolsWizardPage implements + SelectionListener, ModifyListener, IMemSpyTraceListener { + + /** + * Selection index for import from device via TraceViewer radio button + */ + private static final int DEVICE_RADIO_BUTTON_SELECTION_INDEX = 2; + + public enum PageType{ IMPORT_PAGE, COMPARE_FIRST_HEAP, COMPARE_SECOND_HEAP }; + + // UI elements + private Combo fileCombo; + private Button buttonBrowseFile; + + private Button fileRadioButton; + private Button deviceRadioButton; + private Button loadThreadListButton; + private Button connectionSettingsButton; + private Button getHeapButton; + + private Label heapsReceivedLabel; + private Label connectionTextLabel; + private Label connectionNameInUseLabel; + + private GridData threadSelectionGridData; + private GridData fileSelectionGridData; + private GridData deviceThreadTableGridData; + private GridData importedHeapTableGridData; + private GridData loadThreadListGridData; + private GridData connectionGridData; + private GridData connectionButtonGridData; + private GridData connectionNameInUseGridData; + private GridData threadFilterTypesGridData; + private GridData threadFilterGridData; + + private Group compareGroup; + + + private Group fileSelectionGroup; + private Composite fileLocationGroup; + private Composite fileThreadListGroup; + + private Group radioButtonGroup; + private Group threadSelectionGroup; + private Composite threadListGroup; + private Composite threadButtonGroup; + + /** + * Table that is shown when getting heap From File System. + */ + private Table fileThreadTable; + /** + * Table which contents can be loaded/refreshed from the device. + */ + private Table deviceThreadTable; + /** + * Table that contains two heaps that are to be compared when Import and compare is selected. + */ + private Table comparedHeapsTable; + /** + * Table in second page, where only imported heap can be selected. + */ + private Table importedHeapTable; + + /** + * Text field for setting filter text. + */ + private String filterText; + /** + * Filter text. + */ + private Text threadFilterText; + /** + * Combo for filtering types. + */ + private Combo threadFilterTypesCombo; + + // Thread list from one file + private ArrayList fileThreadList; + + // selected thread from thread list + private ThreadInfo comparedThread; + + // Decoder Engine + private MemSpyLogParserEngine engine; + + // Thread list received from usb/musti + ArrayList deviceThreadList; + + // TraceCore engine + TraceCoreEngine traceEngine; + + // List of received heaps: + ArrayList receivedHeaps; + + // Heap that is currently received + ThreadInfo receivedHeap; + + // this pages UserEnterData section + ValueTypes section; + + // viewed error message + String errorMessage; + + // Type of this page + PageType pageType; + + // boolean variable, which is set to true if some MemSpy operation is running. + boolean memSpyOperationRunning; + + // MemSpy operation processes: + // receive thread list + IRunnableWithProgress receiveThreadListProcess; + // receive heap + IRunnableWithProgress receiveHeapProcess; + + + //Strings + + private final static String FILE_SELECTION_DIALOG_TEXT = "Select Heap Dump File"; + private final static String GET_HEAP_RADIO_BUTTON = "Get Heap:"; + private final static String GET_HEAP_FROM_FILE_RADIO_BUTTON = "From File System"; + private final static String GET_HEAP_FROM_DEVICE_RADIO_BUTTON = "From Device via TraceViewer"; + private final static String HEAP_DUMP_LOCATION_TEXT = "Define Location of Heap Dump File:"; + private final static String BROWSE_TEXT = "Browse..."; + private final static String HEAP_CONTAINS_TEXT_IMPORT = "Selected file contains heaps from following threads."; + private final static String HEAP_CONTAINS_TEXT_COMPARE = "Selected file contains heaps from following threads, select thread which heap needs to be compared."; + private final static String THREAD_NAME_TEXT = "Thread Name"; + private final static String SELECT_THREAD_TEXT = GET_HEAP_FROM_DEVICE_RADIO_BUTTON; + private final static String SELECT_FILE_TEXT = GET_HEAP_FROM_FILE_RADIO_BUTTON; + private final static String LOAD_REFRESH_THREAD_LIST_BUTTON = "Load/Refresh Thread List"; + private final static String CONNECTION_SETTINGS_BUTTON = "Connection Settings..."; + private final static String CURRENTLY_USING_TEXT = "Currently using:"; + private final static String GET_HEAP_NOW_BUTTON = "Get Selected Heap Now"; + private final static String HEAP_DUMP_RECEIVED = "Heap Dump Received"; + private final static String RECEIVING_THREAD_LIST = "Receiving Thread List: "; + private final static String RECEIVING_HEAP_DUMP = "Receiving Heap Dump: "; + private final static String HEAP_DUMPS_RECEIVED = " Heap Dumps Received"; + private final static String COMPARE_HEAPS = "Compared heaps"; + + + // Error/warning messages + private final static String ERROR_INVALID_FILE = "Invalid heap dump file. The file doesn't contain any threads with binary data information."; + private final static String ERROR_FILE_NOT_FOUND = "File not found"; + private final static String SELECT_COMPARED_THREAD = "Select thread which heap needs to be compared"; + private final static String WARNING_HEAPS_NOT_FROM_SAME_THREAD = "Compared heaps are not from same thread"; + + private final static String ERROR_DRM_THREAD = "Heaps from threads which name contains word \"drm\" cannot be received due to security policies."; + private final static String ERROR_DBGTRS_THREAD = "Heaps from threads which name contains word \"dbgtrcserver::!DbgTrcServer\" cannot be received due to Trace restrictions."; + + + /** + * DeviceOrFileSelectionPage(String pageName) + * Constructor + * @param pagename name of this wizard page + */ + protected DeviceOrFileSelectionPage( String pageName, String title, String description, ValueTypes section, + PageType pageType, TraceCoreEngine traceEngine ) { + super(pageName); + setTitle( title ); + setDescription( description ); + this.engine = new MemSpyLogParserEngine(); + this.fileThreadList = new ArrayList(); + this.deviceThreadList = new ArrayList(); + this.traceEngine = traceEngine; + this.receivedHeaps = new ArrayList(); + this.receivedHeap = new ThreadInfo(); + this.section = section; + this.errorMessage = ""; + this.pageType = pageType; + this.comparedThread = null; + memSpyOperationRunning = false; + this.createMemSpyProcesses(); + this.filterText = ""; + } + + /** + * (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus() + */ + + public void setInitialFocus() { + fileCombo.setFocus(); + } + + /** + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + this.getHeapButtonPressed(); + } + + /** + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + if (e.widget == buttonBrowseFile) { + // open file dialog for selecting a Heap Dump file + FileDialog dialog = new FileDialog(this.getShell()); + dialog.setText(FILE_SELECTION_DIALOG_TEXT); + String[] filterExt = { "*.txt", "*.log", "*.*" }; + dialog.setFilterExtensions(filterExt); + dialog.setFilterPath(fileCombo .getText()); + String result = dialog.open(); + if (result != null ){ + fileCombo.setText(result); + } + + } + + // Update controls after radio buttons state changes to false + else if ( ( e.widget == deviceRadioButton && deviceRadioButton.getSelection() == false ) || + ( e.widget == fileRadioButton && fileRadioButton.getSelection() == false ) ){ + this.hideAndRevealItems(); + getWizard().getContainer().updateButtons(); + + MemSpyWizard wizard = (MemSpyWizard) getWizard(); + if( this.pageType != PageType.IMPORT_PAGE ){ + wizard.setComparedHeaps(); + } + + } + + // Open connection settings. + else if ( e.widget == connectionSettingsButton ){ + // Open connection Trace viewers connection settings. + Shell shell = MemSpyPlugin.getCurrentlyActiveWbWindowShell(); + PreferenceUtils.openPreferencePage(MemSpyPlugin.getTraceProvider().getTraceSourcePreferencePageId(), shell); + + // Disconnect trace source so that new settings are used when sending next request + MemSpyPlugin.getTraceProvider().disconnectTraceSource(); + + MemSpyWizard wizard = (MemSpyWizard) this.getWizard(); + // update new settings to each wizard page. + wizard.updateConnectionSettings(); + } + + // Load thread list from device + else if ( e.widget == loadThreadListButton ){ + this.loadThreadListButtonPressed(); + } + else if ( e.widget == getHeapButton ){ + this.getHeapButtonPressed(); + } + else if( e.widget == deviceThreadTable ){ + this.enableAndDisableGetHeapButton(); + } + else if( e.widget == importedHeapTable ){ + this.enableAndDisableGetHeapButton(); + } + else if( e.widget == fileThreadTable ){ + + // get selection index from thread table + int selectionIndex = fileThreadTable.getSelectionIndex(); + + // set selected heap as compared heap + comparedThread = fileThreadList.get( selectionIndex ); + + // get wizard and update compared thread names + MemSpyWizard wizard = (MemSpyWizard)this.getWizard(); + wizard.setComparedHeaps(); + + wizard.showImportedHeapsInComparePage( false ); + + // update buttons + getWizard().getContainer().updateButtons(); + + // Set selection back to table after updatebuttons has cleared it. + fileThreadTable.setSelection( selectionIndex ); + + } + else if( e.widget == threadFilterTypesCombo) { + updateThreadList(); + } + + + } + + /** + * (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + public void modifyText(ModifyEvent event) { + if (event.widget.equals(fileCombo)) { + try { + getWizard().getContainer().updateButtons(); + } catch (Exception e) { + } + } + else if (event.widget.equals(threadFilterText)) { + filterText = threadFilterText.getText(); + updateThreadList(); + } + } + + /** + * (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates() + */ + public void recalculateButtonStates() { + + } + + + /** + * hideAndRevealItems() + * Hides and reveals controls according to radiobutton states. + */ + private void hideAndRevealItems() { + + // get radiobutton selection + boolean fileSelected = true; + if( deviceRadioButton.getSelection() == false ){ + fileSelected = false; + } + + // exlude/include needed controls + fileSelectionGridData.exclude = fileSelected; + threadSelectionGridData.exclude = !fileSelected; + + if( fileSelected ){ + // Since excluded groups size and location are not updated, do it now + threadSelectionGroup.setSize( fileSelectionGroup.getSize() ); + threadSelectionGroup.setLocation(fileSelectionGroup.getLocation()); + + } + else{ + // Since excluded groups size and location are not updated, do it now + fileSelectionGroup.setSize( threadSelectionGroup.getSize() ); + fileSelectionGroup.setLocation(threadSelectionGroup.getLocation()); + + } + // Hide/show needed controls + fileSelectionGroup.setVisible(!fileSelected); + threadSelectionGroup.setVisible(fileSelected); + + + + } + + + /** + * canFinish() + * Returns false, because symbol files must be defined always. + */ + public boolean canFinish() + { + return false; + } + + + + public boolean refreshFileThreadList(){ + + File file = new File(fileCombo.getText()); + + // If file exists + if (file.isFile() && file.exists()) { + + // Empty thread list table + fileThreadTable.removeAll(); + + fileThreadList.clear(); + + // Check that file is Heap Dump file and display thread names in table. + if ( engine.isFileHeapDumpFile(file, fileThreadList) ) { + this.setErrorMessage(null); + + + for( int i = 0; i < fileThreadList.size(); i++ ){ + TableItem newItem = new TableItem(fileThreadTable, SWT.NONE,i); + newItem.setText(fileThreadList.get(i).getThreadName()); + } + if( fileThreadList.size() == 1 ){ + comparedThread = fileThreadList.get(0); + ((MemSpyWizard)this.getWizard()).setComparedHeaps(); + } + + // If comparing heaps and no heap is selected as compared heap + if( comparedThread == null && this.pageType != PageType.IMPORT_PAGE){ + this.setErrorMessage(SELECT_COMPARED_THREAD); + return false; + } + else{ + // if importing heaps, set first heap as compared heap. + if( this.pageType == PageType.IMPORT_PAGE ){ + comparedThread = fileThreadList.get(0); + } + return true; + } + } + else { + this.setErrorMessage(ERROR_INVALID_FILE); + return false; + } + } + else { + this.setErrorMessage(ERROR_FILE_NOT_FOUND ); + return false; + } + + } + + /** + * (non-Javadoc) + * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage() + */ + + public boolean canFlipToNextPage() { + + if( fileRadioButton.getSelection() ){ + try { + if( !this.refreshFileThreadList() ){ + return false; + } + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + else{ // deviceRadioButton.getSelection() + if( receivedHeaps.size() > 0 ){ + this.setErrorMessage(null); + } + else{ + this.setErrorMessage(null); + return false; + } + } + + if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){ + MemSpyWizard wizard = (MemSpyWizard)this.getWizard(); + if( !wizard.areComparedHeapsFromSameThread() ){ + this.setMessage(WARNING_HEAPS_NOT_FROM_SAME_THREAD, ERROR); + if( this.pageType == PageType.COMPARE_SECOND_HEAP ){ + return false; + } + } + else{ + this.setMessage(null); + } + } + return true; + + + + + } + + + /** + * loadUserEnteredData + * Loads previously used values and selections into UI components + */ + + private void loadUserEnteredData(){ + + // restore previous state of radio buttons. + // if last value is not found, set selection file. + + UserEnteredData data = new UserEnteredData(); + int lastUsedSource = data.getPreviousRadioButtonSelection(section); + + // Restoring previous state of radio buttons only if device import is also possible and was previously selected + if(MemSpyPlugin.isTraceProviderAvailable() && lastUsedSource == DEVICE_RADIO_BUTTON_SELECTION_INDEX){ + deviceRadioButton.setSelection( true ); + fileRadioButton.setSelection( false ); + } + else{ + deviceRadioButton.setSelection( false ); + fileRadioButton.setSelection( true ); + } + + // Restore previous values to file combobox + String[] lastUsedFiles = data.getPreviousValues( section ); + if ( lastUsedFiles != null ) { + fileCombo.setItems( lastUsedFiles ); + fileCombo.select(0); + } + + } + + /** + * saveUserEnteredData. + * Saves user entered values and selections. + */ + public void saveUserEnteredData(){ + UserEnteredData data = new UserEnteredData(); + + // Save Action radio-buttons state + if( deviceRadioButton.getSelection() ){ + data.saveRadioButtonSelection(section, 2); + } + else { + data.saveRadioButtonSelection(section, 1); + } + + // Save file combo box + String item = fileCombo.getText(); + data.saveValue(section, item); + + + + } + + /** + * enableAndDisableGetHeapButton. + * Enables/Disables "Get Heap Now" -button regarding wizard's state + */ + private void enableAndDisableGetHeapButton(){ + final PageType type = this.pageType; + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + if( type == PageType.COMPARE_SECOND_HEAP && !importedHeapTableGridData.exclude ) { + getHeapButton.setEnabled( true ); + } + else if( deviceThreadTable.getSelectionCount() == 1 ){ + getHeapButton.setEnabled( true ); + } + else{ + getHeapButton.setEnabled( false ); + } + } + }; + Display.getDefault().asyncExec(updateUiRunnable); + + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction) + */ + public void operationFinished( LauncherAction action ){ + + + this.memSpyOperationRunning = false; + + if( action == LauncherAction.GET_HEAP_DUMP ){ + this.updateReceivedHeap(); + } + else if( action == LauncherAction.GET_THREAD_LIST ){ + + // command wizard to update all thread tables from all wizard pages + ((MemSpyWizard)this.getWizard()).updateThreadLists( this.deviceThreadList ); + } + + + } + + /** + * updateReceivedHeap. + * Does all actions that are done when Heap Dump file has been received. + */ + private void updateReceivedHeap(){ + receivedHeaps.add( receivedHeap ); + + + if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){ + comparedThread = receivedHeap; + } + + final MemSpyWizard wizard = (MemSpyWizard)this.getWizard(); + + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + + // if this is import page, update UI's receivedHeaps-text + if( pageType == PageType.IMPORT_PAGE ){ + heapsReceivedLabel.setText( Integer.toString( receivedHeaps.size() ) + HEAP_DUMPS_RECEIVED ); + threadButtonGroup.layout(); + } + + // If this is compare heaps page, command wizard to update all compare-tables. + else{ + wizard.setComparedHeaps(); + } + + // hide thread list selection in second compare page. + if( pageType == PageType.COMPARE_FIRST_HEAP ){ + wizard.showImportedHeapsInComparePage( true ); + } + + // Getting selected item from currently active table + TableItem item; + if( pageType == PageType.COMPARE_SECOND_HEAP && importedHeapTable.isVisible() ) { + item = importedHeapTable.getItem( importedHeapTable.getSelectionIndex() ); + } else { + item = deviceThreadTable.getItem( deviceThreadTable.getSelectionIndex() ); + } + ThreadInfo thread = (ThreadInfo)item.getData(); + + // Imported threads needs to be updated from first compare page. + if( pageType == PageType.COMPARE_FIRST_HEAP ) { + // sets thread list selection in 2. comparePage + wizard.setThreadListSelectionToComparePages( thread ); + } + + // get date formatter + SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT ); + String date = formatter.format( receivedHeap.getDate() ); + item.setText( 1, date ); + // Date is saved to thread information so that it will be available if table is sorted. + thread.setStatus(date); + } + + }; + + // needs to be called from UI thread. + Display.getDefault().asyncExec(updateUiRunnable); + } + + /** + * Updates list and uses current filtering. + */ + public void updateThreadList(){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + String filter = filterText; + deviceThreadTable.removeAll(); + for( ThreadInfo thread : deviceThreadList ) { + if(threadFilterTypesCombo.getSelectionIndex() == 0) { + // Starts with filter. + if(thread.getThreadName().toLowerCase().startsWith(filter.toLowerCase())) { + TableItem newItem = new TableItem(deviceThreadTable, SWT.NONE); + newItem.setText( new String[]{ thread.getThreadName(), thread.getStatus() } ); + newItem.setData(thread); + } + } else { + // Contains filter. + if(thread.getThreadName().toLowerCase().contains(filter.toLowerCase())) { + TableItem newItem = new TableItem(deviceThreadTable, SWT.NONE); + newItem.setText( new String[]{ thread.getThreadName(), thread.getStatus() } ); + newItem.setData(thread); + } + } + } + + // update wizard buttons + getWizard().getContainer().updateButtons(); + // Update get heap button. + enableAndDisableGetHeapButton(); + } + }; + Display.getDefault().asyncExec(updateUiRunnable); + + } + + /** + * updateConnectionText + * updates connection text to match used settings + */ + + public void updateConnectionText(){ + // Updating connection name. + String displayName = MemSpyPlugin.getTraceProvider().getDisplayNameForCurrentConnection(); + connectionNameInUseLabel.setText(displayName); + // Update layout. + threadSelectionGroup.layout(); + threadButtonGroup.layout(); + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#deviceError(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherErrorType) + */ + public void deviceError( final LauncherErrorType error ){ + + Date date = new Date (System.currentTimeMillis()); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "DeviceOrFileSelectionPage.deviceError: '" + error.name() +"' time:'" +date.toString() + "'."); //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ + memSpyOperationRunning = false; + + // Getting user visible error message + errorMessage = UiUtils.getErrorMessageForLauncherError(error, traceEngine.getAdditionalErrorInformation(), traceEngine.getProgressStatus()); //$NON-NLS-1$ + + // Handling HeapDump query-specific logic related to the error + switch (error){ + case HEAP_NOT_FOUND:{ + errorMessage = ERROR_HEAP_NOT_FOUND; + this.receivedHeap = null; + break; + } + } + + // Advising user to install launcher component to the device + UiUtils.showErrorDialogToUser(error, errorMessage, traceEngine.getProgressStatus()); + + } + + /** + * Gets trace engine object instance. + * @return used TraceEngine-object + */ + public TraceCoreEngine getTraceEngine() { + return traceEngine; + } + + + /** + * Sets thread info into comparedHeaps-table. + * @param firstHeap first compared heap + * @param secondHeap second compared heap + */ + public void setComparedHeap( final ThreadInfo firstHeap, final ThreadInfo secondHeap ){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + comparedHeapsTable.removeAll(); + TableItem firstItem = new TableItem(comparedHeapsTable, SWT.NONE, 0 ); + TableItem secondItem = new TableItem(comparedHeapsTable, SWT.NONE, 1 ); + + // get date formatter + SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT ); + if( firstHeap != null){ + firstItem.setText( new String[]{ firstHeap.getThreadName(), formatter.format( firstHeap.getDate() ) } ); + } + if( secondHeap != null ){ + secondItem.setText( new String[]{ secondHeap.getThreadName(), formatter.format( secondHeap.getDate() ) } ); + } + + } + + }; + Display.getDefault().asyncExec(updateUiRunnable); + } + + /** + * setThreadListSelection. + * Sets thread list selection into given index and updates thread list selection into importedHeapTable if needed + * @param thread Thread information. + */ + public void setThreadListSelection( final ThreadInfo thread ){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + if( pageType == PageType.COMPARE_SECOND_HEAP ){ + ThreadInfo importedThread = thread.clone(); + + importedHeapTable.removeAll(); + // Get selected item from deviceThread + TableItem importedItem = new TableItem( importedHeapTable, SWT.NONE, 0 ); + + // copy selected item data into importedThread + importedItem.setText(new String[]{ importedThread.getThreadName(), importedThread.getStatus() }); + importedItem.setData(importedThread); + + // select thread in importedHeapTable + importedHeapTable.setSelection( 0 ); + + enableAndDisableGetHeapButton(); + } + } + + }; + Display.getDefault().asyncExec(updateUiRunnable); + } + + /** + * setDeviceThreadList. + * @param deviceThreadList new deviceThreadList + */ + public void setDeviceThreadList(ArrayList deviceThreadList) { + this.deviceThreadList = deviceThreadList; + } + + /** + * getRecentHeap + * @return last received Heap's thread info. + */ + public ThreadInfo getRecentHeap(){ + if( this.deviceRadioButton.getSelection() ){ + if( receivedHeaps.size() > 0 ){ + ThreadInfo returnValue = receivedHeaps.get( receivedHeaps.size()-1 ); + return returnValue; + } + else{ + return null; + } + } + else{ + if(comparedThread != null ){ + return comparedThread; + } + else{ + return null; + } + } + } + + /** + * getImportedHeaps. + * @return imported heaps + */ + public ArrayList getImportedHeaps() { + if( this.deviceRadioButton.getSelection() ){ + return receivedHeaps; + } + else{ + return fileThreadList; + } + } + + /** + * updateConnectionSettings. + * Updates new connection settings to UI + */ + public void updateConnectionSettings() { + this.updateConnectionText(); + } + + /** + * setImportedThreadTableVisible. + * Shows/Hides importedHeapTable + * @param value true if importedHeapsTable should be shown. + */ + public void setImportedThreadTableVisible( boolean value ){ + if( this.pageType == PageType.COMPARE_SECOND_HEAP ){ + + deviceThreadTableGridData.exclude = value; + deviceThreadTable.setVisible( !value ); + + importedHeapTableGridData.exclude = !value; + importedHeapTable.setVisible( value ); + + loadThreadListGridData.exclude = value; + loadThreadListButton.setVisible( !value ); + + connectionButtonGridData.exclude = value; + connectionSettingsButton.setVisible( !value ); + + connectionGridData.exclude = value; + connectionTextLabel.setVisible( !value ); + + connectionNameInUseGridData.exclude = value; + connectionNameInUseLabel.setVisible( !value ); + + threadFilterGridData.exclude = value; + threadFilterText.setVisible( !value ); + + threadFilterTypesGridData.exclude = value; + threadFilterTypesCombo.setVisible( !value ); + + if( value == true ){ + + threadButtonGroup.setLayoutData( new GridData( GridData.FILL_BOTH)); + } + else{ + threadButtonGroup.setLayoutData( new GridData( GridData.VERTICAL_ALIGN_CENTER)); + + } + threadButtonGroup.layout(); + + + } + + threadSelectionGroup.layout(); + threadListGroup.layout(); + + enableAndDisableGetHeapButton(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + + Composite composite = new Composite(parent, SWT.NULL); + + // create the desired layout for this wizard page + GridLayout gl = new GridLayout(); + gl.numColumns = 1; + composite.setLayout(gl); + + if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){ + GridLayout compareGroupGridLayout = new GridLayout(); + compareGroupGridLayout.numColumns = 2; + compareGroup = new Group(composite, SWT.NONE); + compareGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + compareGroup.setText(COMPARE_HEAPS); + compareGroup.setLayout(compareGroupGridLayout); + + + // Table that contains all thread names and id's + comparedHeapsTable = new Table(compareGroup, SWT.BORDER); + TableColumn heapNameColumn = new TableColumn(comparedHeapsTable, SWT.LEFT); + heapNameColumn.setText(THREAD_NAME_TEXT); + heapNameColumn.setWidth(200); + TableColumn receivedColumn = new TableColumn(comparedHeapsTable, SWT.LEFT); + receivedColumn.setText(HEAP_DUMP_RECEIVED); + receivedColumn.setWidth(150); + comparedHeapsTable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + comparedHeapsTable.setHeaderVisible(true); + + + TableItem newItem = new TableItem(comparedHeapsTable, SWT.NONE,0); + newItem.setText( new String[]{ "", "" } ); + TableItem newItem1 = new TableItem(comparedHeapsTable, SWT.NONE,1); + newItem1.setText( new String[]{ "", "" } ); + + + } + + + // Radio button group + GridLayout radioButtonGroupGridLayout = new GridLayout(); + radioButtonGroup = new Group(composite, SWT.NONE); + radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + radioButtonGroup.setText(GET_HEAP_RADIO_BUTTON); + radioButtonGroup.setLayout(radioButtonGroupGridLayout); + GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL); + radioButtonGridData.horizontalSpan = 2; + + // Heap Dump File radio button + fileRadioButton = new Button(radioButtonGroup, SWT.RADIO); + fileRadioButton.setText(GET_HEAP_FROM_FILE_RADIO_BUTTON); + fileRadioButton.setLayoutData(radioButtonGridData); + fileRadioButton.addSelectionListener(this); + fileRadioButton.setSelection(true); + + // From Device via TraceViewer radio button + deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO); + deviceRadioButton.setText(GET_HEAP_FROM_DEVICE_RADIO_BUTTON); + deviceRadioButton.setLayoutData(radioButtonGridData); + deviceRadioButton.addSelectionListener(this); + deviceRadioButton.setSelection(false); + + // In case trace plugin is not available, disabling import from device selection + if(!MemSpyPlugin.isTraceProviderAvailable()){ + deviceRadioButton.setEnabled(false); + } + + // File selection group + + fileSelectionGroup = new Group(composite, SWT.NONE); + GridLayout fileSelectionGridLayout = new GridLayout(); + fileSelectionGridLayout.numColumns = 1; + + fileSelectionGridData = new GridData(GridData.FILL_BOTH); + fileSelectionGroup.setLayoutData(fileSelectionGridData); + fileSelectionGroup.setLayout(fileSelectionGridLayout); + fileSelectionGroup.setText(SELECT_FILE_TEXT); + + // File location composite + fileLocationGroup = new Composite(fileSelectionGroup, SWT.NONE); + GridLayout fileLocationGridLayout = new GridLayout(); + fileLocationGridLayout.numColumns = 2; + GridData fileLocationGridData = new GridData(GridData.FILL_HORIZONTAL); + fileLocationGroup.setLayoutData(fileLocationGridData); + fileLocationGroup.setLayout(fileLocationGridLayout); + + // Define location label + Label defineFileLocation = new Label(fileLocationGroup, SWT.NONE); + defineFileLocation.setText( HEAP_DUMP_LOCATION_TEXT ); + GridData defineFileLocationGridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + defineFileLocationGridData.horizontalSpan = 2; + defineFileLocation.setLayoutData(defineFileLocationGridData); + + // File location combo + fileCombo = new Combo(fileLocationGroup, SWT.BORDER); + GridData fileDataGrid = new GridData(GridData.FILL_HORIZONTAL); + + fileCombo.setLayoutData(fileDataGrid); + fileCombo.addModifyListener(this); + + // Browse-button + buttonBrowseFile = new Button(fileLocationGroup, SWT.PUSH); + buttonBrowseFile.setText(BROWSE_TEXT); + buttonBrowseFile.addSelectionListener(this); + + // File location group + fileThreadListGroup = new Composite(fileSelectionGroup, SWT.NONE); + GridLayout fileThreadListGridLayout = new GridLayout(); + fileThreadListGridLayout.numColumns = 1; + + GridData fileThreadListGridData = new GridData(GridData.FILL_BOTH); + fileThreadListGroup.setLayoutData(fileThreadListGridData); + fileThreadListGroup.setLayout(fileThreadListGridLayout); + + + // Define location label + Label threadsFromFileLabel = new Label(fileThreadListGroup, SWT.NONE); + if( this.pageType == PageType.IMPORT_PAGE ){ + threadsFromFileLabel.setText( HEAP_CONTAINS_TEXT_IMPORT ); + } + else{ + threadsFromFileLabel.setText( HEAP_CONTAINS_TEXT_COMPARE ); + } + threadsFromFileLabel.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING) ); + + // Threads from file table + fileThreadTable = new Table(fileThreadListGroup, SWT.BORDER); + TableColumn nameColumn = new TableColumn(fileThreadTable, SWT.LEFT); + nameColumn.setText(THREAD_NAME_TEXT); + nameColumn.setWidth(250); + fileThreadTable.setLayoutData(new GridData(GridData.FILL_BOTH)); + fileThreadTable.setHeaderVisible(true); + fileThreadTable.setItemCount(5); + + if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){ + fileThreadTable.addSelectionListener(this); + } + + + // Thread Selection group + + threadSelectionGroup = new Group(composite, SWT.NONE); + GridLayout threadSelectionGridLayout = new GridLayout(); + threadSelectionGridLayout.numColumns = 2; + + + threadSelectionGridData = new GridData(GridData.FILL_BOTH); + threadSelectionGroup.setLayoutData(threadSelectionGridData); + threadSelectionGroup.setLayout(threadSelectionGridLayout); + threadSelectionGroup.setText(SELECT_THREAD_TEXT); + + // Thread list Group + threadListGroup = new Composite(threadSelectionGroup, SWT.NONE); + GridLayout threadListLayout = new GridLayout(); + threadListLayout.numColumns = 2; + threadListGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + threadListGroup.setLayout(threadListLayout); + + // Filter text field. + threadFilterText = new Text(threadListGroup, SWT.BORDER); + threadFilterText.setText("type filter text"); + threadFilterGridData = new GridData(GridData.FILL_HORIZONTAL); + threadFilterGridData.grabExcessHorizontalSpace = true; + threadFilterGridData.grabExcessVerticalSpace = false; + threadFilterGridData.verticalAlignment = SWT.TOP; + threadFilterText.setLayoutData(threadFilterGridData); + + threadFilterText.addModifyListener(this); + + // Filter selection combo. + threadFilterTypesCombo = new Combo(threadListGroup, SWT.BORDER|SWT.READ_ONLY); + threadFilterTypesCombo.setItems(new String[]{"Starts with", "Contains"}); + threadFilterTypesGridData = new GridData(); + threadFilterTypesGridData.widthHint = 100; + threadFilterTypesCombo.select(0); + threadFilterTypesCombo.setLayoutData(threadFilterTypesGridData); + + threadFilterTypesCombo.addSelectionListener(this); + + // Table that contains all thread names and id's + deviceThreadTable = new Table(threadListGroup, SWT.BORDER); + + TableColumn deviceThreadColumn = new TableColumn(deviceThreadTable, SWT.LEFT); + deviceThreadColumn.setText(THREAD_NAME_TEXT); + deviceThreadColumn.setWidth(200); + TableColumn receivedColumn = new TableColumn(deviceThreadTable, SWT.LEFT); + receivedColumn.setText(HEAP_DUMP_RECEIVED); + receivedColumn.setWidth(150); + deviceThreadTableGridData = new GridData(GridData.FILL_BOTH); + deviceThreadTableGridData.horizontalSpan = 2; + deviceThreadTable.setLayoutData( deviceThreadTableGridData ); + deviceThreadTable.setHeaderVisible(true); + deviceThreadTable.addSelectionListener( this ); + + if( this.pageType == PageType.COMPARE_SECOND_HEAP ){ + // Table where first imported heaps name is presented + importedHeapTable = new Table( threadListGroup, SWT.BORDER ); + TableColumn importedThreadNameColumn = new TableColumn( importedHeapTable, SWT.LEFT ); + importedThreadNameColumn.setText( THREAD_NAME_TEXT ); + importedThreadNameColumn.setWidth( 200 ); + TableColumn importedWhenColumn = new TableColumn( importedHeapTable, SWT.LEFT ); + importedWhenColumn.setText( HEAP_DUMP_RECEIVED ); + importedWhenColumn.setWidth( 150 ); + //importedHeapTableGridData = new GridData(GridData.GRAB_VERTICAL); + importedHeapTableGridData = new GridData(GridData.FILL_HORIZONTAL); + importedHeapTable.setLayoutData( importedHeapTableGridData ); + importedHeapTable.setHeaderVisible( true ); + importedHeapTable.addSelectionListener( this ); + } + + // Thread button group + threadButtonGroup = new Composite(threadSelectionGroup, SWT.NONE); + GridLayout threadButtonLayout = new GridLayout(); + threadButtonLayout.numColumns = 1; + + GridData threadButtonGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + threadButtonGroup.setLayoutData(threadButtonGridData); + threadButtonGroup.setLayout(threadButtonLayout); + + loadThreadListButton = new Button(threadButtonGroup, SWT.PUSH); + loadThreadListGridData = new GridData(GridData.FILL_HORIZONTAL); + loadThreadListButton.setLayoutData( loadThreadListGridData ); + loadThreadListButton.setText(LOAD_REFRESH_THREAD_LIST_BUTTON); + loadThreadListButton.addSelectionListener( this ); + + // Connection settings button + + connectionSettingsButton = new Button(threadButtonGroup, SWT.PUSH); + connectionButtonGridData = new GridData(GridData.FILL_HORIZONTAL); + connectionSettingsButton.setLayoutData( connectionButtonGridData ); + connectionSettingsButton.setText(CONNECTION_SETTINGS_BUTTON); + connectionSettingsButton.addSelectionListener(this); + + // Connection settings labels + connectionTextLabel = new Label(threadButtonGroup, SWT.LEFT); + connectionTextLabel.setText(CURRENTLY_USING_TEXT); + connectionGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + connectionTextLabel.setLayoutData( connectionGridData ); + + connectionNameInUseLabel = new Label(threadButtonGroup, SWT.LEFT); + connectionNameInUseGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + connectionNameInUseLabel.setLayoutData( connectionNameInUseGridData ); + + // Get Heap button + + getHeapButton = new Button(threadButtonGroup, SWT.PUSH); + getHeapButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + getHeapButton.setText(GET_HEAP_NOW_BUTTON); + getHeapButton.addSelectionListener( this ); + this.enableAndDisableGetHeapButton(); + + if( this.pageType == PageType.IMPORT_PAGE ){ + heapsReceivedLabel = new Label(threadButtonGroup, SWT.LEFT); + heapsReceivedLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + heapsReceivedLabel.setText( "0" + HEAP_DUMPS_RECEIVED ); + } + // load saved user entered data. + this.loadUserEnteredData(); + + // update buttons and texts on screen. + this.updateConnectionText(); + this.hideAndRevealItems(); + this.setImportedThreadTableVisible( false ); + + setHelps(); + setInitialFocus(); + setControl(composite); + } + + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction, com.nokia.s60tools.memspy.containers.SWMTLogInfo) + */ + public void operationFinished(LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning) { + // Can be left empty. + + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#startedReceivingSWMTLog() + */ + public void startedReceivingSWMTLog() { + // Can be left empty. + + } + + private void loadThreadListButtonPressed(){ + deviceThreadList.clear(); + if( traceEngine.requestThreadList( deviceThreadList, (DeviceOrFileSelectionPage)getWizard().getContainer().getCurrentPage() ) ){ + try { + getContainer().run(true, false, receiveThreadListProcess); + } catch (InvocationTargetException e1) { + e1.printStackTrace(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + else{ + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); + } + } + + /** + * getHeapButtonPressed. + * Method that is called when "Get Heap Now"-button is pressed. + */ + private void getHeapButtonPressed(){ + // Imported thread is loaded, if it is importedHeapTable is visible. + ThreadInfo thread; + if(this.pageType == PageType.COMPARE_SECOND_HEAP && importedHeapTable.isVisible()) { + if(importedHeapTable.getSelectionIndex() == -1) { + // No selection, nothing to do. + return; + } + thread = (ThreadInfo)importedHeapTable.getSelection()[0].getData(); + } else { + if(deviceThreadTable.getSelectionIndex() == -1) { + // No selection, nothing to do. + return; + } + thread = (ThreadInfo)deviceThreadTable.getSelection()[0].getData(); + } + + // if thread name contains text "drm" it cannot be requested because of security reasons + if( thread.getThreadName().toLowerCase().contains("drm") ){ + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_DRM_THREAD); + return; + } + // if thread name contains text "dbgtrcserver::!DbgTrcServer" it cannot be requested because of TraceCore + else if(thread.getThreadName().toLowerCase().contains("dbgtrcserver::!dbgtrcserver") ){ + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_DBGTRS_THREAD); + return; + } + + String threadID = thread.getThreadID(); + Date date = new Date(); + String threadName = thread.getThreadName(); + + // Get file name for heap dump from engine + String filePath = MemSpyFileOperations.getFileNameForTempHeapDump( threadName, date); + + // Add new file into receivedHeaps-ArrayList + receivedHeap = new ThreadInfo(); + receivedHeap.setThreadFilePath(filePath); + receivedHeap.setThreadID(threadID); + receivedHeap.setThreadName(threadName); + receivedHeap.setDate(date); + receivedHeap.setType(HeapDumpType.DEVICE); + + + if( traceEngine.requestHeapDump( threadID, this, filePath ) ){ + + try { + getContainer().run(true, false, receiveHeapProcess); + } catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + } + else{ + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); + receivedHeap = null; + } + + getWizard().getContainer().updateButtons(); + + } + + /** + * createMemSpyProcesses. + * Creates MemSpy operation processes. + */ + private void createMemSpyProcesses(){ + + // receive thread list process + receiveThreadListProcess = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + memSpyOperationRunning = true; + monitor.beginTask(RECEIVING_THREAD_LIST, IProgressMonitor.UNKNOWN); + while(true){ + // some delay, so that launcher has time to set it's state correct. + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // do nothing + } + if( !memSpyOperationRunning ){ + break; + } + } + monitor.done(); + } + }; + + // receive heap process. + receiveHeapProcess = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + memSpyOperationRunning = true; + monitor.beginTask(RECEIVING_HEAP_DUMP, IProgressMonitor.UNKNOWN); + while(true){ + // some delay + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // do nothing + } + if( !memSpyOperationRunning ){ + break; + } + + } + monitor.done(); + + } + }; + } + + /** + * setHeapDumpFile. + * Sets parameter test to file combo box, selects file radio button and disables UI-components + * @param newFilePath new file path. + */ + public void setHeapDumpFile( final String newFilePath ){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + + if( deviceRadioButton.getSelection() ){ + // select file system-radio button + fileRadioButton.setSelection(true); + deviceRadioButton.setSelection(false); + hideAndRevealItems(); + } + // set text to file location combo box + fileCombo.setText( newFilePath ); + + // set selection buttons disabled. + fileCombo.setEnabled( false ); + buttonBrowseFile.setEnabled( false ); + deviceRadioButton.setEnabled(false); + + + } + }; + Display.getDefault().asyncExec(updateUiRunnable); + + } + + /** + * getSelectedFilePath. + * @return text value from file combo box. + */ + public String getSelectedFilePath(){ + return fileCombo.getText(); + } + + /** + * resetFileCombo. + * sets text field in file combo box empty. + */ + public void resetFileCombo(){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + fileCombo.setText( "" ); + } + }; + Display.getDefault().asyncExec(updateUiRunnable); + } + + + /** + * Sets this page's context sensitive helps + * + */ + protected void setHelps() { + + String helpContextId = null; + if( this.pageType == PageType.IMPORT_PAGE ){ + helpContextId = HelpContextIDs.MEMSPY_IMPORT_HEAP; + } + else{ + helpContextId = HelpContextIDs.MEMSPY_IMPORT_COMPARE; + } + PlatformUI.getWorkbench().getHelpSystem().setHelp( deviceRadioButton, helpContextId ); + PlatformUI.getWorkbench().getHelpSystem().setHelp( fileRadioButton, helpContextId); + PlatformUI.getWorkbench().getHelpSystem().setHelp( fileCombo, helpContextId); + PlatformUI.getWorkbench().getHelpSystem().setHelp( fileThreadTable, helpContextId); + + PlatformUI.getWorkbench().getHelpSystem().setHelp( loadThreadListButton, helpContextId ); + PlatformUI.getWorkbench().getHelpSystem().setHelp( connectionSettingsButton, helpContextId); + PlatformUI.getWorkbench().getHelpSystem().setHelp( getHeapButton, helpContextId); + PlatformUI.getWorkbench().getHelpSystem().setHelp( deviceThreadTable, helpContextId); + + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ExportFileNamePage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ExportFileNamePage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,233 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; + +public class ExportFileNamePage extends S60ToolsWizardPage implements ModifyListener, SelectionListener{ + + // UI-components + private Combo fileCombo; + private Button buttonBrowseFile; + + // Strings + private final static String REPORT_LOCATION_TEXT = "File Location"; + private final static String BROWSE_TEXT = "Browse..."; + private final static String FILE_SELECTION_DIALOG_TEXT = "Define location for exported file."; + private final static String OUTPUT_FILE_TEXT = "Output file"; + private final static String DESCRIPTION_TEXT = "Define file name for exported comparison report file(xls-file)."; + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus() + */ + public void setInitialFocus() { + fileCombo.setFocus(); + } + + + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates() + */ + public void recalculateButtonStates() { + } + + /** + * ExportFileNamePage + * constructor + * @param pageName name of the page + */ + protected ExportFileNamePage(String pageName) { + super(pageName); + setTitle(OUTPUT_FILE_TEXT); + setDescription(DESCRIPTION_TEXT); + } + + public void createControl(Composite parent) { + // Radio button group + Composite composite = new Composite(parent, SWT.NULL); + + // create the desired layout for this wizard page + GridLayout gl = new GridLayout(); + gl.numColumns = 1; + composite.setLayout(gl); + + // file location group + Group fileLocationGroup = new Group(composite, SWT.NONE); + fileLocationGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout fileLocationLayout = new GridLayout(); + fileLocationLayout.numColumns = 2; + fileLocationGroup.setLayout( fileLocationLayout ); + fileLocationGroup.setText( REPORT_LOCATION_TEXT ); + + // file combo + fileCombo = new Combo(fileLocationGroup, SWT.BORDER); + GridData fileDataGrid = new GridData(GridData.FILL_HORIZONTAL); + fileCombo.setLayoutData(fileDataGrid); + fileCombo.addModifyListener(this); + + // browse button + buttonBrowseFile = new Button(fileLocationGroup, SWT.PUSH); + buttonBrowseFile.setText(BROWSE_TEXT); + buttonBrowseFile.addSelectionListener(this); + + // load previous value + this.loadUserEnteredData(); + + setHelps(); + setInitialFocus(); + setControl(composite); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + public void modifyText(ModifyEvent event) { + + if (event.widget.equals(fileCombo)) { + try { + getWizard().getContainer().updateButtons(); + } catch (Exception e) { + } + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent arg0) { + + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + if (e.widget == buttonBrowseFile) { + // open file dialog for selecting a crash file + FileDialog dialog = new FileDialog(this.getShell(), SWT.SAVE ); + dialog.setText(FILE_SELECTION_DIALOG_TEXT); + String[] filterExt = { "*.xls" }; + dialog.setFilterExtensions(filterExt); + + dialog.setFilterPath(fileCombo.getText()); + String result = dialog.open(); + + // add xls-end if needed + if( !result.endsWith( ".xls" ) ){ + result += ".xls"; + } + + + + fileCombo.setText(result); + + } + + } + /* + * (non-Javadoc) + * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage() + */ + public boolean canFlipToNextPage() { + if( fileCombo.getText() != "" ){ + return true; + } + else { + return false; + + } + + } + + /** + * loadUserEnteredData + * loads previous values into UI components + */ + private void loadUserEnteredData(){ + UserEnteredData data = new UserEnteredData(); + + // Restore previous values to file combobox + String[] lastUsedFiles = data.getPreviousValues(ValueTypes.OUTPUT_FILE); + if (lastUsedFiles != null) { + fileCombo.setItems(lastUsedFiles); + fileCombo.select(0); + } + + + + } + + /** + * saveUserEnteredData + * Saves current user entered data from UI components + */ + public void saveUserEnteredData(){ + UserEnteredData data = new UserEnteredData(); + + // Save file combo box + String item = fileCombo.getText(); + data.saveValue(ValueTypes.OUTPUT_FILE, item); + } + + /** + * getOutputFileName + * @return output file name + */ + public String getOutputFileName(){ + return fileCombo.getText(); + } + + /** + * Sets this page's context sensitive helps + * + */ + protected void setHelps() { + PlatformUI.getWorkbench().getHelpSystem().setHelp( fileCombo, HelpContextIDs.MEMSPY_IMPORT_COMPARE); + PlatformUI.getWorkbench().getHelpSystem().setHelp( buttonBrowseFile, HelpContextIDs.MEMSPY_IMPORT_COMPARE); + PlatformUI.getWorkbench().getHelpSystem().setHelp( buttonBrowseFile, HelpContextIDs.MEMSPY_IMPORT_COMPARE); + + } + + +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizard.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,641 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; + + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.ui.IWorkbench; + +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; +import com.nokia.s60tools.memspy.containers.ThreadInfo; +import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator; +import com.nokia.s60tools.memspy.model.ImportEngine; +import com.nokia.s60tools.memspy.model.MemSpyFileOperations; +import com.nokia.s60tools.memspy.model.TraceCoreEngine; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.resources.ImageKeys; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; +import com.nokia.s60tools.memspy.ui.views.MemSpyMainView; +import com.nokia.s60tools.memspy.ui.wizards.DeviceOrFileSelectionPage.PageType; +import com.nokia.s60tools.memspy.ui.wizards.SelectActionPage.MemSpyAction; +import com.nokia.s60tools.ui.wizards.S60ToolsWizard; +import com.nokia.s60tools.util.debug.DbgUtility; + +public class MemSpyWizard extends S60ToolsWizard { + + public enum MemSpyWizardType{ FULL, COMPARE, SYMBOLS }; + + static private final ImageDescriptor bannerImgDescriptor = ImageResourceManager.getImageDescriptor(ImageKeys.IMG_WIZARD); + + + SelectActionPage selectActionPage; + DeviceOrFileSelectionPage importHeapPage; + DeviceOrFileSelectionPage compareHeapsFirstPage; + DeviceOrFileSelectionPage compareHeapsSecondPage; + ParameterFilesPage parameterFilesPage; + ExportFileNamePage exportFileNamePage; + SWMTLogPage swmtLogPage; + MemSpyMainView mainView; + ImportEngine importEngine; + MemSpyWizardDialog wizDialog; + + MemSpyWizardType wizardType; + TraceCoreEngine traceEngine; + AnalyserXMLGenerator fillValues; + + private final static String IMPORTING_FILES = "Importing Files"; + + public MemSpyWizard(){ + super(bannerImgDescriptor); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard constructor - start"); + + this.mainView = MemSpyMainView.showAndReturnYourself(); + this.importEngine = mainView.getImportEngine(); + this.setNeedsProgressMonitor(true); + this.traceEngine = new TraceCoreEngine(); + this.wizardType = MemSpyWizardType.FULL; + this.fillValues = null; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard constructor - end"); + + } + + public MemSpyWizard( MemSpyWizardType wizardType, AnalyserXMLGenerator fillValues ) { + this(); + this.wizardType = wizardType; + this.fillValues = fillValues; + if( wizardType != MemSpyWizardType.SYMBOLS ){ + MemSpyMainView.showTraceViewer(); + } + } + + + /** + * (non-Javadoc) + * + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizard#addPages() + */ + public void addPages() { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard addpages - start"); + + // if wizard's type is full, add all pages. + if( wizardType == MemSpyWizardType.FULL ){ + + selectActionPage = new SelectActionPage("Select Action"); + addPage(selectActionPage); + + importHeapPage = new DeviceOrFileSelectionPage( "Get Heap From", + "Import Heap Wizard, step 1", "Define source for Heap Dump files. Logs can be imported from already existing files or from device via TraceViewer.", ValueTypes.IMPORT_HEAP, + PageType.IMPORT_PAGE, traceEngine ); + addPage(importHeapPage); + + compareHeapsFirstPage = new DeviceOrFileSelectionPage("Select First Heap", + "Compare Two Heaps Wizard, step 1", "Define source for first compared Heap Dump. Heap Dumps can be imported from already existing files\nor from device via TraceViewer.", ValueTypes.COMPARE_HEAP_FIRST_HEAP, + PageType.COMPARE_FIRST_HEAP, traceEngine); + addPage(compareHeapsFirstPage); + + compareHeapsSecondPage = new DeviceOrFileSelectionPage("Select Second Heap", + "Compare Two Heaps Wizard, step 2", "Define source for second compared Heap Dump. Compared heap dumps must be from same thread.", ValueTypes.COMPARE_HEAP_SECOND_HEAP, + PageType.COMPARE_SECOND_HEAP, traceEngine); + addPage(compareHeapsSecondPage); + + exportFileNamePage = new ExportFileNamePage("Define export file name"); + addPage(exportFileNamePage); + + parameterFilesPage = new ParameterFilesPage(null, null, "Import Heap Wizard, step 2"); + addPage(parameterFilesPage); + + swmtLogPage = new SWMTLogPage("Get SWMT-logs", traceEngine); + addPage(swmtLogPage); + } + // if wizard type is compare add only compare output and symbol pages. + else if( wizardType == MemSpyWizardType.COMPARE){ + + compareHeapsFirstPage = new DeviceOrFileSelectionPage("Select First Heap", + "Compare Two Heaps Wizard, step 1", "Define source for first compared Heap Dump. Heap Dumps can be imported from already existing files\nor from device via TraceViewer.", ValueTypes.COMPARE_HEAP_FIRST_HEAP, + PageType.COMPARE_FIRST_HEAP, traceEngine); + addPage(compareHeapsFirstPage); + + // prefill path of compared Heap Dump to wizard page. + compareHeapsFirstPage.setHeapDumpFile( fillValues.getXMLSourceFile()[0] ); + + compareHeapsSecondPage = new DeviceOrFileSelectionPage("Select Second Heap", + "Compare Two Heaps Wizard, step 2", "Define source for second compared Heap Dump. Compared heap dumps must be from same thread.", ValueTypes.COMPARE_HEAP_SECOND_HEAP, + PageType.COMPARE_SECOND_HEAP, traceEngine); + addPage(compareHeapsSecondPage); + + // reset file combo box text from second page. + compareHeapsSecondPage.resetFileCombo(); + + exportFileNamePage = new ExportFileNamePage("Define export file name"); + addPage(exportFileNamePage); + + parameterFilesPage = new ParameterFilesPage(fillValues.getXMLDebugMetaDataFile(), null, "Import Heap Wizard, step 2"); + addPage(parameterFilesPage); + + + + + } + else if( wizardType == MemSpyWizardType.SYMBOLS ){ + parameterFilesPage = new ParameterFilesPage( fillValues.getXMLDebugMetaDataFile(), fillValues.getXMLDebugMetaDataDirectory(), "Edit Symbol Definitions" ); + addPage(parameterFilesPage); + } + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard addpages - end"); + + } + + /** + * (non-Javadoc) + * + * @see org.eclipse.jface.wizard.Wizard#getNextPage(org.eclipse.jface.wizard.IWizardPage) + */ + public IWizardPage getNextPage(IWizardPage page) { + + + if (page.equals( selectActionPage )) { + + SelectActionPage SelectWizardPage = (SelectActionPage) page; + if ( SelectWizardPage.importHeapRadioButton.getSelection() ) { + return importHeapPage; + } + else if ( SelectWizardPage.compareTwoHeapsRadioButton.getSelection() ) { + return compareHeapsFirstPage; + } + else if ( SelectWizardPage.swmtRadioButton.getSelection() ) { + return swmtLogPage; + } + } else if ( page.equals(importHeapPage) ) { + return parameterFilesPage; + } + + else if ( page.equals(compareHeapsFirstPage) ) { + return compareHeapsSecondPage; + } + else if ( page.equals(compareHeapsSecondPage ) ) { + return exportFileNamePage; + } + else if ( page.equals( exportFileNamePage ) ){ + boolean setText = true; + File file = new File( exportFileNamePage.getOutputFileName()); + if( file.exists() ){ + // if file already exists confirm that user wants to overwrite it. + MessageBox messageBox = new MessageBox(this.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); + messageBox.setText( MemSpyMainView.WARNING_COMPARE ); + messageBox.setMessage( MemSpyMainView.WARNING_FILE_EXISTS ); + int buttonID = messageBox.open(); + if (buttonID == SWT.NO) { + setText = false; + } + } + if( setText == false ){ + return exportFileNamePage; + } + return parameterFilesPage; + } + + + return page; + } + + /** + * (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#canFinish() + */ + public boolean canFinish() { + if (this.getContainer().getCurrentPage() == parameterFilesPage) { + return parameterFilesPage.canFinish(); + } + else if (this.getContainer().getCurrentPage() == swmtLogPage ){ + return swmtLogPage.canFinish(); + } + else { + return false; + } + + } + + + + + /** + * (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performFinish() + */ + + + public boolean performFinish() { + + if( this.wizardType == MemSpyWizardType.FULL ){ + // save form values + saveUserEnteredData(); + + IRunnableWithProgress importFiles = null; + + // get selected action from first page. + final MemSpyAction action = selectActionPage.getAction(); + + importHeapPage.getTraceEngine().shutDownMemSpy(); + // Initialize XML generator + AnalyserXMLGenerator generator = new AnalyserXMLGenerator(); + + + if( action != MemSpyAction.SWMT ){ + + // read symbol definitions + this.getSymbolInformation(generator); + + final AnalyserXMLGenerator finalGenerator = generator; + + // if importing Heap Dump(s) + if( selectActionPage.getAction() == MemSpyAction.IMPORT_HEAP ){ + final ArrayList importedHeaps = importHeapPage.getImportedHeaps(); + importFiles = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN); + + // import heaps + importEngine.importAndAnalyseHeap( importedHeaps, finalGenerator, true ); + } + }; + }//if Comparing heaps + else if( selectActionPage.getAction() == MemSpyAction.COMPARE_HEAPS ){ + + final ArrayList heaps = new ArrayList(); + + heaps.add( compareHeapsFirstPage.getRecentHeap() ); + heaps.add( compareHeapsSecondPage.getRecentHeap() ); + final String output = exportFileNamePage.getOutputFileName(); + + importFiles = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN); + // import heaps + importEngine.importAndAnalyseHeap( heaps, finalGenerator, false ); + // compare heaps + importEngine.compareHeaps( heaps.get(0), heaps.get(1), finalGenerator, output ); + } + }; + + } + } + else{ // if importing SWMT-logs + final ArrayList logList = swmtLogPage.getLogList(); + final AnalyserXMLGenerator finalGenerator = generator; + importFiles = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN); + + // import heaps if SWMT logging was also dumping heap data for thread(s) + final ArrayList importedHeaps = traceEngine.getImportedSWMTHeaps(); + if(importedHeaps != null){ + //Don't delete temp folder and files yet, SWMT import will do that + importEngine.importAndAnalyseHeap( importedHeaps, finalGenerator, false, false ); + } + + // import swmt-logs and delete temp files & folder + importEngine.importSWMTLogs( logList, true ); + + } + }; + } + try { + getContainer().run(true, false, importFiles); + } + catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } + catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + MemSpyMainView.showAndReturnYourself(); + } + else if( this.wizardType == MemSpyWizardType.COMPARE ){ + + IRunnableWithProgress importFiles = null; + + compareHeapsFirstPage.getTraceEngine().shutDownMemSpy(); + + // Initialize XML generator + AnalyserXMLGenerator generator = new AnalyserXMLGenerator(); + + // read symbol definitions + this.getSymbolInformation(generator); + + final AnalyserXMLGenerator finalGenerator = generator; + final ThreadInfo secondHeap = compareHeapsSecondPage.getRecentHeap(); + + // create new ThreadInfo object and format combobox value from first compare page to it's + // threadFilePath variable.(We don't want to import that heap again as it has already + // been updated.) + ThreadInfo firstModifiedHeap = new ThreadInfo(); + firstModifiedHeap.setThreadFilePath( compareHeapsFirstPage.getSelectedFilePath() ); + firstModifiedHeap.setThreadName( secondHeap.getThreadName() ); + final ThreadInfo firstHeap = firstModifiedHeap; + + final String output = exportFileNamePage.getOutputFileName(); + + importFiles = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN); + ArrayList heaps = new ArrayList(); + heaps.add( secondHeap ); + importEngine.importAndAnalyseHeap(heaps, finalGenerator, false); + importEngine.compareHeaps( firstHeap, secondHeap, finalGenerator, output ); + } + }; + + + try { + getContainer().run(true, false, importFiles); + } + catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } + catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + MemSpyMainView.showAndReturnYourself(); + + } + else if(this.wizardType == MemSpyWizardType.SYMBOLS ){ + + // read symbol definitions + this.getSymbolInformation(fillValues); + + // send new symbols to Main View + IRunnableWithProgress importFiles = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask("Saving new symbol definitions", IProgressMonitor.UNKNOWN); + mainView.symbolsUpdated(fillValues); + monitor.done(); + } + }; + + + try { + getContainer().run(true, false, importFiles); + } + catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } + catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + } + return true; + } + + /** + * (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performCancel() + */ + public boolean performCancel() { + try { + if( this.wizardType == MemSpyWizardType.FULL){ + this.saveUserEnteredData(); + } + + MemSpyMainView.showAndReturnYourself(); + + // delete temp files + MemSpyFileOperations.deleteTempMemSpyFiles(); + traceEngine.shutDownMemSpy(); + } catch (Exception e) { + // Some failure in above should not prevent user Canceling dialog + e.printStackTrace(); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "performCancel/exception: " + e); + } + + return true; + } + + /** + * (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#getPreviousPage(org.eclipse.jface.wizard.IWizardPage) + */ + public IWizardPage getPreviousPage(IWizardPage page) { + if (page.equals(importHeapPage)) { + return selectActionPage; + } else if (page.equals(compareHeapsFirstPage)) { + return selectActionPage; + } else if (page.equals(compareHeapsSecondPage)) { + return compareHeapsFirstPage; + } + return page; + } + + /** + * setComparedHeaps + * sets compared thread names into each compare page + */ + public void setComparedHeaps(){ + + // get recent thread infos from compare heap pages + ThreadInfo firstHeap = null; + ThreadInfo secondHeap = null; + + firstHeap = compareHeapsFirstPage.getRecentHeap(); + secondHeap = compareHeapsSecondPage.getRecentHeap(); + + // save thread infos into compare pages + compareHeapsSecondPage.setComparedHeap(firstHeap, secondHeap); + compareHeapsFirstPage.setComparedHeap(firstHeap, secondHeap); + } + + /** + * updateThreadLists + * updates tread lists into each file or device selection page + * @param threadList + */ + public void updateThreadLists(ArrayList threadList){ + // Each page gets new thread list so that status of threads won't change when another page is modified. + if(importHeapPage != null){ + this.importHeapPage.setDeviceThreadList( copyThreadList( threadList ) ); + this.importHeapPage.updateThreadList(); + } + if(compareHeapsFirstPage != null){ + this.compareHeapsFirstPage.setDeviceThreadList( copyThreadList( threadList ) ); + this.compareHeapsFirstPage.updateThreadList(); + } + if(compareHeapsFirstPage != null){ + this.compareHeapsSecondPage.setDeviceThreadList( copyThreadList( threadList ) ); + this.compareHeapsSecondPage.updateThreadList(); + } + } + + /** + * Copies threads to new list. + * @param threadList List to be copied. + * @return New list containing thread information in new list. + */ + private ArrayList copyThreadList(ArrayList threadList) { + ArrayList returnList = new ArrayList(); + for(ThreadInfo thread : threadList) { + returnList.add(thread.clone()); + } + return returnList; + } + + /** + * sets thread list selection and hides threadListTable from 2. comparePage + * @param thread Thread information. + */ + public void setThreadListSelectionToComparePages( ThreadInfo thread ){ + this.compareHeapsSecondPage.setThreadListSelection( thread ); + } + + /** + * shows or hides threadListTable in 2. comparePage + */ + public void showImportedHeapsInComparePage( boolean value ){ + this.compareHeapsSecondPage.setImportedThreadTableVisible( value ); + + } + + + + /** + * Check if compared heaps are from same thread + * @return true if heaps are from same thread or other or both heaps are still undefined + */ + public boolean areComparedHeapsFromSameThread(){ + if( compareHeapsFirstPage.getRecentHeap() != null && + compareHeapsSecondPage.getRecentHeap() != null ){ + if( compareHeapsFirstPage.getRecentHeap().getThreadName().equals(compareHeapsSecondPage.getRecentHeap().getThreadName() ) ){ + return true; + } + else{ + return false; + } + } + else{ + return true; + } + + } + + + /** + * saveUserEnteredData + * calls saveUserEnteredData method of all wizard pages. + */ + private void saveUserEnteredData(){ + + // Save form values so that they can be restored later + if( selectActionPage != null){ + selectActionPage.saveUserEnteredData(); + } + if( importHeapPage != null){ + importHeapPage.saveUserEnteredData(); + } + if( parameterFilesPage != null){ + parameterFilesPage.saveUserEnteredData(); + } + if( compareHeapsFirstPage != null){ + compareHeapsFirstPage.saveUserEnteredData(); + } + if( compareHeapsSecondPage != null){ + compareHeapsSecondPage.saveUserEnteredData(); + } + if( exportFileNamePage != null){ + exportFileNamePage.saveUserEnteredData(); + } + if( swmtLogPage != null){ + swmtLogPage.saveUserEnteredData(); + } + } + + public void updateConnectionSettings(){ + if( importHeapPage != null ){ + this.importHeapPage.updateConnectionSettings(); + } + if( compareHeapsFirstPage != null ){ + this.compareHeapsFirstPage.updateConnectionSettings(); + } + if( compareHeapsSecondPage != null ){ + this.compareHeapsSecondPage.updateConnectionSettings(); + } + if( swmtLogPage != null ){ + this.swmtLogPage.updateConnectionSettings(); + } + + if(traceEngine != null){ + // Resetting progress status in case connection settings have been changed + traceEngine.resetProgressStatus(); + } + + } + + public void init(IWorkbench arg0, IStructuredSelection arg1) { + + } + + public void setData(MemSpyWizardDialog wizDialog){ + this.wizDialog = wizDialog; + } + + public void setCancelText( String newText ){ + wizDialog.setCancelText( newText ); + } + + private void getSymbolInformation( AnalyserXMLGenerator symbolInfo ){ + + // combine map and symbol files into one String[] and set them into xmlGenerator + ArrayList debugMetaData; + String[] symbolFiles = parameterFilesPage.getSymbolFiles(); + if( symbolFiles == null ){ + debugMetaData = new ArrayList(); + } + else{ + debugMetaData = new ArrayList(Arrays.asList( symbolFiles )); + } + if( parameterFilesPage.getMapFilesZip().equals("") == false ){ + debugMetaData.add( parameterFilesPage.getMapFilesZip() ); + } + + // Set meta data folder + symbolInfo.setXMLDebugMetaDataFile(debugMetaData.toArray(new String [debugMetaData.size()])); + if( parameterFilesPage.getMapFilesFolder().equals("") == false ){ + symbolInfo.setXMLDebugMetaDataDirectory( parameterFilesPage.getMapFilesFolder() ); + } + else{ + symbolInfo.setXMLDebugMetaDataDirectory(null); + } + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizardDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizardDialog.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; + +public class MemSpyWizardDialog extends WizardDialog { + @Override + public void create() { + super.create(); + } + + public MemSpyWizardDialog(Shell parentShell, IWizard newWizard) { + super(parentShell, newWizard); + } + + public void enableBackCancelButtons(boolean enable) { + getButton(IDialogConstants.BACK_ID).setEnabled(enable); + getButton(IDialogConstants.CANCEL_ID).setEnabled(enable); + + + } + + public void setCancelText(String newText){ + getButton(IDialogConstants.CANCEL_ID).setText(newText); + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ParameterFilesPage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ParameterFilesPage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; + +import java.util.HashMap; + +import org.eclipse.swt.widgets.Composite; + +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.sdk.SdkUtils; +import com.nokia.s60tools.ui.wizards.DebugMetadataWizardPage; + + +/** + * class ParameterFilesPage + * This wizard page will query the user for locations symbol and map files. + */ +public class ParameterFilesPage extends DebugMetadataWizardPage { + + private String[] symbolOrMapFiles; + private String mapFileDirectory; + + private enum FileType{ SYMBOL, MAPFILE }; + + + public ParameterFilesPage( String[] symbolOrMapFiles, String mapFileDirectory, String descriptionText ){ + super("MemSpy", descriptionText, false, UserEnteredData.getParameterFilesSection(), + UserEnteredData.MAX_SAVED_VALUES); + this.symbolOrMapFiles = symbolOrMapFiles; + this.mapFileDirectory = mapFileDirectory; + + } + + public void createControl(Composite parent) { + super.createControl(parent); + + // read symbolOrMapFiles-variables values and set them to UI items. + + if( this.symbolOrMapFiles != null ){ + + //Reset Symbol file list-component + this.listSymbols.removeAll(); + + + // Reset ui-components values + + // set "No Map Files"-radio button selected.(and unselect other buttons) + this.buttonMapFilesFolderRadio.setSelection(false); + this.buttonMapFilesZipRadio.setSelection(false); + this.buttonSdkFolderRadio.setSelection(false); + this.buttonNoMapFilesRadio.setSelection(true); + + // disable combo boxes and browse buttons buttons + this.comboMapFilesFolder.setEnabled(false); + this.buttonMapFolderBrowse.setEnabled(false); + this.comboMapFilesZip.setEnabled(false); + this.buttonZipBrowse.setEnabled(false); + this.comboSdkFolder.setEnabled(false); + + + for( String item : symbolOrMapFiles ){ + if( getFileType(item) == FileType.SYMBOL ){ + listSymbols.add(item); + + } + else if(getFileType(item) == FileType.MAPFILE ){ + comboMapFilesZip.setText(item); + + // set zip-radio button selected.(and unselect other buttons) + this.buttonMapFilesFolderRadio.setSelection(false); + this.buttonMapFilesZipRadio.setSelection(true); + this.buttonSdkFolderRadio.setSelection(false); + this.buttonNoMapFilesRadio.setSelection(false); + + // enable zip buttons + this.comboMapFilesFolder.setEnabled(false); + this.buttonMapFolderBrowse.setEnabled(false); + this.comboMapFilesZip.setEnabled(true); + this.buttonZipBrowse.setEnabled(true); + this.comboSdkFolder.setEnabled(false); + } + } + + } + if( this.mapFileDirectory != null ){ + comboMapFilesFolder.setText( mapFileDirectory ); + + // set folder-radio button selected.(and unselect other buttons) + this.buttonMapFilesFolderRadio.setSelection(true); + this.buttonMapFilesZipRadio.setSelection(false); + this.buttonSdkFolderRadio.setSelection(false); + this.buttonNoMapFilesRadio.setSelection(false); + + // enable folder buttons + this.comboMapFilesFolder.setEnabled(true); + this.buttonMapFolderBrowse.setEnabled(true); + this.comboMapFilesZip.setEnabled(false); + this.buttonZipBrowse.setEnabled(false); + this.comboSdkFolder.setEnabled(false); + + } + } + + public boolean zipContainsMapFiles(String path) { + return SdkUtils.zipContainsMapFiles(path); + } + + public String getHelpContext() { + return HelpContextIDs.MEMSPY_IMPORT_SYMBOLS; + } + + public boolean canFlipToNextPage(){ + return false; + } + + public boolean canFinish() { + return canProceed(); + } + + public HashMap getSdkMapFolders() { + return SdkUtils.getSdkMapFileFolders(true); + } + + private static FileType getFileType( String fileName ){ + int index = fileName.lastIndexOf('.'); + if ( index <= 0 ){ + return FileType.SYMBOL; + } + else{ + String end = fileName.substring(index); + if(end.equals(".zip")){ + return FileType.MAPFILE; + } + else{ + return FileType.SYMBOL; + } + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.DebugMetadataWizardPage#folderContainsMapFiles(java.lang.String) + */ + public boolean folderContainsMapFiles(String folder) { + return SdkUtils.folderContainsMapFiles(folder); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTCategoryGroupComposite.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTCategoryGroupComposite.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,388 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.memspy.ui.wizards; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; + +import com.nokia.s60tools.memspy.model.CategoryProfile; +import com.nokia.s60tools.memspy.model.SWMTCategorys; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.preferences.MemSpyPreferences; +import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoriesDialog; +import com.nokia.s60tools.ui.AbstractUIComposite; +import com.nokia.s60tools.util.debug.DbgUtility; + + +/** + * This interface is used to notify category selection changes + */ +interface SWMTCategorySelectionMediator{ + + /** + * Gets category selection as bitwise OR:ed integer. + * @return category selection + */ + public int getCategorySelection(); + + /** + * Sets new category selection + * @param newCategorySelection new category selection as bitwise OR:ed integer + * @param isProfileSettings true if these settings are profile settings + * false if these are custom settings + */ + public void setCategorySelection(int newCategorySelection, boolean isProfileSettings); + + /** + * Set Categories button selection to "All" or "Custom". + * @param isProfileCategoriesSelected true if one profile is selected + * false otherwise. + */ + public void setProfileTrackedCategoriesSelected(boolean isProfileTrackedCategoriesSelected); + + /** + * Get if user has been selected to use one of the profiles Categories + * @return true if one profile is selected + * false if custom categories is selected. + */ + public boolean isProfileTrackedCategoriesSelected(); +}; + + +/** + * Composite for SWMT category selection group in SWMTLogPage wizard page. + */ +public class SWMTCategoryGroupComposite extends AbstractUIComposite implements SelectionListener { + + // + // Private constants + // + private static final int COMPOSITE_COLUMN_COUNT = 1; + private static final int TRACKED_CATEGORIES_GROUP_COLUMN_COUNT = 2; + // + // Private member data + // + private Button profileCategoriesRadioBtn; + private Button customCategoriesRadioBtn; + private Button editCategoriesPushButton; + private boolean isCustomCategorySelected = false; + private final SWMTCategorySelectionMediator mediator; + private boolean isCustomCategorySelectionEnabled = true; + private Combo profileCombo; + + /** + * Constructor. + * @param parentComposite parent composite + * @param isCustomCategorySelected true if custom category is initially selected, otherwise false + * @param mediator mediator for handling category selection changes + * @param isCustomCategorySelectionEnabled true if custom category selection is enabled, otherwise false. + */ + public SWMTCategoryGroupComposite(Composite parentComposite, boolean isCustomCategorySelected, SWMTCategorySelectionMediator mediator, boolean isCustomCategorySelectionEnabled) { + super(parentComposite); + this.isCustomCategorySelected = isCustomCategorySelected; + this.mediator = mediator; + this.isCustomCategorySelectionEnabled = isCustomCategorySelectionEnabled; + setCustomCategorySelection(); + // Updating widget UI state based on the provided constructor parameters + setWidgetStates(); + } + + /** + * Sets custom category selection based on the feature availability + * and the current selection data. + */ + private void setCustomCategorySelection() { + boolean isAllTrackedCategoriesSelected = mediator.isProfileTrackedCategoriesSelected(); + if(isCustomCategorySelectionEnabled && !isAllTrackedCategoriesSelected){ + // If feature is enabled and there is pre-selected values => custom category is selected + isCustomCategorySelected = true; + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.AbstractUIComposite#createControls() + */ + @Override + protected void createControls() { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": createControls()"); //$NON-NLS-1$ + + // Tracked Categories -group + Group categoryGroup = new Group(this, SWT.SHADOW_NONE); + categoryGroup.setText("Tracked Categories and Advanced Options"); + GridLayout gdl = new GridLayout(TRACKED_CATEGORIES_GROUP_COLUMN_COUNT, false); + GridData gd = new GridData(GridData.FILL_BOTH); + categoryGroup.setLayout(gdl); + categoryGroup.setLayoutData(gd); + + Composite profileCom = new Composite(categoryGroup,SWT.NONE); + GridLayout pgl = new GridLayout(2, false); + pgl.marginHeight = 0; + pgl.marginWidth = 0; + GridData pgd = new GridData(GridData.FILL_BOTH); + pgd.horizontalSpan = 2; + pgd.grabExcessHorizontalSpace = true; + pgd.grabExcessVerticalSpace = true; + profileCom.setLayout(pgl); + profileCom.setLayoutData(pgd); + + // + // Tracked Categories -group contents + // + + boolean isProfileSelected = MemSpyPreferences.isProfileTrackedCategoriesSelected(); + + //Profiles button + profileCategoriesRadioBtn = new Button(profileCom, SWT.RADIO); + profileCategoriesRadioBtn.addSelectionListener(this); + profileCategoriesRadioBtn.setSelection(isProfileSelected); + + profileCombo = new Combo( profileCom, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY); + profileCombo.addSelectionListener(this); + + List categoryProfiles = SWMTCategorys.getInstance().getCategoryProfiles(); + for (Iterator iterator = categoryProfiles.iterator(); iterator + .hasNext();) { + CategoryProfile profile = (CategoryProfile) iterator.next(); + profileCombo.add(profile.getName()); + } + + + // Custom -radio button + customCategoriesRadioBtn = new Button(categoryGroup, SWT.RADIO); + customCategoriesRadioBtn.setText("Custom Categories and Advanced Options"); + customCategoriesRadioBtn.addSelectionListener(this); + customCategoriesRadioBtn.setSelection(!isProfileSelected); + + // Edit -push button + editCategoriesPushButton = new Button(categoryGroup, SWT.PUSH); + editCategoriesPushButton.setText("Edit..."); + editCategoriesPushButton.addSelectionListener(this); + } + + /** + * Sets selection and enabled disable states for the widgets + */ + private void setWidgetStates() { + + customCategoriesRadioBtn.setEnabled(true); + profileCategoriesRadioBtn.setEnabled(true); + profileCombo.setEnabled(true); + + if(isCustomCategorySelected){ + profileCombo.setEnabled(false); + profileCategoriesRadioBtn.setSelection(false); + customCategoriesRadioBtn.setSelection(true); + editCategoriesPushButton.setEnabled(true); + } + else{ + profileCombo.setEnabled(true); + profileCategoriesRadioBtn.setSelection(true); + customCategoriesRadioBtn.setSelection(false); + editCategoriesPushButton.setEnabled(false); + } + setProfileComboSelectionAndTooltipText(); + + if(!isCustomCategorySelectionEnabled){ + disableControls(); + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.AbstractUIComposite#createLayout() + */ + @Override + protected Layout createLayout() { + return new GridLayout(COMPOSITE_COLUMN_COUNT, false); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.AbstractUIComposite#createLayoutData() + */ + @Override + protected Object createLayoutData() { + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.verticalSpan = 2; + return gridData; + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + // Must be implemented but not needed in this case + } + + /** + * Sets selection for profile Combo and sets tooltip text + */ + private void setProfileComboSelectionAndTooltipText() { + int selectedProfile = MemSpyPreferences.getSWMTCategorySettingForProfile(); + + List categoryProfiles = SWMTCategorys.getInstance() + .getCategoryProfiles(); + int j = 0; + for (Iterator iterator = categoryProfiles.iterator(); iterator + .hasNext();) { + CategoryProfile profile = (CategoryProfile) iterator.next(); + if (selectedProfile == profile.getCategories()) { + //Selection of combo + profileCombo.select(j); + //Tootip text for combo selection + String categoryNames = ""; + String[] profileCategoryNames = profile.getCategoryEntryNames(); + //Collection names of all categories belongs to profile as comma separated list (but last with "and") + for (int i = 0; i < profileCategoryNames.length; i++) { + categoryNames += profileCategoryNames[i]; + if (i == profileCategoryNames.length - 2) { + categoryNames += " and "; + } else if (i != profileCategoryNames.length - 1) { + categoryNames += ", "; + } + // else its last item and we dont need to add anything + } + String name = profile.getName(); + //To show "&" char in tooltip, it must be replaced with "&&" + name = name.replace("&", "&&"); + String toolTipText = "Profile: (" + name + + ") contains following categories: " + categoryNames; + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, toolTipText); + profileCombo.setToolTipText(toolTipText); + break; + } + + j++; + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + Widget widget = e.widget; + + if(widget.equals(profileCategoriesRadioBtn)){ + isCustomCategorySelected = false; + mediator.setProfileTrackedCategoriesSelected(true); + setWidgetStates(); + } + else if(widget.equals(customCategoriesRadioBtn)){ + isCustomCategorySelected = true; + mediator.setProfileTrackedCategoriesSelected(false); + setWidgetStates(); + } + else if(widget.equals(editCategoriesPushButton)){ + categoriesEditButtonPressed(); + } + else if(widget.equals(profileCombo)){ + String selectedProfile = profileCombo.getText(); + CategoryProfile profile = SWMTCategorys.getInstance().getProfile(selectedProfile); + mediator.setCategorySelection(profile.getCategories(), true); + setProfileComboSelectionAndTooltipText(); + } + } + + + + /** + * Checks if custom category set has been selected by a user. + * @return true if custom category has been selected, otherwise false. + */ + public boolean isCustomCategorySelected() { + return isCustomCategorySelected; + } + + /** + * Handles Edit...-button press event. + */ + private void categoriesEditButtonPressed() { + Shell sh = MemSpyPlugin.getCurrentlyActiveWbWindowShell(); + SWMTCategoriesDialog entryDialog = new SWMTCategoriesDialog(sh, mediator.getCategorySelection()); + entryDialog.create(); + int userSelection = entryDialog.open(); + if(userSelection == Window.OK){ + int newCategorySelection = entryDialog.getSelectedCategories(); + mediator.setCategorySelection(newCategorySelection, false); + } + } + + /** + * Disables custom category selection programmatically and updates UI accordingly + */ + public void disableCustomCategorySelection(){ + isCustomCategorySelectionEnabled = false; + isCustomCategorySelected = false; + setWidgetStates(); + } + + /** + * Sets enable state false to the controls. + */ + private void disableControls() { + // Disabling custom category selection + setEnabled(false); + profileCategoriesRadioBtn.setEnabled(false); + customCategoriesRadioBtn.setEnabled(false); + editCategoriesPushButton.setEnabled(false); + profileCombo.setEnabled(false); + } + + /** + * Refreshes widget state + */ + public void refresh(){ + setWidgetStates(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + public void dispose(){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": dispose()"); //$NON-NLS-1$ + super.dispose(); + } + + /** + * Sets buttons enabled/disabled + * @param isButtonsEnabled set true if buttons are enabled, and false + * if buttons are disabled + */ + public void setButtonsEnabled(boolean isButtonsEnabled){ + if(isButtonsEnabled){ + setWidgetStates(); + }else{ + disableControls(); + } + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTLogPage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTLogPage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1362 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.memspy.containers.SWMTLogInfo; +import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType; +import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener; +import com.nokia.s60tools.memspy.model.MemSpyFileOperations; +import com.nokia.s60tools.memspy.model.MemSpyLogParserEngine; +import com.nokia.s60tools.memspy.model.TraceCoreEngine; +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; +import com.nokia.s60tools.memspy.preferences.MemSpyPreferences; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.memspy.ui.UiUtils; +import com.nokia.s60tools.ui.preferences.PreferenceUtils; +import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * SWMT-log import page is used for importing SWMT-logs from file system or from device. + */ + +public class SWMTLogPage extends S60ToolsWizardPage implements SelectionListener, IMemSpyTraceListener, SWMTCategorySelectionMediator{ + + /** + * Selection index for import from device via TraceViewer radio button + */ + private static final int DEVICE_RADIO_BUTTON_SELECTION_INDEX = 2; + + // Array list of logs that are imported + // from files: + private ArrayList fileLogList; + // from device: + private ArrayList deviceLogList; + + // SWMT-log that is currently received + SWMTLogInfo receivedLog; + + // TraceCore engine + private TraceCoreEngine traceEngine; + + // Cycle Number for SMWT-log file name + private int cycleNumber; + + // Error message + String errorMessage; + + // boolean value stating that error has been occurred and logs cannot be requested before removing + // all items and restarting from cycle 1. + boolean missedLogs; + + //UI-components: + private Group radioButtonGroup; + private Button fileRadioButton; + private Button deviceRadioButton; + + // Components for importing file from device + private Table fileLogsTable; + private Composite fileSelectionButtonComposite; + private Button addFileButton; + private Button addDirectoryButton; + private Button removeOneButton; + private Button removeAllButton; + + private Group fileSelectionGroup; + private Group deviceGroup; + + private GridData fileSelectionGridData; + private GridData deviceGridData; + + + // components for importing log from device + private Table deviceLogsTable; + private Composite loggingComposite; + private Button connectionSettingsButton; + private Button getLogNowButton; + private Button removeReceivedLogsButton; + private Label connectionNameInUseLabel; + + // Timer related components + private Label intervalLabel; + private Label secondLabel; + private Button startTimerButton; + private Combo timerCombo; + + /** + * UI composite for SWMT Category group + */ + private SWMTCategoryGroupComposite categoryGroupComposite; + + // boolean variable, which is set to true if some MemSpy operation is running. + boolean memSpyOperationRunning; + boolean memSpyStopping; + boolean memSpyTimerRunning; + + // MemSpy operation processes: + // receive SWMT-log manually + IRunnableWithProgress receiveSWMTLogProcess; + + private final static String GET_LOG_FROM_RADIO_BUTTON = "Get SWMT Log"; + private final static String GET_FROM_FROM_FILE_RADIO_BUTTON = "From File System"; + private final static String GET_LOG_FROM_DEVICE_RADIO_BUTTON = "From Device via TraceViewer"; + private final static String LOG_FILES = "Log files:"; + private final static String LOG_TYPE = "Type"; + private final static String ADD_FILE = "Add File"; + private final static String ADD_DIRECTORY = "Add Directory"; + private final static String REMOVE_ONE = "Remove"; + private final static String REMOVE_ALL = "Remove All"; + private final static String ADD_FILE_TEXT = "Define Location of SWMT Log file:"; + private final static String ADD_DIRECTORY_TEXT = "Define Location of directory that contains SWMT Logs:"; + private final static String LOG_TYPE_FILE = "File"; + private final static String LOG_TYPE_DIRECTORY = "Directory"; + + private final static String CONNECTION_SETTINGS_BUTTON = "Connection Settings..."; + private final static String CURRENTLY_USING_TEXT = "Currently using:"; + private final static String GET_LOG_NOW_BUTTON = "Get SWMT Log Now"; + private final static String LOGS = "Logs"; + private final static String RECEIVED = "Received"; + + private final static String RECEIVING_SWMT_LOG = "Receiving SWMT Log: "; + private final static String WAITING_FOR_TIMER = "Waiting for timer to expire: "; + private final static String STOPPING_TIMER = "Stopping timer: "; + + private final static String TEXT_GET_LOG_WITH_TIMER = "Get Log with Timer"; + private final static String TEXT_INTERVAL = "Interval:"; + private final static String START_TIMER = "Start Timer"; + private final static String TEXT_SECOND = "Seconds"; + + private final static String ERROR_INTERVAL = "Time interval needs to be integer and more than zero."; + + /** + * Constructor. + * @param pageName name of the page + * @param traceEngine TraceCore engine that is used when requesting data from TC + */ + protected SWMTLogPage(String pageName, TraceCoreEngine traceEngine) { + super(pageName); + setTitle("System Wide Memory Tracking Wizard"); + setDescription("Define Source For SWMT logs that are imported. Logs can be imported from already existing files or from device via TraceViewer."); + this.fileLogList = new ArrayList(); + this.deviceLogList = new ArrayList(); + this.traceEngine = traceEngine; + this.createMemSpyProcesses(); + + this.memSpyTimerRunning = false; + this.memSpyOperationRunning = false; + this.memSpyStopping = false; + this.cycleNumber = 0; + + this.missedLogs = false; + } + + @Override + public void recalculateButtonStates() { + // no implementation needed + } + + @Override + public void setInitialFocus() { + timerCombo.setFocus(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + // Not needed in this case + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + // Update controls after radio buttons state changes to false + if ( ( e.widget == deviceRadioButton && deviceRadioButton.getSelection() == false ) || + ( e.widget == fileRadioButton && fileRadioButton.getSelection() == false ) ){ + //When selection is changed, we clear the previous results. + removeReceivedLogs(); + this.hideAndRevealItems(); + } + + // open file dialog + else if (e.widget == addFileButton) { + // open file dialog for selecting a crash file + FileDialog dialog = new FileDialog(this.getShell(), SWT.MULTI); + dialog.setText(ADD_FILE_TEXT); + String[] filterExt = { "*.txt", "*.log", "*.*" }; + dialog.setFilterExtensions(filterExt); + + if (dialog.open() != null ){ + String[] files = dialog.getFileNames(); + String directory = dialog.getFilterPath(); + directory = MemSpyFileOperations.addSlashToEnd( directory ); + + boolean noLogFound = false; + + for( String item : files ){ + + // confirm that file is smwt log + if( MemSpyLogParserEngine.isFileSWMTLog( new File(directory + item)) ){ + this.addFileLog( directory + item ); + } + + else{ + noLogFound = true; + } + } + + // if some of the selected files is not swmt-file show error message. + if( noLogFound ){ + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "Some of the selected files is not SWMT-log file.", null); + // Display the dialog + ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status); + } + } + + + } + + // open directory dialog + else if (e.widget == addDirectoryButton) { + // open file dialog for selecting a crash file + DirectoryDialog dialog = new DirectoryDialog(this.getShell()); + dialog.setText(ADD_DIRECTORY_TEXT); + String result = dialog.open(); + if (result != null ){ + + File[] allFiles = MemSpyFileOperations.getFilesFromDirectory( new File( result ) ); + + int swmtFileCount = 0; + + for ( File item : allFiles ){ + if( MemSpyLogParserEngine.isFileSWMTLog( item ) ){ + swmtFileCount++; + this.addFileLog( item.toString() ); + } + } + // if no SWMT-log files were found from selected directory, show error message. + if(swmtFileCount == 0){ + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "No SWMT-logs were found from selected directory.", null); + // Display the dialog + ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status); + + + } + } + } + + // remove selected log file + else if (e.widget == removeOneButton ){ + if( fileLogsTable.getSelectionCount() == 1 ){ + fileLogList.remove( fileLogsTable.getSelectionIndex() ); + this.refreshFileLogTable(); + } + } + + // remove all log files + else if (e.widget == removeAllButton ){ + fileLogList.clear(); + this.refreshFileLogTable(); + } + + // open connection settings + else if ( e.widget == connectionSettingsButton ){ + // Open connection Trace viewers connection settings. + Shell shell = MemSpyPlugin.getCurrentlyActiveWbWindowShell(); + PreferenceUtils.openPreferencePage(MemSpyPlugin.getTraceProvider().getTraceSourcePreferencePageId(), shell); + + // Disconnect trace source so that new settings are used when sending next request + MemSpyPlugin.getTraceProvider().disconnectTraceSource(); + + // get wizard pointer and cast it to MemSpyWizard + MemSpyWizard wizard = (MemSpyWizard) this.getWizard(); + // update new settings to each wizard page. + wizard.updateConnectionSettings(); + } + + // get log now from TC + else if (e.widget == getLogNowButton ){ + this.getLogNowPressed(); + } + + // Remove all log received from device-button + else if( e.widget == removeReceivedLogsButton ){ + this.removeReceivedLogs(); + } + + // SWMT timer started + else if( e.widget == startTimerButton ){ + this.getLogWithTimerPressed(); + } + + + // if file logs table selection changes or button is pressed, enable and disable buttons + if( e.widget == this.fileLogsTable || + e.widget == this.removeAllButton || + e.widget == this.removeOneButton || + e.widget == this.addFileButton || + e.widget == this.addDirectoryButton ){ + this.enableAndDisableFileButtons(); + } + getWizard().getContainer().updateButtons(); + + } + + /** + * Checks if wizard can be finished or not. + * @return boolean value if wizard can finish + */ + public boolean canFinish(){ + + // if traceEngines taskList is not empty, return false + if( traceEngine.getFirstTask() != null ){ + return false; + } + + // if file or device log lists are not empty(depending on radiobutton selection) return true + if( fileRadioButton.getSelection() ){ + if( fileLogList.size() > 0 ){ + return true; + } + } + else{ + if( deviceLogList.size() > 0 ){ + return true; + } + } + return false; + } + + + /** + * Hides and reveals controls according to radio button states. + */ + private void hideAndRevealItems() { + + boolean fileSelected = true; + + if( fileRadioButton.getSelection() == false ){ + fileSelected = false; + } + + // exclude/include needed controls + fileSelectionGridData.exclude = !fileSelected; + deviceGridData.exclude = fileSelected; + + if( !fileSelected ){ + // Since excluded groups size and location are not updated, do it now + deviceGroup.setSize( fileSelectionGroup.getSize() ); + deviceGroup.setLocation(fileSelectionGroup.getLocation()); + } + else{ + // Since excluded groups size and location are not updated, do it now + fileSelectionGroup.setSize( deviceGroup.getSize() ); + fileSelectionGroup.setLocation(deviceGroup.getLocation()); + + } + // Hide/show needed controls + fileSelectionGroup.setVisible(fileSelected); + deviceGroup.setVisible(!fileSelected); + + } + + /** + * Adds a log file. + * @param location of log file + */ + private void addFileLog( String location ){ + + // create SWMTLogInfo object for log file. + SWMTLogInfo info = new SWMTLogInfo(); + info.setType( SWMTLogType.FILE ); + info.setPath( location ); + fileLogList.add(info); + + // get files name + String fileName = location.substring( location.lastIndexOf("\\") + 1 ); + + // add name into table + TableItem item = new TableItem( fileLogsTable, SWT.NONE, fileLogsTable.getItemCount() ); + item.setText( new String[]{ fileName, LOG_TYPE_FILE }); + + } + + /** + * Updates file log table so that it contains same data that file log list. + */ + private void refreshFileLogTable(){ + //Remove all items + fileLogsTable.removeAll(); + + for( int i = 0; i < fileLogList.size(); i++ ){ + TableItem newItem = new TableItem(fileLogsTable, SWT.NONE,i); + + // get item + SWMTLogInfo log = fileLogList.get(i); + String fileName = log.getPath(); + String fileType = LOG_TYPE_DIRECTORY; + + // Remove path if type is file + if( log.getType() == SWMTLogType.FILE ){ + fileName = fileName.substring( fileName.lastIndexOf("\\") + 1 ); + fileType = LOG_TYPE_FILE; + } + + newItem.setText( new String[]{ fileName, fileType } ); + } + + } + + /** + * Removed received logs. + */ + private void removeReceivedLogs(){ + // Delete all items in deviceLogList and deviceLogsTable + deviceLogList.clear(); + deviceLogsTable.removeAll(); + + // Delete all temp files + MemSpyFileOperations.deleteTempMemSpyFiles(); + + // set cycle number to zero + cycleNumber = 0; + + // reset missed logs value + missedLogs = false; + + // enable and disable buttons + this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); + } + + /** + * Gets list of log files that are in currently selected table. + * @return list of log files that are in currently selected table + */ + public ArrayList getLogList(){ + if( fileRadioButton.getSelection() ){ + return fileLogList; + } + else{ + return deviceLogList; + } + } + + /** + * Updates connection text to match used settings. + */ + public void updateConnectionText(){ + // Updating connection name. + String displayName = MemSpyPlugin.getTraceProvider().getDisplayNameForCurrentConnection(); + connectionNameInUseLabel.setText(displayName); + loggingComposite.layout(); + } + + /** + * Loads previous values into UI components. + */ + private void loadUserEnteredData(){ + + // if last value is not found, set selection file. + UserEnteredData data = new UserEnteredData(); + int lastUsedSource = data.getPreviousRadioButtonSelection( ValueTypes.SWMT ); + + // Restoring previous state of radio buttons only if device import is also possible and was previously selected + if(MemSpyPlugin.isTraceProviderAvailable() && lastUsedSource == DEVICE_RADIO_BUTTON_SELECTION_INDEX){ + deviceRadioButton.setSelection( true ); + fileRadioButton.setSelection( false ); + } + else{ + deviceRadioButton.setSelection( false ); + fileRadioButton.setSelection( true ); + } + + // Restore previous values to file combobox + String[] lastUsedFiles = data.getPreviousValues( ValueTypes.SWMT ); + if (lastUsedFiles != null) { + timerCombo.setItems(lastUsedFiles); + timerCombo.select(0); + } + + } + + /** + * Saves user entered values and selections from UI components so that they can be restored later if needed. + */ + public void saveUserEnteredData(){ + UserEnteredData data = new UserEnteredData(); + + // Save Action radio-buttons state + if( deviceRadioButton.getSelection() ){ + data.saveRadioButtonSelection(ValueTypes.SWMT, 2); + } + else { + data.saveRadioButtonSelection(ValueTypes.SWMT, 1); + } + data.saveValue(ValueTypes.SWMT, timerCombo.getText()); + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#deviceError(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherErrorType) + */ + public void deviceError( final LauncherErrorType error ){ + + Date date = new Date (System.currentTimeMillis()); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.deviceError: '" + error.name() +"' time:'" +date.toString() + "'."); //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ + + // Set MemSpy's state correct + memSpyOperationRunning = false; + memSpyTimerRunning = false; + + // change Cancel text from wizard back to "Cancel" + this.setCancelText( "Cancel" ); + + // Getting user visible error message + errorMessage = UiUtils.getErrorMessageForLauncherError(error, traceEngine.getAdditionalErrorInformation(), traceEngine.getProgressStatus()); //$NON-NLS-1$ + + // Handling SWMT-specific logic related to the error + switch (error){ + case DUMPED_TRACES:{ + this.receivedLog = null; + break; + } + case CATEGORIES_NOT_SUPPORTED:{ + disableSWMTCategoryFeature(); + break; + } + } + + // Add reset info into error message. + if(error != LauncherErrorType.CATEGORIES_NOT_SUPPORTED){ + errorMessage = errorMessage + ERROR_SWMT_NEEDS_RESET; + } + + // Set missedLogs value to true so that logs cannot be requested anymore because of missed logs. + missedLogs = true; + + // Advising user to install launcher component to the device + UiUtils.showErrorDialogToUser(error, errorMessage, traceEngine.getProgressStatus()); + } + + /** + * Disables SWMT category feature for the rest of the session in case is was not supported by the device. + */ + private void disableSWMTCategoryFeature() { + Runnable disableRunnable = new Runnable(){ + + public void run() { + try { + MemSpyPlugin.getDefault().setSWMTCategorySettingFeatureEnabled(false); + MemSpyPreferences.setProfileTrackedCategoriesSelected(true); + categoryGroupComposite.disableCustomCategorySelection(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }; + + Display.getDefault().asyncExec(disableRunnable); + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction) + */ + public void operationFinished(LauncherAction action) { + + // reset missed logs. + missedLogs = false; + + if( action == LauncherAction.SWMT_UPDATE ){ + cycleNumber++; + this.updateReceivedSWMTLog( false ); + } + + } + + /** + * Does actions that are made when SWMT log is received. + */ + private void updateReceivedSWMTLog( final boolean timerRunning ){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.updateReceivedSWMTLog/timerRunning=" + timerRunning ); //$NON-NLS-1$ + + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + + // get date formatter + SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT ); + String date = formatter.format(receivedLog.getDate() ); + // get files name + String path = receivedLog.getPath().substring( receivedLog.getPath().lastIndexOf("\\") + 1 ); + + // add log into table + TableItem item = new TableItem( deviceLogsTable, SWT.NONE, deviceLogsTable.getItemCount() ); + item.setText( new String[]{ path, date }); + + // add receivedlog-object into deviceLogsList-Arraylist + deviceLogList.add( receivedLog ); + + if( timerRunning ){ + // show progress bar + memSpyTimerRunning = true; + memSpyOperationRunning = false; + + } + else{ + + // change Cancel text from wizard back to "Cancel" + setCancelText("Cancel"); + + // Set state correct + memSpyOperationRunning = false; + + } + } + + }; + Display.getDefault().asyncExec(updateUiRunnable); + } + + /** + * Enables and disables device buttons and SWMT category group UI according to current situation + */ + private void enableAndDisableDeviceButtonsAndSWMTCategoryGroup(){ + + // Refreshes enable/disable status for SWMT category group UI + categoryGroupComposite.refresh(); + + // if log table is not empty, enable remove all button. + if( this.deviceLogsTable.getItemCount() > 0 ){ + this.connectionSettingsButton.setEnabled(false); + this.removeReceivedLogsButton.setEnabled(true); + this.categoryGroupComposite.setButtonsEnabled(false); + this.categoryGroupComposite.setEnabled(false); + if( this.missedLogs ){ + this.getLogNowButton.setEnabled(false); + this.startTimerButton.setEnabled(false); + } + } + else{ + this.connectionSettingsButton.setEnabled(true); + this.removeReceivedLogsButton.setEnabled(false); + this.categoryGroupComposite.setButtonsEnabled(true); + this.categoryGroupComposite.setEnabled(true); + if( !this.missedLogs ){ + this.getLogNowButton.setEnabled(true); + this.startTimerButton.setEnabled(true); + } + } + } + + /** + * Enables and disables file buttons according to current situation. + */ + private void enableAndDisableFileButtons(){ + + // If one log is selected, enable Remove button, otherwise disable it + if( this.fileLogsTable.getSelectionCount() == 1 ){ + this.removeOneButton.setEnabled(true); + } + else{ + this.removeOneButton.setEnabled(false); + } + + // if log table is not empty, enable remove all button. + if( this.fileLogsTable.getItemCount() > 0 ){ + this.removeAllButton.setEnabled(true); + } + else{ + this.removeAllButton.setEnabled(false); + } + + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage() + */ + public boolean canFlipToNextPage() { + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": createControl()"); //$NON-NLS-1$ + + // Radio button group + Composite composite = new Composite(parent, SWT.NULL); + + // create the desired layout for this wizard page + GridLayout gl = new GridLayout(); + gl.numColumns = 1; + composite.setLayout(gl); + + //Create group where to select if import from File System / From Device + createRadioButtonGroup(composite); + + //Create group where import logs from File + createImportFromFileGroup(composite); + + //Create group where import logs from Device + createImportFromDeviceGroup(composite); + + + // load saved user entered data. + this.loadUserEnteredData(); + + // update buttons and texts on screen. + this.updateConnectionText(); + + // Enable/disable buttons + this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); //will call also #enableOrDisableHeapFilterText(); + this.enableAndDisableFileButtons(); + + this.hideAndRevealItems(); + + // Setting context-sensitive help ID + PlatformUI.getWorkbench().getHelpSystem().setHelp( composite, HelpContextIDs.MEMSPY_IMPORT_SWMT); + + setInitialFocus(); + setControl(composite); + } + + private void createImportFromDeviceGroup(Composite parent) { + // Device group + + deviceGroup = new Group(parent, SWT.NONE); + GridLayout deviceGridLayout = new GridLayout(); + deviceGridLayout.numColumns = 2; + + deviceGridData = new GridData(GridData.FILL_BOTH); + deviceGroup.setLayoutData(deviceGridData); + deviceGroup.setLayout(deviceGridLayout); + deviceGroup.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON); + + + + // Logs from device table + + deviceLogsTable = new Table(deviceGroup, SWT.BORDER); + GridData tableGridData = new GridData(GridData.FILL_BOTH); + deviceLogsTable.setLayoutData(tableGridData); + + TableColumn logsColumn = new TableColumn(deviceLogsTable, SWT.LEFT); + logsColumn.setText(LOGS); + logsColumn.setWidth(300); + + TableColumn receivedColumn = new TableColumn(deviceLogsTable, SWT.LEFT); + receivedColumn.setText(RECEIVED); + receivedColumn.setWidth(110); + + GridData deviceLogsTableGridData = new GridData(GridData.FILL_BOTH); + deviceLogsTable.setLayoutData(deviceLogsTableGridData); + deviceLogsTable.setHeaderVisible(true); + deviceLogsTable.addSelectionListener(this); + + + // + //Create logging composite, contains Get log now, Get log with timer and remove logs functions + // + createLoggingComposite(deviceGroup); + + // + //Bottom composite where settings and categories are located + // + Composite bottomComposite = new Composite(deviceGroup,SWT.NONE); + GridLayout pgl = new GridLayout(2, false); + pgl.marginHeight = 0; + pgl.marginWidth = 0; + GridData pgd = new GridData(GridData.VERTICAL_ALIGN_END | GridData.FILL_HORIZONTAL); + bottomComposite.setLayout(pgl); + bottomComposite.setLayoutData(pgd); + + // + //Create Connection settings group + // + createConnectionSettingsGroup(bottomComposite); + + // + // Create and add SWMT category setting group + // + categoryGroupComposite = new SWMTCategoryGroupComposite(bottomComposite, false, this, MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()); + + } + + private void createLoggingComposite(Composite parent) { + + loggingComposite = new Composite(parent, SWT.NONE); + GridLayout deviceButtonLayout = new GridLayout(); + GridData deviceButtonGridData = new GridData(SWT.FILL, SWT.FILL, true, true);//GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_CENTER + deviceButtonLayout.numColumns = 1; + loggingComposite.setLayoutData(deviceButtonGridData); + loggingComposite.setLayout(deviceButtonLayout); + + // + // Get Log now button + // + Composite getLogComposite = new Composite(loggingComposite, SWT.NONE); + GridLayout getLogLayout = new GridLayout(); + GridData getLogGD = new GridData(SWT.FILL, SWT.BEGINNING, true, false); + getLogComposite.setLayoutData(getLogGD); + getLogComposite.setLayout(getLogLayout); + + //Null label is added with no text to align get log now + @SuppressWarnings("unused") + Label nullLabel = new Label(getLogComposite,SWT.NULL); + + getLogNowButton = new Button(getLogComposite, SWT.PUSH); + getLogNowButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL ));//| GridData.VERTICAL_ALIGN_BEGINNING + getLogNowButton.setText(GET_LOG_NOW_BUTTON); + getLogNowButton.addSelectionListener(this); + + // + // Timer composite + // + Composite timerComposite = new Composite(loggingComposite, SWT.NONE); + GridLayout timerLayout = new GridLayout(); + timerLayout.marginWidth = 0; + GridData timerGD = new GridData(SWT.FILL, SWT.CENTER, true, true); + timerComposite.setLayoutData(timerGD); + timerComposite.setLayout(timerLayout); + + createTimerComposite(timerComposite); + + // + // Remove all files button + // + Composite removeComposite = new Composite(loggingComposite, SWT.NONE); + GridLayout removeLayout = new GridLayout(); + GridData removeGD = new GridData(SWT.FILL, SWT.BOTTOM, true, false); + removeComposite.setLayoutData(removeGD); + removeComposite.setLayout(removeLayout); + + removeReceivedLogsButton = new Button(removeComposite, SWT.PUSH); + removeReceivedLogsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));//| GridData.VERTICAL_ALIGN_END + removeReceivedLogsButton.setText(REMOVE_ALL); + removeReceivedLogsButton.addSelectionListener(this); + } + + private void createConnectionSettingsGroup(Composite parent) { + Group connectionSettingsGroup = new Group(parent, SWT.NONE); + connectionSettingsGroup.setText("Connection"); + GridLayout connectionGroupLayout = new GridLayout(); + connectionGroupLayout.numColumns = 1; + connectionSettingsGroup.setLayout(connectionGroupLayout); + GridData connectionGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + connectionSettingsGroup.setLayoutData(connectionGridData); + + + connectionSettingsButton = new Button(connectionSettingsGroup, SWT.PUSH); + connectionSettingsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + connectionSettingsButton.setText(CONNECTION_SETTINGS_BUTTON); + connectionSettingsButton.addSelectionListener(this); + + // Connection settings labels + Label connectionTextLabel = new Label(connectionSettingsGroup, SWT.LEFT); + connectionTextLabel.setText(CURRENTLY_USING_TEXT); + connectionTextLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + + connectionNameInUseLabel = new Label(connectionSettingsGroup, SWT.LEFT); + connectionNameInUseLabel.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_CENTER) ); + } + + private void createImportFromFileGroup(Composite parent) { + // File selection group + + fileSelectionGroup = new Group(parent, SWT.NONE); + GridLayout fileSelectionGridLayout = new GridLayout(); + fileSelectionGridLayout.numColumns = 2; + + fileSelectionGridData = new GridData(GridData.FILL_BOTH); + fileSelectionGroup.setLayoutData(fileSelectionGridData); + fileSelectionGroup.setLayout(fileSelectionGridLayout); + fileSelectionGroup.setText(GET_FROM_FROM_FILE_RADIO_BUTTON); + + // Logs from file table + + fileLogsTable = new Table(fileSelectionGroup, SWT.BORDER); + TableColumn fileColumn = new TableColumn(fileLogsTable, SWT.LEFT); + fileColumn.setText(LOG_FILES); + fileColumn.setWidth(300); + + TableColumn nameColumn = new TableColumn(fileLogsTable, SWT.LEFT); + nameColumn.setText(LOG_TYPE); + nameColumn.setWidth(100); + + GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH); + fileLogsTable.setLayoutData(fileLogsTableGridData); + fileLogsTable.setHeaderVisible(true); + fileLogsTable.addSelectionListener(this); + + // File Selection button composite. Contains file operation buttons + + fileSelectionButtonComposite = new Composite(fileSelectionGroup, SWT.NONE); + GridLayout threadButtonLayout = new GridLayout(); + GridData fileSelectionButtonGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + fileSelectionButtonComposite.setLayoutData(fileSelectionButtonGridData); + fileSelectionButtonComposite.setLayout(threadButtonLayout); + threadButtonLayout.numColumns = 1; + + // Add file button + addFileButton = new Button(fileSelectionButtonComposite, SWT.PUSH); + addFileButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + addFileButton.setText(ADD_FILE); + addFileButton.addSelectionListener(this); + + // Add folder button + addDirectoryButton = new Button(fileSelectionButtonComposite, SWT.PUSH); + addDirectoryButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + addDirectoryButton.setText(ADD_DIRECTORY); + addDirectoryButton.addSelectionListener(this); + + // Remove one file button + removeOneButton = new Button(fileSelectionButtonComposite, SWT.PUSH); + removeOneButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + removeOneButton.setText(REMOVE_ONE); + removeOneButton.addSelectionListener(this); + + // Remove all files and folders button + removeAllButton = new Button(fileSelectionButtonComposite, SWT.PUSH); + removeAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + removeAllButton.setText(REMOVE_ALL); + removeAllButton.addSelectionListener(this); + } + + private void createRadioButtonGroup(Composite parent) { + // Radio button group + GridLayout radioButtonGroupGridLayout = new GridLayout(); + radioButtonGroup = new Group(parent, SWT.NONE); + radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + radioButtonGroup.setText(GET_LOG_FROM_RADIO_BUTTON); + radioButtonGroup.setLayout(radioButtonGroupGridLayout); + GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL); + radioButtonGridData.horizontalSpan = 2; + + // File radio button + fileRadioButton = new Button(radioButtonGroup, SWT.RADIO); + fileRadioButton.setText(GET_FROM_FROM_FILE_RADIO_BUTTON); + fileRadioButton.setLayoutData(radioButtonGridData); + fileRadioButton.addSelectionListener(this); + fileRadioButton.setSelection(true); + + // From Device via TraceViewer radio button + deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO); + deviceRadioButton.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON); + deviceRadioButton.setLayoutData(radioButtonGridData); + deviceRadioButton.addSelectionListener(this); + deviceRadioButton.setSelection(false); + + // In case trace plugin is not available, disabling import from device selection + if(!MemSpyPlugin.isTraceProviderAvailable()){ + deviceRadioButton.setEnabled(false); + } + } + + private void createTimerComposite(Composite parent) { + // Timer UI-components + + Group timerComposite = new Group(parent, SWT.NONE); + timerComposite.setText(TEXT_GET_LOG_WITH_TIMER); + + GridLayout timerLayout = new GridLayout(); + timerLayout.numColumns = 2; + GridData timerGd = new GridData(SWT.FILL, SWT.CENTER, true, true);; + timerComposite.setLayoutData( timerGd ); + timerComposite.setLayout( timerLayout ); + + + // Interval- label + intervalLabel = new Label( timerComposite, SWT.LEFT ); + intervalLabel.setText( TEXT_INTERVAL ); + GridData intervalGd = new GridData(); + intervalGd.horizontalSpan = 2; + intervalLabel.setLayoutData( intervalGd ); + + // Timer combo box + timerCombo = new Combo( timerComposite, SWT.BORDER); + GridData timerComboGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + timerComboGridData.widthHint = 25; + timerCombo.setLayoutData( timerComboGridData ); + timerCombo.setTextLimit(3); + + // Interval- label + secondLabel = new Label( timerComposite, SWT.LEFT ); + secondLabel.setText( TEXT_SECOND ); + GridData secondLabelLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + secondLabel.setLayoutData( secondLabelLayoutData ); + + // Start timer - button + startTimerButton = new Button(timerComposite, SWT.PUSH); + GridData startTimerGridData = new GridData( GridData.FILL_HORIZONTAL ); + startTimerGridData.horizontalSpan = 2; + startTimerButton.setLayoutData( startTimerGridData ); + startTimerButton.setText( START_TIMER ); + startTimerButton.addSelectionListener(this); + + + } + + + /** + * Checks if device radio buttons is selected. + * @return true if device radio button is selected, otherwise false. + */ + public boolean isDeviceRadioButtonSelected(){ + return deviceRadioButton.getSelection(); + } + + /** + * Updates connection settings. + */ + public void updateConnectionSettings() { + this.updateConnectionText(); + } + + + /** + * Gets timer interval from interval UI-component. + * If interval set to text box is not valid, method prints error message and returns value 0. + * @return current timer interval + */ + private int getTimerInteval() { + boolean showError = false; + + int integer = 0; + try{ + integer = Integer.parseInt( timerCombo.getText() ); + } + catch( NumberFormatException e ){ + // show error message of interval is not integer. + showError = true; + } + + if( integer <= 0 && showError == false ){ + // show error message if integer is negative or zero. + showError = true; + } + + if( showError ){ + // open error dialog and print error message + Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, ERROR_INTERVAL, null); + ErrorDialog.openError(Display.getCurrent().getActiveShell(),"MemSpy Error", null, status); + return 0; + } + + return integer; + + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction, com.nokia.s60tools.memspy.containers.SWMTLogInfo) + */ + public void operationFinished(LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning) { + if( action == LauncherAction.TIMED_SWMT_UPDATE ){ + + // update received log to table + this.receivedLog = swmtLogInfo; + this.updateReceivedSWMTLog( timerRunning ); + + // increase cycle number + cycleNumber++; + } + } + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#startedReceivingSWMTLog() + */ + public void startedReceivingSWMTLog() { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.startedReceivingSWMTLog"); //$NON-NLS-1$ + + // Set MemSpy's state correct + this.memSpyOperationRunning = true; + this.memSpyTimerRunning = false; + } + + /** + * Method that is called when "Get Log Now" - button is pressed. + */ + private void getLogNowPressed(){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed"); //$NON-NLS-1$ + + // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted. + boolean reset = false; + if( deviceLogsTable.getItemCount() == 0 ){ + reset = true; + cycleNumber = 1; + } + + //Check if S60 application is ment to reset between cycles + boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected(); + if(isToBeClosedBetweenCycles){ + reset = true; + } + + // Create new SWMTLogInfo object + receivedLog = new SWMTLogInfo(); + + // get temp file name for swmt-log + Date date = new Date(); + receivedLog.setPath( MemSpyFileOperations.getTempFileNameForSWMTLog( cycleNumber, date ) ); + receivedLog.setType( SWMTLogType.FILE ); + receivedLog.setDate(date); + receivedLog.setType(SWMTLogType.DEVICE); + + if( traceEngine.requestSWMTLog( this, receivedLog.getPath(), reset) ){ + + try { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$ + getContainer().run(true, false, receiveSWMTLogProcess); + } catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/openError"); //$NON-NLS-1$ + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); + receivedLog = null; + } + } + + + /** + * Method that is called when "Start Timer" - button is pressed. + */ + private void getLogWithTimerPressed(){ + + int interval = this.getTimerInteval(); + + // if interval is not zero continue + if( interval != 0 ){ + + // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted. + boolean reset = false; + if( deviceLogsTable.getItemCount() == 0 ){ + reset = true; + cycleNumber = 1; + } + + boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected(); + + // if connect to trace source was established + if( traceEngine.startSWMTTimer(this, cycleNumber, reset, isToBeClosedBetweenCycles, interval) ){ + + // change Cancel text from wizard to "Stop Timer" + setCancelText("Stop Timer"); + + // launch receiveSWMTLog process. + try { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogWithTimerPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$ + getContainer().run(true, true, receiveSWMTLogProcess); + } catch (InvocationTargetException e1) { + // do nothing + e1.printStackTrace(); + } catch (InterruptedException e1) { + // do nothing + e1.printStackTrace(); + } + + // Enable/Disable device buttons. + enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); + + } + else{ + // increase cycle number + cycleNumber++; + + // show error message + MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); + + } + } + } + + /** + * Method that is called when stop timer-button is pressed. + */ + private void stopTimerPressed(){ + + this.memSpyTimerRunning = false; + if( traceEngine.stopSWMTTimer() ){ + // if timer is stopped immediately, hide progress bar + memSpyStopping = false; + + this.setCancelText("Cancel"); + } + } + + /** + * Created needed MemSpy processes. + */ + private void createMemSpyProcesses(){ + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.createMemSpyProcesses/receiveSWMTLogProcess"); //$NON-NLS-1$ + + // receive SWMT-Log process + receiveSWMTLogProcess = new IRunnableWithProgress() { + /** + * In receive SWMT-Log process process views progress bar and checks every 0,5 seconds + * if current MemSpy process has been finished. After MemSpy process has finished. Progress + * bar is hidden. + */ + public void run(IProgressMonitor monitor) { + memSpyOperationRunning = true; + + monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN); + while(true){ + // some delay, so that launcher has time to set it's state correct. + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // do nothing + } + + // If no operations are on-going, break + if( !memSpyOperationRunning && !memSpyTimerRunning && !memSpyStopping ){ + break; + } + + // If Cancel-message received, send stop request. + if( monitor.isCanceled() ){ + monitor.beginTask(STOPPING_TIMER, IProgressMonitor.UNKNOWN); + stopTimerPressed(); + } + + // If timer and operation are running, show "Waiting for timer to expire"-text + else if ( memSpyTimerRunning ){ + monitor.beginTask(WAITING_FOR_TIMER, IProgressMonitor.UNKNOWN); + } + + // If MemSpy operation is running, show "Requesting Heap Dump" -text + else if( memSpyOperationRunning ){ + monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN); + } + } + monitor.done(); + } + }; + } + + /** + * Changes wizard's cancel button's text. + * @param newText new text for button + */ + private void setCancelText( final String newText ){ + Runnable updateUiRunnable = new Runnable(){ + public void run(){ + // change Cancel text from wizard back to "Cancel" + ( (MemSpyWizard)getWizard() ).setCancelText( newText ); + } + }; + // needs to be done on UI thread. + Display.getDefault().asyncExec(updateUiRunnable); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategoryGroupComposite.SWMTCategorySelectionChangeListener#categorySelectionChanged(int) + */ + public void setCategorySelection(int newCategorySelection, boolean isProfileSettings) { + traceEngine.setCategoriesForSWMT(newCategorySelection, isProfileSettings); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getCategorySelection() + */ + public int getCategorySelection() { + return traceEngine.getCategoriesForSWMT(); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#setAllTrackedCategoriesSelected(boolean) + */ + public void setProfileTrackedCategoriesSelected( + boolean isAllCategoriesSelected) { + traceEngine.setProfileTrackedCategoriesSelected(isAllCategoriesSelected); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getAllTrackedCategoriesSelected() + */ + public boolean isProfileTrackedCategoriesSelected() { + return traceEngine.isProfileTrackedCategoriesSelected(); + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.DialogPage#dispose() + */ + public void dispose(){ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": dispose()"); //$NON-NLS-1$ + categoryGroupComposite.dispose(); + super.dispose(); + } + + +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SelectActionPage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SelectActionPage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +package com.nokia.s60tools.memspy.ui.wizards; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.memspy.model.UserEnteredData; +import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; +import com.nokia.s60tools.memspy.resources.HelpContextIDs; +import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; + +public class SelectActionPage extends S60ToolsWizardPage{ + + // Available actions + public enum MemSpyAction{IMPORT_HEAP, COMPARE_HEAPS, SWMT} + + // UI components + public Button importHeapRadioButton; + public Button compareTwoHeapsRadioButton; + public Button swmtRadioButton; + + /* + * (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus() + */ + public void setInitialFocus() { + } + + public void recalculateButtonStates() { + } + + + protected SelectActionPage(String pageName) { + super(pageName); + setTitle("MemSpy Import Wizard, First step"); + setDescription("Select action you wish to perform with MemSpy."); + } + public void createControl(Composite parent) { + // Radio button group + + Composite composite = new Composite(parent, SWT.NULL); + + // create the desired layout for this wizard page + GridLayout gl = new GridLayout(); + gl.numColumns = 1; + composite.setLayout(gl); + + // Radio Button Group + GridLayout radioButtonGroupGridLayout = new GridLayout(); + Group radioButtonGroup = new Group (composite, SWT.NONE); + radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + radioButtonGroup.setText("Select Action:"); + radioButtonGroup.setLayout(radioButtonGroupGridLayout); + GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL); + radioButtonGridData.horizontalSpan = 2; + + // Import Heap wizard radio button + importHeapRadioButton = new Button(radioButtonGroup, SWT.RADIO); + importHeapRadioButton.setText("Import heap and analyse log with Heap Analyser"); + importHeapRadioButton.setLayoutData(radioButtonGridData); + + // Compare Two Heaps radio button + compareTwoHeapsRadioButton = new Button(radioButtonGroup, SWT.RADIO); + compareTwoHeapsRadioButton.setText("Import heaps and compare logs with Heap Analyser"); + compareTwoHeapsRadioButton.setLayoutData(radioButtonGridData); + + // SWMT wizard radio button + swmtRadioButton = new Button(radioButtonGroup, SWT.RADIO); + swmtRadioButton.setText("Import System Wide Memory Tracking logs and analyse them with SWMT Analyser"); + swmtRadioButton.setLayoutData(radioButtonGridData); + + // restore previous value of radio button. + // if last value is not found, set selection to import heap + + UserEnteredData data = new UserEnteredData(); + int lastUsed = data.getPreviousRadioButtonSelection(ValueTypes.SELECT_ACTION); + + if( lastUsed == 2 ){ + compareTwoHeapsRadioButton.setSelection(true); + } + else if( lastUsed == 3 ){ + swmtRadioButton.setSelection(true); + } + else { + importHeapRadioButton.setSelection(true); + } + + setHelps(); + setInitialFocus(); + setControl(composite); + } + + /** + * getAction + * @return currently selected action + */ + public MemSpyAction getAction(){ + if( importHeapRadioButton.getSelection() ){ + return MemSpyAction.IMPORT_HEAP; + } + else if( compareTwoHeapsRadioButton.getSelection() ){ + return MemSpyAction.COMPARE_HEAPS; + } + else{ + return MemSpyAction.SWMT; + } + + } + + + /** + * saves user entered data from UI components so that it can be restored later. + */ + public void saveUserEnteredData(){ + UserEnteredData data = new UserEnteredData(); + + // Save Action radio-buttons state + if( compareTwoHeapsRadioButton.getSelection() ){ + data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 2); + } + else if( swmtRadioButton.getSelection() ){ + data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 3); + } + else { + data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 1); + } + } + + /** + * canFlipPreviousPage + * returns always false because this is first page of wizard. + */ + public boolean canFlipPreviousPage(){ + return false; + } + + /** + * Sets this page's context sensitive helps + * + */ + protected void setHelps() { + PlatformUI.getWorkbench().getHelpSystem().setHelp( importHeapRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION); + PlatformUI.getWorkbench().getHelpSystem().setHelp( compareTwoHeapsRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION); + PlatformUI.getWorkbench().getHelpSystem().setHelp( swmtRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION); + PlatformUI.getWorkbench().getHelpSystem().setHelp( this.getShell(), HelpContextIDs.MEMSPY_SELECT_ACTION); + + } + +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/util/MemSpyConsole.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/util/MemSpyConsole.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.memspy.util; + +import org.eclipse.jface.resource.ImageDescriptor; + +import com.nokia.s60tools.memspy.resources.ImageKeys; +import com.nokia.s60tools.memspy.resources.ImageResourceManager; +import com.nokia.s60tools.util.console.AbstractProductSpecificConsole; + +/** + * Singleton class that offers console printing + * services for the MemSpy plug-in. + */ +public class MemSpyConsole extends AbstractProductSpecificConsole { + + /** + * Singleton instance of the class. + */ + static private MemSpyConsole instance = null; + + /** + * Public accessor method. + * @return Singleton instance of the class. + */ + static public MemSpyConsole getInstance(){ + if(instance == null ){ + instance = new MemSpyConsole(); + } + return instance; + } + + /** + * Private constructor forcing Singleton usage of the class. + */ + private MemSpyConsole(){ + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.util.console.AbstractProductSpecificConsole#getProductConsoleName() + */ + protected String getProductConsoleName() { + return "MemSpy Console"; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.util.console.AbstractProductSpecificConsole#getProductConsoleImageDescriptor() + */ + protected ImageDescriptor getProductConsoleImageDescriptor() { + return ImageResourceManager.getImageDescriptor(ImageKeys.IMG_APP_ICON); + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.classpath Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,7 @@ + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.settings/org.eclipse.jdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,8 @@ +#Tue Sep 22 14:04:29 EEST 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/META-INF/MANIFEST.MF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Carbide.c++ Extensions - SWMT Analyser Thirdpartysources +Bundle-SymbolicName: com.nokia.s60tools.swmtanalyser.thirdpartysources +Bundle-Version: 1.6.0 +Bundle-Activator: com.nokia.s60tools.swmtanalyser.thirdpartysources.Activator +Bundle-Vendor: Nokia +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/about.html Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ + + + +About + + + +

About This Content

+ +

Dec 11, 2009

+ +

Copyright

+ +

+ +

Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: http://www.eclipse.org/legal/epl-v10.html.

+ +

+ + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + iText-src-2.1.7.zip,\ + about.html diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/iText-src-2.1.7.zip Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/iText-src-2.1.7.zip has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/src/com/nokia/s60tools/swmtanalyser/thirdpartysources/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/src/com/nokia/s60tools/swmtanalyser/thirdpartysources/Activator.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.thirdpartysources; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + /** + * The plug-in ID for third party sources plugin + */ + public static final String PLUGIN_ID = "com.nokia.s60tools.swmtanalyser.thirdpartysources"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.classpath Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,11 @@ + + + + + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.settings/org.eclipse.jdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,8 @@ +#Tue Sep 22 14:04:40 EEST 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/META-INF/MANIFEST.MF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Carbide.c++ Extensions - Swmt Analyser +Bundle-SymbolicName: com.nokia.s60tools.swmtanalyser;singleton:=true +Bundle-Version: 1.6.0 +Bundle-Activator: com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin +Bundle-Vendor: Nokia +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.forms, + com.nokia.s60tools.ui;bundle-version="1.5.0", + org.eclipse.core.filesystem, + org.eclipse.core.resources, + org.eclipse.ui.ide, + org.eclipse.ui.editors, + org.eclipse.draw2d, + com.nokia.s60tools.util;bundle-version="1.5.0" +Bundle-ActivationPolicy: lazy +Bundle-ClassPath: poi-3.2-FINAL-20081019.jar, + poi-contrib-3.2-FINAL-20081019.jar, + poi-scratchpad-3.2-FINAL-20081019.jar, + iText-2.1.7.jar, + . +Export-Package: com.nokia.s60tools.swmtanalyser.data;x-friends:="com.nokia.s60tools.swmtanalyser.tests", + com.nokia.s60tools.swmtanalyser.exception;x-friends:="com.nokia.s60tools.swmtanalyser.tests", + com.nokia.s60tools.swmtanalyser.model;x-friends:="com.nokia.s60tools.swmtanalyser.tests", + com.nokia.s60tools.swmtanalyser.ui.actions +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/about.html Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,22 @@ + + + +About + + + +

About This Content

+ +

Dec 11, 2009

+ +

Copyright

+ +

+ +

Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: http://www.eclipse.org/legal/epl-v10.html.

+ +

+ + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/build.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/build.properties Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,13 @@ +javacSource=1.5 +javacTarget=1.5 +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + poi-3.2-FINAL-20081019.jar,\ + poi-contrib-3.2-FINAL-20081019.jar,\ + poi-scratchpad-3.2-FINAL-20081019.jar,\ + icons/,\ + iText-2.1.7.jar,\ + about.html diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/iText-2.1.7.jar Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/iText-2.1.7.jar has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/Launch_SWMT.png Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/Launch_SWMT.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/green.png Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/green.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/red.png Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/red.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/yellow.png Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/yellow.png has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/plugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/plugin.xml Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,13 @@ + + + + + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-3.2-FINAL-20081019.jar Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-3.2-FINAL-20081019.jar has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-contrib-3.2-FINAL-20081019.jar Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-contrib-3.2-FINAL-20081019.jar has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-scratchpad-3.2-FINAL-20081019.jar Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-scratchpad-3.2-FINAL-20081019.jar has changed diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/SwmtAnalyserPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/SwmtAnalyserPlugin.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.nokia.s60tools.swmtanalyser.analysers.IAnalyser; +import com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser; +import com.nokia.s60tools.swmtanalyser.analysers.ThreadDataAnalyser; +import com.nokia.s60tools.util.console.IConsolePrintUtility; + +/** + * The activator class controls the plug-in life cycle + */ +public class SwmtAnalyserPlugin extends AbstractUIPlugin { + + ArrayList Analysers = new ArrayList(); + + // The plug-in ID + public static final String PLUGIN_ID = "com.nokia.s60tools.swmtanalyser"; + + // The shared instance + private static SwmtAnalyserPlugin plugin; + + private String pluginInstallPath = ""; + + /** + * Console for plug-in + */ + private IConsolePrintUtility console; + + /** + * The constructor + */ + public SwmtAnalyserPlugin() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + registerAnalyser(new LinearAnalyser()); + registerAnalyser(new ThreadDataAnalyser()); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static SwmtAnalyserPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } + + /** + * @param analyser will be registered for analysis. The tool invokes analysis + * on all registered analysers. + */ + public void registerAnalyser(IAnalyser analyser) + { + if(!Analysers.contains(analyser)) + Analysers.add(analyser); + } + + public IAnalyser [] getRegisteredAnalysers() + { + return Analysers.toArray(new IAnalyser[0]); + } + + public static String getPluginInstallPath() { + try { + if ("".equals(plugin.pluginInstallPath)) { + // URL to the plugin's root ("/") + URL relativeURL = plugin.getBundle().getEntry("/"); + // Converting into local path + URL localURL = FileLocator.toFileURL(relativeURL); + // Getting install location in correct form + File f = new File(localURL.getPath()); + plugin.pluginInstallPath = f.getAbsolutePath(); + } + return plugin.pluginInstallPath; + } catch (Exception e) { + return ""; + } + } + + /** + * Set the IConsolePrintUtility for plug-in + * @param console + */ + public void setConsole(IConsolePrintUtility console) { + this.console = console; + } + + /** + * Get the console print utility + * @return console + */ + public static IConsolePrintUtility getConsole(){ + return getDefault().getConsolePrintUtility(); + } + + /** + * Get the console print utility + * @return console + */ + private IConsolePrintUtility getConsolePrintUtility(){ + return console; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/AnalyserConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/AnalyserConstants.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; + +/** + * Constants for general Analyser purposes + */ +public class AnalyserConstants { + + /** + * Priority types + */ + public static enum Priority {NEGLIGIBLE,NORMAL,HIGH,CRITICAL} + /** + * Delta types + */ + public static enum DeltaType {SIZE, COUNT} + /** + * Color for Severity Normal + */ + public static final Color COLOR_SEVERITY_NORMAL = new Color(Display.getCurrent(),121,255,121);//Green + /** + * Color for Severity High + */ + public static final Color COLOR_SEVERITY_HIGH = new Color(Display.getCurrent(),255,255,138);//Yellow + /** + * Color for Severity Critical + */ + public static final Color COLOR_SEVERITY_CRITICAL = new Color(Display.getCurrent(),254,106,99);//Red + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/IAnalyser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/IAnalyser.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import com.nokia.s60tools.swmtanalyser.data.ParsedData; + +/** + * + * This Interface must be implemented by all swmt analysers + */ +public interface IAnalyser { + + + /** + * Analysis is started from this method. And all analysis results + * are added to a list. + * + * @param logData data objects of log file + */ + public void analyse(ParsedData logData); + + + /** + * The method returns the array of issues. + * @return results + */ + public Object [] getResults(); + + /** + * The method returns the array of children for a given issue. + * @param parent must be {@link ResultsParentNodes} + * @return childrens + */ + public Object [] getChildren (Object parent); +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/LinearAnalyser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/LinearAnalyser.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,537 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import java.text.DecimalFormat; +import java.util.ArrayList; + +import com.nokia.s60tools.swmtanalyser.data.DiskOverview; +import com.nokia.s60tools.swmtanalyser.data.KernelElements; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.data.SystemData; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; + +/** + * + * Defines Enum constants for all Kernel events to be analysed. + */ +enum KERNEL_EVENTS{ + NO_OF_THREADS("Number of Threads"), NO_OF_PROCESSES("Number of Processes"), + NO_OF_TIMERS("Number of Timers"), NO_OF_SEMAPHORES("Number of Semaphores"), + NO_OF_SERVERS("Number of Servers"), NO_OF_MSGQUEUES("Number of Msg. Queues"), + NO_OF_SESSIONS("Number of Sessions"), NO_OF_CHUNKS("Number of Chunks"); + + private String event_name; + private String event_cateogory = "System Data"; + + private KERNEL_EVENTS(String eventName) { + this.event_name = eventName; + } + + /** + * Returns event string + * @return name of the event + */ + public String getEventName() + { + return event_name; + } + + /** + * Returns event category + * @return category of the event + */ + public String getEventCategory() + { + return event_cateogory; + } +} + +/** + * Analyses RAM and DISK events and Kernal events. It implements interface IAnalyser. + * + */ +public class LinearAnalyser implements IAnalyser { + + /** + * {@link #RAM_AND_DISK_TITLE} and {@link #KERNEL_ELEMS_TITLE} issues + */ + ArrayList allIssues = new ArrayList(); + + protected static DecimalFormat Bytes_Format = new DecimalFormat("#####.##"); + protected int [] time_intervals = null; + + private static final String RAM_AND_DISK_TITLE = "RAM and Disk Memory"; + private static final String KERNEL_ELEMS_TITLE = "Kernel Elements"; + + private ParsedData logData = null; + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#analyse(com.nokia.s60tools.swmtanalyser.data.ParsedData) + */ + public void analyse(ParsedData logData) { + + this.logData = logData; + allIssues.clear(); + + //List to store RAM DISK issues + ArrayList ram_disk_issues = new ArrayList(); + + //Analyse RAM events using the logData and store the results in given list + analyseUsedRam(logData, ram_disk_issues); + //Analyse DISK events using the logData and store the results in given list + analyseDiskSizes(logData, ram_disk_issues); + + //Create parent for all RAM and Disks issues. + ResultsParentNodes ram_and_disk_node = new ResultsParentNodes(RAM_AND_DISK_TITLE); + ram_and_disk_node.setChildren(ram_disk_issues); + allIssues.add(ram_and_disk_node); + + //List to store Kernel issues + ArrayList kernel_issues = new ArrayList(); + //Analyse Kernel events using the logData and store the results in given list + analyseKernelHandles(logData, kernel_issues); + + //Create parent for all kernel issues found + ResultsParentNodes kernel_analysis_node = new ResultsParentNodes(KERNEL_ELEMS_TITLE); + kernel_analysis_node.setChildren(kernel_issues); + allIssues.add(kernel_analysis_node); + } + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#getResults() + */ + public Object[] getResults() { + return allIssues.toArray(); + } + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parent) + { + if(parent instanceof ResultsParentNodes && allIssues.contains(parent)) + { + return ((ResultsParentNodes)(parent)).getChildren(); + } + else + return null; + } + + /** + * This method linearly analyses the variation of used Ram size. + * @param logData signifies data of all seleced cycles. + * @param results signifies the list to which all issues will be added to. + */ + private void analyseUsedRam(ParsedData logData, ArrayList results) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + ArrayList systemData = utils.getSystemDataFromAllCycles(logData); + + //Store used memory values + long [] usedRamValues = new long[logData.getNumberOfCycles()]; + + //Calculate used memory using the total and free memroy + for(int i=0; i results) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + ArrayList diskNames = utils.getAllDiskNames(logData); + for(String disk:diskNames) { + ArrayList diskData = utils.getUsedMemoryAndSizesForDisk(disk, logData); + + //Store used memory values + long [] diskUsedValues = new long[logData.getNumberOfCycles()]; + for(int i=0; i results) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + ArrayList kernelElems = utils.getKerenelElemsFromAllCycles(logData); + + for(KERNEL_EVENTS event: KERNEL_EVENTS.values()){ + long [] event_values = new long[kernelElems.size()]; + for(int i=0; i 0) + overallNormalizedRoc[i] = overallNormalizedRoc[i-1] + normalizedRocWithTime[i]; + else if(normalizedRocWithTime[i] < 0) + overallNormalizedRoc[i] = -Math.log(-normalizedRocWithTime[i])+ overallNormalizedRoc[i-1]; + else + overallNormalizedRoc[i] = overallNormalizedRoc[i-1]; + } + + totalNormalizedRoc = overallNormalizedRoc[overallNormalizedRoc.length - 1]; + int growth_index = calculateStableGrowth(values); + double growiness_factor = Math.exp(growth_index); + + double log_of_first = 0; + double log_of_last = 0; + + if(values[values.length -1] != 0) + log_of_last = Math.log(values[values.length -1]); + + if(values[0] != 0) + log_of_first = Math.log(values[0]); + + double log_diff = log_of_last - log_of_first; + + double tmp = Math.round(Math.exp(totalNormalizedRoc)); + double final_growth_factor = tmp * log_diff + growiness_factor; + + return final_growth_factor; + } + + protected long [] calculateNormalizedRoC(long [] values) + { + long [] deltas = new long[values.length]; + long [] valueVsBaseline = new long[values.length]; + + deltas[0] = 0; + valueVsBaseline[0] = 0; + + for(int i=1; i 0) + { + if(valueVsBaseline[i] > 0) + normalizedRoC[i] = (long)Math.log(deltas[i]); + + else if(valueVsBaseline[i] < 0) + normalizedRoC[i] = (long)(Math.log(deltas[i] + valueVsBaseline[i])); + else + normalizedRoC[i] = 0; + } + else if(deltas[i] < 0) + normalizedRoC[i] = -(long)Math.log(-deltas[i]); + else + normalizedRoC[i] = 0; + } + + return normalizedRoC; + } + + private int calculateStableGrowth(long [] values) + { + int [] stableGrowiness = new int[values.length]; + + for(int i=0; i0) + { + long diff = values[i] - values[i-1]; + + if(diff > 0) + { + stableGrowiness[i] = stableGrowiness[i-1] + 1; + } + else if(diff == 0) + stableGrowiness[i] = stableGrowiness[i-1]; + else + { + if(values[i] > values[0]) + stableGrowiness[i] = stableGrowiness[i-1] - 1; + else + stableGrowiness[i] = 0; + } + } + } + + return stableGrowiness[stableGrowiness.length-1]; + } + + /** + * The method calculates priority of an issue, based on the values of + * growiness factor, delta factor and number of Cycles. + * @param growing_factor + * @param delta_factor + * @param noOfCycles + * @return priority of the issue. + */ + protected AnalyserConstants.Priority calculatePriorityFactor(double growing_factor, double delta_factor, int noOfCycles) + { + double high_threshold = Math.exp(noOfCycles - 1); + int temp = noOfCycles/2; + double normal_threshold = Math.exp(temp); + + int temp1 = noOfCycles/4; + double low_threshold = Math.exp(temp1); + + if(growing_factor > high_threshold) + { + if(delta_factor > 0) + return AnalyserConstants.Priority.CRITICAL; + } + if(growing_factor > normal_threshold) + { + if(delta_factor > 0.5) + return AnalyserConstants.Priority.CRITICAL; + else if(delta_factor > 0) + return AnalyserConstants.Priority.HIGH; + } + if(growing_factor > low_threshold) + { + if(delta_factor > 3) + return AnalyserConstants.Priority.CRITICAL; + else if(delta_factor > 0.5) + return AnalyserConstants.Priority.HIGH; + } + if(growing_factor > Math.exp(1)) + { + if(delta_factor > 5) + return AnalyserConstants.Priority.CRITICAL; + else if(delta_factor > 3) + return AnalyserConstants.Priority.HIGH; + } + if(growing_factor >0 && delta_factor > 0) + return AnalyserConstants.Priority.NORMAL; + + return AnalyserConstants.Priority.NEGLIGIBLE; + } + + /** + * The method formats the given value to Bytes, Kilo Bytes and Mega Bytes. + * @param bytes -- value to be formatted. + * @return formatted string in KB or MB + */ + protected String getFormattedBytes(long bytes) + { + String formatted_value = ""; + + if (bytes < 1024) + { + formatted_value += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + formatted_value += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + formatted_value += Bytes_Format.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + return formatted_value; + } + + /** + * The method calculates Growiness and priority based on given set of values. + * As no time intervals are provided, the method treats that the event is alive in all cycles (from first to last). + * @param event_values -- values of the event being analysed. + * @param result_elem -- structure to which calculated growiness and priority would be set to. + */ + protected void calculateGrowinessAndPriority(long [] event_values, ResultElements result_elem) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + if(time_intervals == null) + time_intervals = utils.getTimeIntervalsFromLogData(logData); + + calculateGrowinessAndPriority(event_values, time_intervals, result_elem); + + } + + /** + * The method calculates Growiness and priority based on given set of values and given time intervals + * @param event_values + * @param log_intervals + * @param result_elem + */ + protected void calculateGrowinessAndPriority(long [] event_values, int [] log_intervals, ResultElements result_elem) + { + double growiness = calculateGrowiness(event_values, log_intervals); + + long firstValue = event_values[0]; + long lastValue = event_values[event_values.length -1]; + + double log_of_first = 0; + double log_of_last = 0; + + if(firstValue != 0) + log_of_first = Math.log(firstValue); + if(lastValue != 0) + log_of_last = Math.log(lastValue); + + double prioritization_factor = log_of_last - log_of_first; + + AnalyserConstants.Priority priority = calculatePriorityFactor(growiness, prioritization_factor, log_intervals.length); + + result_elem.setGrowingFactor(growiness); + result_elem.setPriority(priority); + + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultElements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultElements.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import org.eclipse.swt.graphics.Color; +/** + * Input object for tree viewer in analysis tab. + * + */ +public class ResultElements implements Comparable{ + + /** + * Item name + */ + public static final String ITEM_NAME_COLUMN = "Item name"; + /** + * Event + */ + public static final String EVENT_COLUMN = "Event"; + /** + * Delta + */ + public static final String DELTA_COLUMN = "Delta"; + /** + * Severity + */ + public static final String SEVERITY_COLUMN = "Severity"; + + private static final String TAB = "\t"; + + private String itemName; + private String event; + private String delta; + private long delta_value; + private double growing_factor; + private Color color; + private long [] event_values; + + private AnalyserConstants.Priority priority = AnalyserConstants.Priority.NEGLIGIBLE; + private AnalyserConstants.DeltaType deltaType = AnalyserConstants.DeltaType.COUNT; + + /** + * Construction + * @param itemName + * @param event + * @param delta + * @param deltaValue + * @param type + */ + ResultElements(String itemName, String event, String delta, long deltaValue, AnalyserConstants.DeltaType type) + { + this.itemName = itemName; + this.event = event; + this.delta = delta; + this.delta_value = deltaValue; + this.deltaType = type; + } + + /** + * @return item name + */ + public String toString() + { + return this.itemName; + } + + + /** + * Get tab separated headers for this result. + * @return headers with tab as separator + */ + public String getTabSeparatedHeaders() + { + //NOTE: If reorganized, also #getTabSeparatedValues() must reorganize + StringBuffer b = new StringBuffer(); + b.append(ITEM_NAME_COLUMN); + b.append(TAB); + b.append(EVENT_COLUMN); + b.append(TAB); + b.append(DELTA_COLUMN); + b.append(TAB); + b.append(SEVERITY_COLUMN); + + return b.toString(); + + } + + /** + * Get tab separated values for this result. + * @return values + */ + public String getTabSeparatedValues() + { + //NOTE: If reorganized, also #getTabSeparatedHeaders() must reorganize + StringBuffer b = new StringBuffer(); + b.append(itemName); + b.append(TAB); + b.append(event); + b.append(TAB); + b.append(delta); + b.append(TAB); + b.append(getPriority()); + + return b.toString(); + + } + + + + /** + * Get delta + * @return delta + */ + public String getDelta() { + return delta; + } + + /** + * Set delta + * @param delta + */ + public void setDelta(String delta) { + this.delta = delta; + } + + /** + * Get item name + * @return item name + */ + public String getItemName() { + return itemName; + } + + /** + * Get event + * @return event + */ + public String getEvent() { + return event; + } + + /** + * Set event + * @param event + */ + public void setEvent(String event) { + this.event = event; + } + + /** + * Get growing factor + * @return growing factor + */ + public double getGrowingFactor() { + return growing_factor; + } + + /** + * Set growing factor + * @param growing_factor + */ + public void setGrowingFactor(double growing_factor) { + this.growing_factor = growing_factor; + } + + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(ResultElements input) { + + int priority_comparision = this.getPriority().compareTo(input.getPriority()); + + if(priority_comparision == 0) + { + if(this.growing_factor > input.growing_factor) + return 1; + else if(this.growing_factor < input.growing_factor) + return -1; + else + return 0; + } + else + return priority_comparision; + } + + /** + * Compare this objects {@link #getDelta()} to given object {@link #getDelta()} + * Returns a negative integer, zero, or a positive integer + * as this object is less than, equal to, or greater than the specified object. + * @param input + * @return 0 if this object is equal to given object, + * 1 if this object is greater to given object, + * -1 if this object is less to given object + */ + public int compareByDelta(ResultElements input) + { + long input_delta = input.getDeltaValue(); + + if(delta_value > input_delta) + return 1; + else if(delta_value < input_delta) + return -1; + else + return 0; + + } + /** + * Get priority + * @return priority + */ + public AnalyserConstants.Priority getPriority() { + return priority; + } + + /** + * Set priority + * @param priority + */ + public void setPriority(AnalyserConstants.Priority priority) { + this.priority = priority; + } + + /** + * Get delta + * @return delta + */ + public long getDeltaValue() { + return delta_value; + } + + /** + * Set delta + * @param delta_value + */ + public void setDeltaValue(long delta_value) { + this.delta_value = delta_value; + } + + /** + * Get Delta type + * @return delta type + */ + public AnalyserConstants.DeltaType getType() { + return deltaType; + } + + /** + * Set delta type + * @param type + */ + public void setType(AnalyserConstants.DeltaType type) { + this.deltaType = type; + } + + /** + * Get color + * @return color + */ + public Color getColor() { + return color; + } + + /** + * Set Color + * @param color + */ + public void setColor(Color color) { + this.color = color; + } + + /** + * Get event values + * @return values + */ + public long[] getEventValues() { + return event_values; + } + + /** + * Set event values + * @param event_values + */ + public void setEventValues(long[] event_values) { + this.event_values = event_values; + } +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultsParentNodes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultsParentNodes.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import java.util.ArrayList; +/** + * Input object(parent) for tree viewer in analysis tab. + * + */ +public class ResultsParentNodes{ + + private String description; + private ArrayList children; + private ArrayList filteredChildren = new ArrayList(); + + /** + * Construction + * @param description + */ + ResultsParentNodes(String description) + { + this.description = description; + } + + /** + * Set the childrens of this element + * @param childArrayList + */ + public void setChildren(ArrayList childArrayList) + { + this.children = childArrayList; + } + + /** + * Get childrens + * @return childrens as {@link ResultElements} + */ + public Object[] getChildren() + { + if(children != null) + return children.toArray(new ResultElements[0]); + else + return null; + } + + /** + * Get description + */ + public String toString() + { + return this.description; + } + + /** + * Add a filtered children + * @param child + */ + public void addFilteredChild(ResultElements child) + { + filteredChildren.add(child); + } + + /** + * Get all filtered childrens + * @return + */ + public ArrayList getFilteredChildrenList() + { + return filteredChildren; + } + /** + * Get count for filtered childrens + * @return count + */ + public int getFilteredCount() + { + return filteredChildren.size(); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ThreadDataAnalyser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ThreadDataAnalyser.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,264 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.analysers; + +import java.util.ArrayList; + +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.data.ThreadData; +import com.nokia.s60tools.swmtanalyser.data.ThreadSegments; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; + +/** + * + * Defines Enum constants for all Thread events to be analysed. + */ +enum THREAD_EVENTS { + + HEAP_SIZE("Heap size"), NO_OF_FILES("No of Files"), HEAP_ALLOC_SPACE("Heap allocated space"), HEAP_ALLOC_CELLS("Heap allocated cell count"), NO_OF_PSHANDLES("No of PS Handles"); + + private String description; + + THREAD_EVENTS(String desc) + { + description = desc; + } + public String getDescription() + { + return description; + } +} +/** + * Analyser class implementation for Thread data + */ +public class ThreadDataAnalyser extends LinearAnalyser{ + + private static final String THREADS_TITLE = "Threads"; + + ArrayList treeElements = new ArrayList(); + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#analyse(com.nokia.s60tools.swmtanalyser.data.ParsedData) + */ + public void analyse(ParsedData logData) { + + treeElements.clear(); + ResultsParentNodes thread_issues = new ResultsParentNodes(THREADS_TITLE); + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + ArrayList heapThreads = utils.getAllThreadNames(logData); + + int in = 0; + + ArrayList sub_issues = new ArrayList (); + + for(String thName: heapThreads) + { + ArrayList thData = utils.getHeapDataFromAllCycles(thName, logData); + ThreadSegments [] segments = utils.getHeapSegments(thData); + + if(segments != null){ + + THREAD_EVENTS [] events = THREAD_EVENTS.values(); + + for(THREAD_EVENTS event:events) + analyseThreadEvent(event, thName, thData, logData, segments, sub_issues); + + } + + in++; + } + + thread_issues.setChildren(sub_issues); + + treeElements.add(thread_issues); + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#getResults() + */ + public Object[] getResults() { + + return treeElements.toArray(); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parent) + { + if(parent instanceof ResultsParentNodes && treeElements.contains(parent)) + { + return ((ResultsParentNodes)(parent)).getChildren(); + } + else + return null; + } + + /** + * This method analyses data of given thread event + * @param event thread event to be analysed + * @param thName name of the thread + * @param heapData represents data of given thread from all log files + * @param logData represents data of all log files + * @param thSegments array of segments in which the thread is alive + * @param results structure to which all thread issues will be added to. + */ + private void analyseThreadEvent(THREAD_EVENTS event, String thName, ArrayList heapData, ParsedData logData, ThreadSegments [] thSegments, ArrayList results) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + CycleData[] cyclesData = logData.getLogData(); + + for(int i=0; i 1){ + int id = i+1; + thread_instance += "(0" + id + ")"; + + int index; + + for(index=0; index < startIndex; index++){ + event_values[index] = 0; + } + + for(int tmp =0; tmp < heap_size_values.length; tmp++) + { + event_values[index] = heap_size_values[tmp]; + index++; + } + + for(;index < cyclesData.length ;index++) + event_values[index] = 0; + } + else + { + for(int index=0; index < heapData.size(); index++) + event_values[index] = getEventValue(heapData.get(index), event); + } + String formatted_delta = Long.toString(delta); + AnalyserConstants.DeltaType delta_type = AnalyserConstants.DeltaType.COUNT; + switch(event) + { + case HEAP_SIZE: + case HEAP_ALLOC_SPACE: + formatted_delta = getFormattedBytes(delta); + delta_type = AnalyserConstants.DeltaType.SIZE; + } + + ResultElements res_elem = new ResultElements(thread_instance, event.getDescription(), formatted_delta, delta, delta_type); + res_elem.setEventValues(event_values); + + calculateGrowinessAndPriority(heap_size_values, time_intervals, res_elem); + if(res_elem.getPriority() != AnalyserConstants.Priority.NEGLIGIBLE) + { + results.add(res_elem); + } + } + + } + + /** + * + * @param thData structure represents entire data of a thread in one log(cycle). + * @param event a specific thread event + * @return value of the given event. + */ + private long getEventValue(ThreadData thData, THREAD_EVENTS event) + { + long event_value = 0; + + if(thData.getStatus() == CycleData.Deleted) + return 0; + + switch(event) + { + case HEAP_SIZE: + event_value = thData.getHeapChunkSize(); + break; + case NO_OF_FILES: + event_value = thData.getOpenFiles(); + break; + case HEAP_ALLOC_SPACE: + event_value = thData.getHeapAllocatedSpace(); + break; + case HEAP_ALLOC_CELLS: + event_value = thData.getAllocatedCells(); + break; + case NO_OF_PSHANDLES: + event_value = thData.getPsHandles(); + break; + } + + return event_value; + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ChunksData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ChunksData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Stores chunk related data. + * + */ +public class ChunksData { + private String processName; + private String chunkName; + private String handle; + private String baseAddr; + private long size = -1; + private int attrib; + private boolean isKernelHandleDeleted; + + public ChunksData() {} + + public ChunksData(ChunksData target) + { + this.chunkName = target.chunkName; + this.processName = target.processName; + this.baseAddr = target.baseAddr; + this.size = target.size; + this.attrib = target.attrib; + } + + public int getAttrib() { + return attrib; + } + public void setAttrib(int attrib) { + this.attrib = attrib; + } + public String getBaseAddr() { + return baseAddr; + } + public void setBaseAddr(String baseAddr) { + this.baseAddr = baseAddr; + } + public String getChunkName() { + return chunkName; + } + public void setChunkName(String chunkName) { + this.chunkName = chunkName; + } + public String getHandle() { + return handle; + } + public void setHandle(String handle) { + this.handle = handle; + } + public String getProcessName() { + return processName; + } + public void setProcessName(String processName) { + this.processName = processName; + } + public long getSize() { + return size; + } + public void setSize(long size) { + this.size = size; + } + + public boolean isKernelHandleDeleted() { + return isKernelHandleDeleted; + } + + public void setKernelHandleDeleted(boolean isKernelHandleDeleted) { + this.isKernelHandleDeleted = isKernelHandleDeleted; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/CycleData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/CycleData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,953 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +public class CycleData implements Comparable{ + + private String fileName; + private int cycleNumber; + private String time; + private String romCheckSum; + private String romVersion; + private long changeCount; + private long freeMemory = -1; + private long totalMemory = -1; + private long prevFreeMem; + private long memspyRam; + + public static final int Deleted = 0; + public static final int New = 1; + public static final int Alive =2; + + private ArrayList psHandlesList; + private ArrayList kernelHandlesList; + private ArrayList disksList; + private ArrayList filesList; + private ArrayList globalDataChunksList; + private ArrayList stacksList; + private ArrayList nonRHeapList; + private ArrayList heapsList; + private ArrayList chunksList; + private ArrayList wndgList; + + private ArrayList newlyCreatedDisks; + private ArrayList updatedDisks; + private ArrayList deletedDisks; + + private ArrayList newlyCreatedThreads; + private ArrayList updatedThreads; + private ArrayList deletedThreads; + + private ArrayList newlyCreatedHeaps; + private ArrayList updatedHeaps; + private ArrayList deletedHeaps; + + + /** + * @param diskData will be added to the list of disks, maintained internally + */ + public void addDiskData(DiskData diskData) + { + if(disksList == null) + disksList = new ArrayList(); + + disksList.add(diskData); + } + + /** + * @param kernelData will be added to the list of kernelhandles, maintained internally + */ + public void addKernelData(KernelHandles kernelData) + { + if(kernelHandlesList == null) + kernelHandlesList = new ArrayList(); + + kernelHandlesList.add(kernelData); + } + + /** + * @param fileData will be added to the list of files, maintained internally + */ + public void addFileData(FilesData fileData) + { + if(filesList == null) + filesList = new ArrayList(); + + filesList.add(fileData); + } + + /** + * @param HPAS Handles Data will be added to the list of ps handles data, maintained internally + */ + public void addHPASHandlesData(PSHandlesData psHandlesData) + { + if(psHandlesList == null) + psHandlesList = new ArrayList(); + + psHandlesList.add(psHandlesData); + } + + /** + * @param heapData will be added to the list of heaps, maintained internally + */ + public void addHeapData(HeapData heapData) + { + if(heapsList == null) + heapsList = new ArrayList(); + + heapsList.add(heapData); + } + + /** + * @param stackData will be added to the list of stacks, maintained internally + */ + public void addStackData(StackData stackData) + { + if(stacksList == null) + stacksList = new ArrayList(); + + stacksList.add(stackData); + } + + /** + * @param Chunks Data will be added to the list of chunks data, maintained internally + */ + public void addChunksData(ChunksData chunksData) + { + if( chunksList == null) + chunksList = new ArrayList(); + + chunksList.add(chunksData); + } + + /** + * @param Chunks Data will be added to the list of chunks data, maintained internally. + */ + public void addGlobalChunksData(GlobalDataChunks globalChunksData) + { + if( globalDataChunksList == null) + globalDataChunksList = new ArrayList(); + + globalDataChunksList.add(globalChunksData); + } + + /** + * + * @param Window Groups Data will be added to the list of window groups, maintained internally. + */ + public void addWindowGroupsData(WindowGroups wndgData) + { + if(wndgList == null) + wndgList = new ArrayList(); + + wndgList.add(wndgData); + } + + /** + * @returns an arraylist of disknames present in this cycle. + */ + public ArrayList getDiskNames() + { + ArrayList diskNames = new ArrayList(); + + if(disksList != null) + for(DiskData d:disksList) + diskNames.add(d.getName()); + + return diskNames; + } + + /** + * This method parses the cycle data and stores the disk names to + * corresponding lists based on their status. + * + */ + public void parseDisksList() + { + newlyCreatedDisks = new ArrayList(); + updatedDisks = new ArrayList(); + deletedDisks = new ArrayList(); + + if(disksList != null){ + for(DiskData d:disksList){ + if(d.getStatus() == CycleData.New) + newlyCreatedDisks.add(d.getName()); + else if(d.getStatus() == CycleData.Alive) + updatedDisks.add(d.getName()); + else if(d.getStatus() == CycleData.Deleted) + deletedDisks.add(d.getName()); + } + } + + } + + /** + * This method parses the handles list of a cycle data and if the handle type + * if thread, it stores thread names of those handles to corresponding lists + * based on their status + * + */ + public void parseAllThreads() + { + newlyCreatedThreads = new ArrayList(); + updatedThreads = new ArrayList(); + deletedThreads = new ArrayList(); + + if(kernelHandlesList != null){ + for(KernelHandles handle:kernelHandlesList){ + if(handle.getHandleType().equals("Thread")) + { + if(handle.getStatus() == CycleData.New) + newlyCreatedThreads.add(handle.getHandleName()); + else if(handle.getStatus() == CycleData.Alive) + updatedThreads.add(handle.getHandleName()); + else if(handle.getStatus() == CycleData.Deleted) + deletedThreads.add(handle.getHandleName()); + } + } + } + + } + + /** + * + * @param threadName name of the thread whose stack data is needed + * @return class which stores stack information + */ + public StackData getStackData(String threadName) + { + if(stacksList != null) + { + for(StackData st:stacksList) + { + if(st.getThreadName().equalsIgnoreCase(threadName)) + return st; + } + } + + return null; + } + + public int getNewOpenFiles(String threadName) + { + int openFilesCnt = 0; + + if(filesList != null) + { + for(FilesData file:filesList) + { + if(file.getThreadName().equalsIgnoreCase(threadName) + && file.getStatus() == CycleData.New) + openFilesCnt++; + } + + } + + return openFilesCnt; + } + + public int getDeletedFiles(String threadName) + { + int closedFilesCnt = 0; + + if(filesList != null) + { + for(FilesData file:filesList) + { + if(file.getThreadName().equalsIgnoreCase(threadName) + && file.getStatus() == CycleData.Deleted) + closedFilesCnt++; + } + } + + return closedFilesCnt; + } + + public int getUpdatedFiles(String threadName) + { + int openFilesCnt = 0; + + if(filesList != null) + { + for(FilesData file:filesList) + { + if(file.getThreadName().equalsIgnoreCase(threadName) + && file.getStatus() == CycleData.Alive) + openFilesCnt++; + } + //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Openfiles for " + threadName + " are " + openFilesCnt); + } + + return openFilesCnt; + } + + public int getNewPSHandles(String threadName) + { + int psHandlesCnt = 0; + + if(psHandlesList != null) + { + for(PSHandlesData psHandle:psHandlesList) + { + if(psHandle.getThreadName().equalsIgnoreCase(threadName) + && (psHandle.getStatus() == CycleData.New)) + psHandlesCnt++; + } + } + + return psHandlesCnt; + } + + public int getDeletedPSHandles(String threadName) + { + int deletedHandlesCnt = 0; + + if(psHandlesList != null) + { + for(PSHandlesData psHandle:psHandlesList) + { + if(psHandle.getThreadName().equalsIgnoreCase(threadName) + && psHandle.getStatus() == CycleData.Deleted) + deletedHandlesCnt++; + } + } + + return deletedHandlesCnt; + } + + public int getUpdatedPSHandles(String threadName) + { + int alivePSHandles = 0; + + if(psHandlesList != null) + { + for(PSHandlesData psHandle:psHandlesList) + { + if(psHandle.getThreadName().equalsIgnoreCase(threadName) + && psHandle.getStatus() == CycleData.Alive) + alivePSHandles++; + } + //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Openfiles for " + threadName + " are " + openFilesCnt); + + } + + return alivePSHandles; + } + + public ArrayList getNewlyCreatedDisks() + { + return newlyCreatedDisks; + } + + public ArrayList getUpdatedDisks() + { + return updatedDisks; + } + + public ArrayList getDeletedDisks() + { + return deletedDisks; + } + + public ArrayList getNewlyCreatedThreads() + { + return newlyCreatedThreads; + } + + public ArrayList getUpdatedThreads() + { + return updatedThreads; + } + + public ArrayList getDeletedThreads() + { + return deletedThreads; + } + + /** + * Reads the values for given disk in this cycledata. + * @param diskName name of the disk whose info must be fetched. + * @return a structure which can store used memory and size values. + */ + public DiskOverview getDiskUsedAndFreeSize(String diskName) + { + if(disksList != null) + { + DiskOverview overview = new DiskOverview(); + + int index = -1; + for(DiskData disk:disksList) + { + index++; + if(disk.getName().equalsIgnoreCase(diskName)) + { + DiskData diskData = disksList.get(index); + overview.setSize(diskData.getSize()); + overview.setFreeSize(diskData.getFreeSize()); + overview.setStatus(diskData.getStatus()); + + return overview; + } + } + } + return null; + } + + /** + * + * @param threadName name of the thread whose heap data is needed. + * @return class which stores heap information of given thread in this cycle. + */ + public ThreadData getHeapData(String threadName) + { + + if(heapsList != null) + { + ThreadData data = new ThreadData(threadName); + for(HeapData heap:heapsList) + { + if(heap.getThreadName().equalsIgnoreCase(threadName)) + { + data.setHeapChunkSize(heap.getSize()); + data.setMaxHeapSize(heap.getMaxSize()); + data.setAllocatedCells(heap.getAllocatedCells()); + data.setFreeCells(heap.getFreeCells()); + data.setHeapAllocatedSpace(heap.getAllocSpace()); + data.setHeapFreeSpace(heap.getFreeSpace()); + data.setLargestAllocCellSize(heap.getLargestAllocCell()); + data.setLargestFreeCellSize(heap.getLargestFreeCell()); + data.setFreeSlackSize(heap.getFreeSlack()); + data.setStatus(heap.getStatus()); + + return data; + } + } + } + + return null; + } + + public int getKernelHandles() + { + if(kernelHandlesList != null) + return kernelHandlesList.size(); + else + return 0; + } + + /** + * This method parses all heap structures for this cycle and + * stores the thread names of those heaps to corresponding lists + * based on their status + * + */ + public void parseAllHeaps() + { + newlyCreatedHeaps = new ArrayList(); + updatedHeaps = new ArrayList(); + deletedHeaps = new ArrayList(); + + if(heapsList != null){ + for(HeapData heap:heapsList){ + if(heap.getStatus() == CycleData.New) + newlyCreatedHeaps.add(heap.getThreadName()); + else if(heap.getStatus() == CycleData.Alive) + updatedHeaps.add(heap.getThreadName()); + else if(heap.getStatus() == CycleData.Deleted) + deletedHeaps.add(heap.getThreadName()); + } + } + + } + + /** + * @return list of thread names whose heap is created in this cycle. + */ + public ArrayList getNewHeapThreads() + { + return newlyCreatedHeaps; + } + + /** + * @return list of thread names whose heap information is + * updated in this cycle. + */ + public ArrayList getAliveHeapThreads() + { + return updatedHeaps; + } + + /** + * @return list of thread names whose heap is deleted in this cycle. + * + */ + public ArrayList getDeletedHeapThreads() + { + return deletedHeaps; + } + + /** + * This method parses all stack structures for this cycle and + * returns the list of thread names for all newly created stacks. + * + */ + public ArrayList getNewStackThreads() + { + ArrayList threadNames = new ArrayList(); + + if(stacksList != null) + for(StackData stack:stacksList) + { + if(stack.getStatus() == CycleData.New) + threadNames.add(stack.getThreadName()); + } + return threadNames; + } + + /** + * This method parses all stack structures for this cycle and + * returns the list of thread names for updated stacks. + * + */ + public ArrayList getAliveStackThreads() + { + ArrayList threadNames = new ArrayList(); + + if(stacksList != null) + for(StackData stack:stacksList) + { + if(stack.getStatus() == CycleData.Alive) + threadNames.add(stack.getThreadName()); + } + return threadNames; + } + + /** + * This method parses all stack structures for this cycle and + * returns the list of thread names for all deleted stacks. + * + */ + public ArrayList getDeletedStackThreads() + { + ArrayList threadNames = new ArrayList(); + + if(stacksList != null) + for(StackData stack:stacksList) + { + if(stack.getStatus() == CycleData.Deleted){ + threadNames.add(stack.getThreadName()); + } + } + return threadNames; + } + + /** + * + * @return list of thread names which contain PSHandles + */ + public ArrayList getHPASThreads() + { + ArrayList threadNames = new ArrayList(); + + if(psHandlesList != null) + for(PSHandlesData hpas:psHandlesList) + threadNames.add(hpas.getThreadName()); + + return threadNames; + } + + /** + * + * @return list of thread names which contain file handles. + */ + public ArrayList getFileThreads() + { + ArrayList threadNames = new ArrayList(); + + if(filesList != null) + for(FilesData file:filesList) + threadNames.add(file.getThreadName()); + + return threadNames; + } + + public ArrayList getDeletedChunkNames () + { + ArrayList deletedChunks = new ArrayList(); + + if(kernelHandlesList != null){ + for(KernelHandles handle:kernelHandlesList){ + + if(handle.getHandleType().equals("Chunk") && + (handle.getStatus() == CycleData.Deleted)) + { + deletedChunks.add(handle.getHandleName()); + } + } + } + + return deletedChunks; + } + + + + public long getChangeCount() { + return changeCount; + } + public void setChangeCount(long changeCount) { + this.changeCount = changeCount; + } + public int getCycleNumber() { + return cycleNumber; + } + public void setCycleNumber(int cycleNumber) { + this.cycleNumber = cycleNumber; + } + public String getFileName() { + return fileName; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public long getMemspyRam() { + return memspyRam; + } + public void setMemspyRam(long memspyRam) { + this.memspyRam = memspyRam; + } + public long getPrevFreeMem() { + return prevFreeMem; + } + public void setPrevFreeMem(long prevFreeMem) { + this.prevFreeMem = prevFreeMem; + } + public String getTime() { + return time; + } + public void setTime(String time) { + this.time = time; + } + + /** + * Clears all the previous data + * + */ + public void clear() + { + if(disksList != null) + disksList.clear(); + if(heapsList != null) + heapsList.clear(); + if(stacksList != null) + stacksList.clear(); + if(globalDataChunksList != null) + globalDataChunksList.clear(); + if(nonRHeapList != null) + nonRHeapList.clear(); + if(chunksList != null) + chunksList.clear(); + if(kernelHandlesList != null) + kernelHandlesList.clear(); + if(filesList != null) + filesList.clear(); + if(psHandlesList != null) + psHandlesList.clear(); + } + + public ArrayList getGlobalDataChunksList() { + ArrayList s = new ArrayList(); + if(globalDataChunksList!=null) + for (GlobalDataChunks data: globalDataChunksList) + s.add(data); + return s; + } + + public GlobalDataChunks getGlobalChunkDataFor(String chunkName) + { + if(globalDataChunksList != null) + { + for(GlobalDataChunks data : globalDataChunksList) + { + if(data.getChunkName().equalsIgnoreCase(chunkName)) + { + return data; + } + } + } + return null; + } + + public ChunksData getChunkDataFor(String chunkName) + { + if(chunksList != null) + { + for(ChunksData data : chunksList) + { + if(data.getChunkName().equalsIgnoreCase(chunkName)) + { + return data; + } + } + } + return null; + } + + public ArrayList getGlobalChunkNames() + { + ArrayList chunkNames = new ArrayList(); + + if(globalDataChunksList != null) + for(GlobalDataChunks glod:globalDataChunksList) + chunkNames.add(glod.getChunkName()); + + return chunkNames; + } + + + + public ArrayList getNonHeapChunkNames() + { + ArrayList chunkNames = new ArrayList(); + + if(chunksList != null) + for(ChunksData chnk:chunksList) + chunkNames.add(chnk.getChunkName()); + + return chunkNames; + } + + public ArrayList getPsHandlesList() { + ArrayList s = new ArrayList(); + for (PSHandlesData data: psHandlesList) + s.add(data); + + return s; + } + + public ArrayList getGenHandlesList() { + ArrayList s = new ArrayList(); + for (KernelHandles data: kernelHandlesList) + s.add(data); + + return s; + + } + + public ArrayList getDisksList() { + ArrayList s = new ArrayList(); + for (DiskData data: disksList) + s.add(data); + return s; + } + + public ArrayList getHeapsList() { + ArrayList s = new ArrayList(); + for (HeapData data: heapsList) + s.add(data); + return s; + } + + public ArrayList getChunksList() { + ArrayList s = new ArrayList(); + if(chunksList!=null) + for (ChunksData data: chunksList) + s.add(data); + return s; + } + + /** + * + * @returns list of window groups from this cycle. + */ + public ArrayList getWindowGroupsData() + { + ArrayList list = new ArrayList(); + + if(wndgList != null) + { + for(WindowGroups wndg:wndgList) + { + list.add(wndg); + } + } + + return list; + } + public long getFreeMemory() { + return freeMemory; + } + + public void setFreeMemory(long freeMemory) { + this.freeMemory = freeMemory; + } + + public long getTotalMemory() { + return totalMemory; + } + + public void setTotalMemory(long totalMemory) { + this.totalMemory = totalMemory; + } + + public String getRomCheckSum() { + return romCheckSum; + } + + public void setRomCheckSum(String romCheckSum) { + this.romCheckSum = romCheckSum; + } + + public String getRomVersion() { + return romVersion; + } + + public void setRomVersion(String romVersion) { + this.romVersion = romVersion; + } + + /** + * + * This method returns the data related to various kernel elements. + */ + public KernelElements getAllOpenKernelElements() + { + KernelElements elements = new KernelElements(); + + if(kernelHandlesList != null){ + for(KernelHandles handle:kernelHandlesList) + { + if(handle.getHandleType().equals("Timer")) + { + int count = elements.getNumberOfTimers(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfTimers(count); + } + else if(handle.getHandleType().equals("Semaphore")) + { + int count = elements.getNumberOfSemaphores(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfSemaphores(count); + } + else if(handle.getHandleType().equals("Process")) + { + int count = elements.getNumberOfProcesses(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfProcesses(count); + } + else if(handle.getHandleType().equals("Thread")) + { + int count = elements.getNumberOfThreads(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfThreads(count); + } + else if(handle.getHandleType().equals("Chunk")) + { + int count = elements.getNumberOfChunks(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfChunks(count); + } + else if(handle.getHandleType().equals("Session")) + { + int count = elements.getNumberOfSessions(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfSessions(count); + } + else if(handle.getHandleType().equals("Server")) + { + int count = elements.getNumberOfServers(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfServers(count); + } + else if(handle.getHandleType().equals("Msg. Queue")) + { + int count = elements.getNumberOfMsgQueues(); + + if(handle.getStatus() == CycleData.New) + count++; + else if(handle.getStatus() == CycleData.Deleted) + count--; + + elements.setNumberOfMsgQueues(count); + } + } + } + return elements; + } + + public int compareTo(CycleData tmp) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); + Date aDate=null; + Date bDate=null; + try { + aDate = sdf.parse(this.getTime()); + bDate = sdf.parse(tmp.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + } + + if(aDate.before(bDate)) + { + return -1; + } + else if(aDate.after(bDate)) + { + return 1; + } + return 0; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +public class DiskData { + private String driveName; + private long size; + private long freeSize; + private int status; + + public void setName(String name) + { + this.driveName = name; + } + public void setSize(String size) + { + this.size = Long.parseLong(size); + } + + public void setFreeSize(String freeSize) + { + this.freeSize = Long.parseLong(freeSize); + } + + public String getName() + { + return driveName; + } + + /** + * @param status + * This method sets the status of this handle to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + this.status = CycleData.New; + else if (status.equals("[A]")) + this.status = CycleData.Alive; + else + this.status = CycleData.Deleted; + } + public int getStatus() + { + return status; + } + + public long getFreeSize() + { + return this.freeSize; + } + + public long getSize() + { + return this.size; + + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskOverview.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskOverview.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.s60tools.swmtanalyser.data; + +public class DiskOverview { + + private long freeSize; + private long size; + private int status; + + public DiskOverview(DiskOverview target) + { + this.freeSize = target.freeSize; + this.size = target.size; + this.status = target.status; + } + + public DiskOverview() + { + this.freeSize = -1; + this.size = -1; + } + + public long getFreeSize() + { + return freeSize; + } + + public long getSize() + { + return size; + } + + public long getUsedSize() + { + if(freeSize == -1 || size == -1) + return -1; + else + return size - freeSize; + } + + public void setFreeSize(long freeSize) + { + this.freeSize = freeSize; + } + + public void setSize(long size) + { + this.size = size; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/FilesData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/FilesData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +public class FilesData { + private String fileName; + private String threadName; + private long fileSize; + private int status; + + public void setFileName(String fileName){ + this.fileName = fileName; + } + + public void setFileSize(String fileSize){ + this.fileSize = Long.parseLong(fileSize); + } + + public void setThreadName(String threadName){ + this.threadName = threadName; + } + + /** + * @param status + * This method sets the status of this file to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + this.status = CycleData.New; + else if (status.equals("[A]")) + this.status = CycleData.Alive; + else + this.status = CycleData.Deleted; + } + + public int getStatus() + { + return status; + } + + public String getThreadName(){ + return threadName; + } + + public String getFileName() { + return fileName; + } + + public long getFileSize() { + return fileSize; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/GlobalDataChunks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/GlobalDataChunks.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; +/** + * Stores GLOD data from the log files. + */ +public class GlobalDataChunks { + private String processName; + private String chunkName; + private String baseAddr; + private long size = -1; + private int attrib; + private boolean isKernelHandleDeleted; + + public GlobalDataChunks(){} + + public GlobalDataChunks(GlobalDataChunks target) + { + this.chunkName = target.chunkName; + this.processName = target.processName; + this.baseAddr = target.baseAddr; + this.size = target.size; + this.attrib = target.attrib; + } + public int getAttrib() { + return attrib; + } + public void setAttrib(int attrib) { + this.attrib = attrib; + } + public String getBaseAddr() { + return baseAddr; + } + public void setBaseAddr(String baseAddr) { + this.baseAddr = baseAddr; + } + public String getChunkName() { + return chunkName; + } + public void setChunkName(String chunkName) { + this.chunkName = chunkName; + } + public String getProcessName() { + return processName; + } + public void setProcessName(String processName) { + this.processName = processName; + } + public long getSize() { + return size; + } + public void setSize(long size) { + this.size = size; + } + + public boolean isKernelHandleDeleted() { + return isKernelHandleDeleted; + } + + public void setKernelHandleDeleted(boolean isKernelHandleDeleted) { + this.isKernelHandleDeleted = isKernelHandleDeleted; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/HeapData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/HeapData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,187 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; +/** + * Stores the HEAP data from the log files. + * + */ +public class HeapData { + private String threadName; + private String processName; + private String baseAddr; + private long size; + private long maxSize; + private long allocatedCells; + private long freeCells; + private long allocSpace; + private long freeSpace; + private long freeSlack; + private long largestFreeCell; + private long largestAllocCell; + private int attrib; + + public void setThreadAndProcessName(String threadName) + { + int index = threadName.indexOf("::"); + this.processName = threadName.substring(0, index-1); + this.threadName = threadName; + } + + public long getAllocatedCells() { + return allocatedCells; + } + + public void setAllocatedCells(String allocatedCells) { + this.allocatedCells = Long.parseLong(allocatedCells); + } + + public long getAllocSpace() { + return allocSpace; + } + + public void setAllocSpace(String allocSpace) { + this.allocSpace = Long.parseLong(allocSpace); + } + + public String getBaseAddr() { + return baseAddr; + } + + public void setBaseAddr(String baseAddr) { + this.baseAddr = baseAddr; + } + + public long getFreeCells() { + return freeCells; + } + + public void setFreeCells(String freeCells) { + this.freeCells = Long.parseLong(freeCells); + } + + public long getFreeSlack() { + return freeSlack; + } + + public void setFreeSlack(String freeSlack) { + this.freeSlack = Long.parseLong(freeSlack); + } + + public long getFreeSpace() { + return freeSpace; + } + + public void setFreeSpace(String freeSpace) { + this.freeSpace = Long.parseLong(freeSpace); + } + + public long getLargestAllocCell() { + return largestAllocCell; + } + + public void setLargestAllocCell(String largestAllocCell) { + this.largestAllocCell = Long.parseLong(largestAllocCell); + } + + public long getLargestFreeCell() { + return largestFreeCell; + } + + public void setLargestFreeCell(String largestFreeCell) { + this.largestFreeCell = Long.parseLong(largestFreeCell); + } + + public String getProcessName() { + return processName; + } + + /*public void setProcessName(String processName) { + this.processName = processName; + }*/ + + public long getSize() { + return size; + } + + public void setSize(String size) { + this.size = Long.parseLong(size); + } + + public long getMaxSize() { + return maxSize; + } + + public void setMaxSize(String maxSize) { + this.maxSize = Long.parseLong(maxSize); + } + public String getThreadName() { + return threadName; + } + /** + * @param status + * This method sets the status of this heap to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + attrib = CycleData.New; + else if (status.equals("[A]")) + attrib = CycleData.Alive; + else + attrib = CycleData.Deleted; + } + public int getStatus() + { + return attrib; + } + + public void setAllocatedCells(long allocatedCells) { + this.allocatedCells = allocatedCells; + } + + public void setAllocSpace(long allocSpace) { + this.allocSpace = allocSpace; + } + public int getAttrib() { + return attrib; + } + public void setAttrib(int attrib) { + this.attrib = attrib; + } + + public void setFreeCells(long freeCells) { + this.freeCells = freeCells; + } + + public void setFreeSlack(long freeSlack) { + this.freeSlack = freeSlack; + } + public void setFreeSpace(long freeSpace) { + this.freeSpace = freeSpace; + } + public void setLargestAllocCell(long largestAllocCell) { + this.largestAllocCell = largestAllocCell; + } + public void setLargestFreeCell(long largestFreeCell) { + this.largestFreeCell = largestFreeCell; + } + + public void setSize(long size) { + this.size = size; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelElements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelElements.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +/** + * This class contains the information about various kernel elements. + */ +package com.nokia.s60tools.swmtanalyser.data; +/** + * Stores kernel handles information + * + */ +public class KernelElements { + + private int numberOfThreads = 0; + private int numberOfProcesses = 0; + private int numberOfTimers = 0; + private int numberOfSessions = 0; + private int numberOfSemaphores = 0; + private int numberOfServers = 0; + private int numberOfChunks = 0; + private int numberOfMsgQueues = 0; + + public int getNumberOfProcesses() { + return numberOfProcesses; + } + public void setNumberOfProcesses(int numberOfProcesses) { + this.numberOfProcesses = numberOfProcesses; + } + public int getNumberOfSemaphores() { + return numberOfSemaphores; + } + public void setNumberOfSemaphores(int numberOfSemaphores) { + this.numberOfSemaphores = numberOfSemaphores; + } + public int getNumberOfServers() { + return numberOfServers; + } + public void setNumberOfServers(int numberOfServers) { + this.numberOfServers = numberOfServers; + } + public int getNumberOfSessions() { + return numberOfSessions; + } + public void setNumberOfSessions(int numberOfSessions) { + this.numberOfSessions = numberOfSessions; + } + public int getNumberOfThreads() { + return numberOfThreads; + } + public void setNumberOfThreads(int numberOfThreads) { + this.numberOfThreads = numberOfThreads; + } + public int getNumberOfTimers() { + return numberOfTimers; + } + public void setNumberOfTimers(int numberOfTimers) { + this.numberOfTimers = numberOfTimers; + } + public int getNumberOfChunks() { + return numberOfChunks; + } + public void setNumberOfChunks(int numberOfChunks) { + this.numberOfChunks = numberOfChunks; + } + public int getNumberOfMsgQueues() { + return numberOfMsgQueues; + } + public void setNumberOfMsgQueues(int numberOfMsgQueues) { + this.numberOfMsgQueues = numberOfMsgQueues; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelHandles.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Stores HGEN information + * + */ +public class KernelHandles { + + private String handleName; + private String handle; + private String handleType; + private int attrib; + + public void setHandleName(String name) { + this.handleName = name; + } + public void setHandle(String handle){ + this.handle = handle; + } + public void setHandleType(String handleType){ + this.handleType = handleType; + } + + /** + * @param status + * This method sets the status of this handle to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + attrib = CycleData.New; + else if (status.equals("[A]")) + attrib = CycleData.Alive; + else + attrib = CycleData.Deleted; + } + + public int getStatus(){ + return attrib; + } + + public String getHandleType(){ + return handleType; + } + + public String getHandleName(){ + return handleName; + } + public String getHandle() { + return handle; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/OverviewData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/OverviewData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Stores overview information from all the log files. + * + */ +public class OverviewData { + + public int noOfcycles; + public String fromTime; + public String toTime; + public long duration; + public String durationString; +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/PSHandlesData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/PSHandlesData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Stores HPAS data from the log file. + * + */ +public class PSHandlesData { + + public static String [] keyTypes = new String [] {"EInt", "EByteArray", "EText", "ELargeByteArray","ELargeText", "ETypeLimit", "ETypeMask"}; + + private String handleName; + private String handle; + private long key; + private int keyType; + private long threadId; + private String threadName; + private int attrib; + + public int getStatus() + { + return attrib; + } + public String getHandle() { + return handle; + } + public void setHandle(String handle) { + this.handle = handle; + } + public String getHandleName() { + return handleName; + } + public void setHandleName(String handleName) { + this.handleName = handleName; + } + public long getKey() { + return key; + } + public void setKey(long key) { + this.key = key; + } + public int getKeyType() { + return keyType; + } + public void setKeyType(int keyType) { + this.keyType = keyType; + } + public long getThreadId() { + return threadId; + } + public void setThreadId(long threadId) { + this.threadId = threadId; + } + public String getThreadName() { + return threadName; + } + public void setThreadName(String threadName) { + this.threadName = threadName; + } + + /** + * @param status + * This method sets the status of this handle to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + attrib = CycleData.New; + else if (status.equals("[A]")) + attrib = CycleData.Alive; + else + attrib = CycleData.Deleted; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ParsedData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ParsedData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +import java.util.ArrayList; +/** + * Stores the cycle data objects of all log files. + * + */ +public class ParsedData { + + private ArrayList logData; + + public void setParsedData(ArrayList logData){ + this.logData = logData; + } + + public CycleData[] getLogData(){ + if(this.logData != null) + return logData.toArray(new CycleData[0]); + else + return null; + } + + public int getNumberOfCycles(){ + if(logData == null) + return 0; + else + return logData.size(); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/StackData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/StackData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; +/** + * Stores STAK data. + * + */ +public class StackData { + private String threadName; + private String chunkName; + private long size; + private int status; + + + public String getChunkName() { + return chunkName; + } + public void setChunkName(String chunkName) { + this.chunkName = chunkName; + } + public long getSize() { + return size; + } + public void setSize(String size) { + this.size = Long.parseLong(size); + } + public String getThreadName() { + return threadName; + } + public void setThreadName(String threadName) { + this.threadName = threadName; + } + public int getStatus() { + return status; + } + + /** + * @param status + * This method sets the status of this stack to New, Alive or Deleted + */ + public void setStatus(String status) + { + if(status.equals("[N]+[A]")) + this.status = CycleData.New; + else if (status.equals("[A]")) + this.status = CycleData.Alive; + else + this.status = CycleData.Deleted; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/SystemData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/SystemData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * This class is used to store RAM information of a cycle + */ +public class SystemData { + //Free memory + private long freeMemory; + //Total memory + private long totalMemory; + + public long getFreeMemory() { + return freeMemory; + } + public void setFreeMemory(long freeMemory) { + this.freeMemory = freeMemory; + } + public long getTotalMemory() { + return totalMemory; + } + public void setTotalMemory(long usedMemory) { + this.totalMemory = usedMemory; + } + + public SystemData() + { + this.freeMemory = -1; + this.totalMemory = -1; + } + + public SystemData(SystemData target) + { + this.freeMemory = target.freeMemory; + this.totalMemory = target.totalMemory; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * This class is used to store thread information at one cycle + */ +public class ThreadData { + private String name; //name of the thread + private int cycleNo; //number of the swmt cycle + private long heapChunkSize = -1; //size of the heap chunk + private long maxHeapSize = -1; //maximum size of the heap + private long heapAllocatedSpace = -1; //allocated heap space + private long heapFreeSpace = -1; //free heap space + private long freeSlackSize = -1; //free slack space + private long allocatedCells = -1; //number of allocated cells in the heap + private long freeCells = -1; //number of free cells in the heap. + private long largestAllocCellSize = -1; //size of the largest allocated cell + private long largestFreeCellSize = -1; //size of the largest free cell + private long openFiles = 0; //number of open files + private long stackSize = -1; //size of stack + private long psHandles = 0; //number of p&s handles + private boolean isKernelHandleDeleted; + private int heapStatus; + private int stackStatus; + + /** + * Default constructor + * @param name name of the thread. + */ + public ThreadData(String name){ + this.name = name; + } + + /** + * Copy constructor + * @param target thread data to copy initial values from + */ + public ThreadData(ThreadData target) + { + this.name = target.name; + this.heapChunkSize = target.heapChunkSize; + this.maxHeapSize = target.maxHeapSize; + this.heapAllocatedSpace = target.heapAllocatedSpace; + this.heapFreeSpace = target.heapFreeSpace; + this.freeSlackSize = target.freeSlackSize; + this.allocatedCells = target.allocatedCells; + this.freeCells = target.freeCells; + this.largestAllocCellSize = target.largestAllocCellSize; + this.largestFreeCellSize = target.largestFreeCellSize; + this.openFiles = target.openFiles; + this.stackSize = target.stackSize; + this.psHandles = target.psHandles; + this.stackStatus = target.stackStatus; + this.heapStatus = target.heapStatus; + } + + public long getAllocatedCells() { + return allocatedCells; + } + public void setAllocatedCells(long allocatedCells) { + this.allocatedCells = allocatedCells; + } + public long getFreeCells() { + return freeCells; + } + public void setFreeCells(long freeCells) { + this.freeCells = freeCells; + } + public long getFreeSlackSize() { + return freeSlackSize; + } + public void setFreeSlackSize(long freeSlackSize) { + this.freeSlackSize = freeSlackSize; + } + public long getHeapAllocatedSpace() { + return heapAllocatedSpace; + } + public void setHeapAllocatedSpace(long heapAllocatedSpace) { + this.heapAllocatedSpace = heapAllocatedSpace; + } + public long getHeapChunkSize() { + return heapChunkSize; + } + public void setHeapChunkSize(long heapChunkSize) { + this.heapChunkSize = heapChunkSize; + } + public long getHeapFreeSpace() { + return heapFreeSpace; + } + public void setHeapFreeSpace(long heapFreeSpace) { + this.heapFreeSpace = heapFreeSpace; + } + public long getMaxHeapSize() { + return maxHeapSize; + } + public void setMaxHeapSize(long maxHeapSize) { + this.maxHeapSize = maxHeapSize; + } + public String getName() { + return name; + } + + public long getOpenFiles() { + return openFiles; + } + public void setOpenFiles(long openFiles) { + this.openFiles = openFiles; + } + + public long getPsHandles() { + return psHandles; + } + public void setPsHandles(long psHandles) { + this.psHandles = psHandles; + } + public long getStackSize() { + return stackSize; + } + public void setStackSize(long stackSize) { + this.stackSize = stackSize; + } + public long getLargestAllocCellSize() { + return largestAllocCellSize; + } + public void setLargestAllocCellSize(long largestAllocCellSize) { + this.largestAllocCellSize = largestAllocCellSize; + } + public long getLargestFreeCellSize() { + return largestFreeCellSize; + } + public void setLargestFreeCellSize(long largestFreeCellSize) { + this.largestFreeCellSize = largestFreeCellSize; + } + public int getStatus() + { + return heapStatus; + } + public void setStatus(int status) + { + this.heapStatus = status; + } + public int getStackStatus() { + return stackStatus; + } + public void setStackStatus(int stackStatus) { + this.stackStatus = stackStatus; + } + + public int getCycleNumber() { + return cycleNo; + } + + public void setCycleNumber(int cycleNo) { + this.cycleNo = cycleNo; + } + + public boolean isKernelHandleDeleted() { + return isKernelHandleDeleted; + } + + public void setKernelHandleDeleted(boolean isKernelHandleDeleted) { + this.isKernelHandleDeleted = isKernelHandleDeleted; + } + +} + + + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadSegments.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadSegments.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Stores start and end cycle numbers of an instance if the thread has multiple instances. + * + */ +public class ThreadSegments { + + private int startCycle = -1; + private int endCycle = -1; + + public int getStartCycle() { + return startCycle; + } + public void setStartCycle(int startCycle) { + this.startCycle = startCycle; + } + public int getEndCycle() { + return endCycle; + } + public void setEndCycle(int endCycle) { + this.endCycle = endCycle; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroupEventData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroupEventData.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * Data structure to maintain the number of event occurences + * for each window group, in each cycle. + */ +public class WindowGroupEventData { + + private int event_0_count; + private int event_1_count; + private int event_2_count; + private int event_3_count; + + public WindowGroupEventData(WindowGroupEventData target) + { + this.event_0_count = target.event_0_count; + this.event_1_count = target.event_1_count; + this.event_2_count = target.event_2_count; + this.event_3_count = target.event_3_count; + } + public WindowGroupEventData(){} + + public void incrementEventCount(int eventNum) + { + switch(eventNum) + { + case 0: + event_0_count++; + break; + case 1: + event_1_count++; + break; + case 2: + event_2_count++; + break; + case 3: + event_3_count++; + break; + } + } + + public void decrementEventCount(int eventNum) + { + switch(eventNum) + { + case 0: + event_0_count--; + break; + case 1: + event_1_count--; + break; + case 2: + event_2_count--; + break; + case 3: + event_3_count--; + break; + } + } + + public int getEvent_0_count() { + return event_0_count; + } + + public int getEvent_1_count() { + return event_1_count; + } + + public int getEvent_2_count() { + return event_2_count; + } + + public int getEvent_3_count() { + return event_3_count; + } + +} + diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroups.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroups.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.data; + +/** + * + * Data structure to hold the window group events. + * + */ +public class WindowGroups { + + private String name; + private int id; + private int event; + private int status; + public int getEvent() { + return event; + } + public void setEvent(int event) { + this.event = event; + } + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/AdvancedFilterDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/AdvancedFilterDialog.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,653 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants; +import com.nokia.s60tools.swmtanalyser.dialogs.SaveFilterOptions.ValueTypes; + +/** + * UI Dialog class for Advanced Filter Options. + * + */ +public class AdvancedFilterDialog extends Dialog implements SelectionListener{ + + private Button[] severity_buttons; + private Combo delta_dropdown; + private Combo delta_dropdown2; + private Button filter_button; + private Button cancel_button; + private Text start_text; + private Text end_text; + private Text start_text2; + private Text end_text2; + private String[] delta_filter_type = {"Doesn't matter", "Between", "Equals", "Greater than", "Less than"}; + private Combo startwith_dropdown; + private Text item_name_text; + private Button[] ram_and_disk_buttons; + private Button[] thread_event_buttons; + private Button[] system_events_buttons; + private TextVerifyListener verify_listener = new TextVerifyListener(); + private FilterInput input; + private Button reset_button; + + /** + * Construction + * @param parent shell + */ + public AdvancedFilterDialog(Shell parent) { + super(parent); + setShellStyle(getShellStyle()|SWT.RESIZE); + } + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.RESIZE); + composite.setLayout(new GridLayout(1, false)); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + composite.setSize(400, 500); + composite.getShell().setText("Custom filter"); + + Group item_name_grp = new Group(composite, SWT.NONE); + item_name_grp.setText("Item name"); + item_name_grp.setLayout(new GridLayout(3,false)); + item_name_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label item_label = new Label(item_name_grp, SWT.WRAP); + item_label.setText("Item name:"); + + startwith_dropdown = new Combo(item_name_grp, SWT.BORDER|SWT.READ_ONLY); + startwith_dropdown.setItems(new String[]{"Start with", "Contains"}); + startwith_dropdown.select(0); + + item_name_text = new Text(item_name_grp, SWT.BORDER); + item_name_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL|GridData.GRAB_HORIZONTAL)); + + Group event_name_grp = new Group(composite, SWT.NONE); + event_name_grp.setText("Event name"); + event_name_grp.setLayout(new GridLayout(3,true)); + event_name_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label eventLabel = new Label(event_name_grp, SWT.WRAP|SWT.BOLD); + eventLabel.setText("RAM and Disk memory events:"); + GridData eventLabelGD = new GridData(GridData.FILL_HORIZONTAL); + eventLabelGD.horizontalSpan = 4; + eventLabel.setLayoutData(eventLabelGD); + + String[] ram_and_disk_event_names = {"RAM used", "Disk used"}; + ram_and_disk_buttons = new Button[2]; + for(int i=0; i severities = new ArrayList(); + for (int i = 0; i < severity_buttons.length; i++) { + if(i==0 && severity_buttons[i].getSelection()) + break; + else if(severity_buttons[i].getSelection()) + severities.add(AnalyserConstants.Priority.valueOf(severity_buttons[i].getText().toUpperCase())); + } + input.setSeverities(severities.toArray(new AnalyserConstants.Priority[0])); + + input.setDelta_kb_option(delta_dropdown.getSelectionIndex()); + input.setStart_size(Long.parseLong(start_text.getText())); + input.setEnd_size(Long.parseLong(end_text.getText())); + + input.setDelta_count_option(delta_dropdown2.getSelectionIndex()); + input.setStart_count(Long.parseLong(start_text2.getText())); + input.setEnd_count(Long.parseLong(end_text2.getText())); + + if(getShell()!=null) + getShell().dispose(); + setReturnCode(Dialog.OK); + } + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) + */ + @Override + protected void buttonPressed(int buttonId) { + + if(buttonId == IDialogConstants.DESELECT_ALL_ID) + { + startwith_dropdown.select(0); + item_name_text.setText(""); + for (int i = 0; i < ram_and_disk_buttons.length; i++) { + ram_and_disk_buttons[i].setSelection(false); + } + for (int i = 0; i < thread_event_buttons.length; i++) { + thread_event_buttons[i].setSelection(false); + } + for (int i = 0; i < system_events_buttons.length; i++) { + system_events_buttons[i].setSelection(false); + } + severity_buttons[0].setSelection(true); + severity_buttons[0].notifyListeners(SWT.Selection, new Event()); + delta_dropdown.select(0); + delta_dropdown.notifyListeners(SWT.Selection, new Event()); + delta_dropdown2.select(0); + delta_dropdown2.notifyListeners(SWT.Selection, new Event()); + } + super.buttonPressed(buttonId); + } + + /** + * Returns string array of all selected events + * @return events + */ + public String[] getSelectedEvents() + { + ArrayList events = new ArrayList(); + for (int i = 0; i < ram_and_disk_buttons.length; i++) { + if(ram_and_disk_buttons[i].getSelection()) + events.add(ram_and_disk_buttons[i].getText()); + } + for (int i = 0; i < thread_event_buttons.length; i++) { + if(thread_event_buttons[i].getSelection()) + events.add(thread_event_buttons[i].getText()); + } + for (int i = 0; i < system_events_buttons.length; i++) { + if(system_events_buttons[i].getSelection()) + events.add(system_events_buttons[i].getText()); + } + return events.toArray(new String[events.size()]); + } + + /** + * Returns array of selected severities. If the array size is 0, then assume that all severities selected. + * @return severities array + */ + public String[] getSelectedSeverities() + { + ArrayList severities = new ArrayList(); + for (int i = 1; i < severity_buttons.length; i++) { + if(severity_buttons[i].getSelection()) + severities.add(severity_buttons[i].getText()); + } + return severities.toArray(new String[0]); + } + + /** + * Returns start and end values for the delta to search. + * @param drop_down + * @param start + * @param end + * @return + */ + private String[] getToFromValues(Combo drop_down, Text start, Text end) + { + int i = drop_down.getSelectionIndex(); + String[] values = null; + switch (i) { + case 0: + break; + case 1: + values = new String[2]; + values[0] = start.getText(); + values[1] = end.getText(); + break; + case 2: + values = new String[1]; + values[0] = start.getText(); + break; + case 3: + values = new String[1]; + values[0] = start.getText(); + break; + case 4: + values = new String[1]; + values[0] = start.getText(); + break; + default: + break; + } + return values; + } + + /** + * Saves values to dialog settings. + * + */ + private void saveValues() { + SaveFilterOptions save = new SaveFilterOptions(); + save.saveDropdownOption(ValueTypes.FILTER_TYPE, startwith_dropdown.getText()); + save.saveDropdownOption(ValueTypes.ITEM_TEXT, item_name_text.getText()); + String[] events = getSelectedEvents(); + save.saveValues(ValueTypes.EVENTS, events); + String[] severities = getSelectedSeverities(); + save.saveValues(ValueTypes.SEVERITIES, severities); + save.saveDropdownOption(ValueTypes.SIZE_TYPE, delta_dropdown.getText()); + save.saveValues(ValueTypes.SIZES, getToFromValues(delta_dropdown,start_text, end_text)); + save.saveDropdownOption(ValueTypes.COUNT_TYPE, delta_dropdown2.getText()); + save.saveValues(ValueTypes.COUNTS, getToFromValues(delta_dropdown2,start_text2, end_text2)); + } + + /** + * Restore privious values and shows in advanced dialog. + * + */ + private void restorePreviousValues() { + SaveFilterOptions restore = new SaveFilterOptions(); + + String filter_option = restore.getPreviousDropdownOption(ValueTypes.FILTER_TYPE); + if(filter_option!=null) + startwith_dropdown.select(startwith_dropdown.indexOf(filter_option)); + String filter_text = restore.getPreviousDropdownOption(ValueTypes.ITEM_TEXT); + if(filter_text!=null) + item_name_text.setText(filter_text); + String[] events = restore.getValues(ValueTypes.EVENTS); + String[] severities = restore.getValues(ValueTypes.SEVERITIES); + String delta_size_option = restore.getPreviousDropdownOption(ValueTypes.SIZE_TYPE); + String[] sizes = restore.getValues(ValueTypes.SIZES); + String delta_count_option = restore.getPreviousDropdownOption(ValueTypes.COUNT_TYPE); + String[] counts = restore.getValues(ValueTypes.COUNTS); + + List events_list = new ArrayList(); + if(events!=null) + events_list = Arrays.asList(events); + List severity_list = new ArrayList(); + if(severities!=null) + severity_list = Arrays.asList(severities); + + for (int i = 0; i < ram_and_disk_buttons.length; i++) { + if(events_list.contains(ram_and_disk_buttons[i].getText())) + ram_and_disk_buttons[i].setSelection(true); + } + for (int i = 0; i < thread_event_buttons.length; i++) { + if(events_list.contains(thread_event_buttons[i].getText())) + thread_event_buttons[i].setSelection(true); + } + for (int i = 0; i < system_events_buttons.length; i++) { + if(events_list.contains(system_events_buttons[i].getText())) + system_events_buttons[i].setSelection(true); + } + for (int i = 1; i < severity_buttons.length; i++) { + if(severity_list.contains(severity_buttons[i].getText())) + { + severity_buttons[0].setSelection(false); + severity_buttons[0].notifyListeners(SWT.Selection, new Event()); + severity_buttons[i].setSelection(true); + } + } + if(delta_size_option!=null) + { + delta_dropdown.select(delta_dropdown.indexOf(delta_size_option)); + delta_dropdown.notifyListeners(SWT.Selection, new Event()); + + //setText will not work if the verify listener is there. + //So, remove it for temporary + start_text.removeVerifyListener(verify_listener); + end_text.removeVerifyListener(verify_listener); + if(sizes!=null && sizes.length == 2) + { + start_text.setText(sizes[0]); + end_text.setText(sizes[1]); + } + else if(sizes!=null && sizes.length == 1) + { + start_text.setText(sizes[0]); + } + //Add listeners again + start_text.addVerifyListener(verify_listener); + end_text.addVerifyListener(verify_listener); + } + + if(delta_count_option!=null) + { + delta_dropdown2.select(delta_dropdown2.indexOf(delta_count_option)); + delta_dropdown2.notifyListeners(SWT.Selection, new Event()); + + //setText will not work if the verify listener is there. + //So, remove it for temporary + start_text2.removeVerifyListener(verify_listener); + end_text2.removeVerifyListener(verify_listener); + if(counts!=null && counts.length == 2) + { + start_text2.setText(counts[0]); + end_text2.setText(counts[1]); + } + else if(counts!=null && counts.length == 1) + start_text2.setText(counts[0]); + + //Add listeners again + start_text2.addVerifyListener(verify_listener); + end_text2.addVerifyListener(verify_listener); + } + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/SaveFilterOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/SaveFilterOptions.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.dialogs; + +import org.eclipse.jface.dialogs.IDialogSettings; + +import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin; + +/** + * Helper class to store the selections in Advanced Filter Dialog. + * + */ +public class SaveFilterOptions { + + public static final String FILTER_OPTION_SECTION = "Filter Selection Section"; + public static final String FILTER_OPTION = "Filter Selection"; + + public static final String FILTER_TEXT_SECTION = "Filter Text Section"; + public static final String FILTER_TEXT = "Filter text"; + + public static final String EVENTS_SECTION = "Events Section"; + public static final String EVENTS_LIST = "List of events"; + + public static final String SEVERITY_SECTION = "Severity Section"; + public static final String SEVERITY_LIST = "List of severities"; + + public static final String SIZE_OPTION_SECTION = "Size Selection Section"; + public static final String SIZE_OPTION = "Size Selection"; + + public static final String COUNT_OPTION_SECTION = "Count Selection Section"; + public static final String COUNT_OPTION = "Count Selection"; + + public static final String SIZES_SECTION = "Sizes Section"; + public static final String TO_FROM_SIZES = "Sizes"; + + public static final String COUNTS_SECTION = "Counts Section"; + public static final String TO_FROM_COUNT = "Counts"; + + public static enum ValueTypes {FILTER_TYPE, ITEM_TEXT, EVENTS, SEVERITIES, SIZE_TYPE, COUNT_TYPE, SIZES, COUNTS} + + + /** + * Save selected values + * @see #getValues(ValueTypes) + * @param key + * @param values + */ + public void saveValues(ValueTypes key, String[] values) { + IDialogSettings section = null; + switch (key) { + case EVENTS: + section = getSection(EVENTS_SECTION); + if(section!=null) + section.put(EVENTS_LIST, values); + break; + case SEVERITIES: + section = getSection(SEVERITY_SECTION); + if(section!=null) + section.put(SEVERITY_LIST, values); + break; + case SIZES: + section = getSection(SIZES_SECTION); + if(section!=null) + section.put(TO_FROM_SIZES, values); + break; + case COUNTS: + section = getSection(COUNTS_SECTION); + if(section!=null) + section.put(TO_FROM_COUNT, values); + + break; + default: + break; + } + } + + /** + * Get values for type + * @see #saveValues(ValueTypes, String[]) + * @param key + * @return values + */ + public String[] getValues(ValueTypes key) + { + IDialogSettings section = null; + String[] values = null; + switch (key) { + case EVENTS: + section = getSection(EVENTS_SECTION); + if(section != null) + values = section.getArray(EVENTS_LIST); + break; + case SEVERITIES: + section = getSection(SEVERITY_SECTION); + if(section != null) + values = section.getArray(SEVERITY_LIST); + break; + case SIZES: + section = getSection(SIZES_SECTION); + if(section != null) + values = section.getArray(TO_FROM_SIZES); + break; + case COUNTS: + section = getSection(COUNTS_SECTION); + if(section != null) + values = section.getArray(TO_FROM_COUNT); + break; + default: + break; + } + return values; + } + + /** + * Save selected value using that in next time when dialog is opened + * @see #getPreviousDropdownOption(ValueTypes) + * @see #getValues(ValueTypes) for indexes + * @param key + * @param index + */ + public void saveDropdownOption(ValueTypes key, String index) + { + IDialogSettings section = null; + switch (key) { + case SIZE_TYPE: + section = getSection(SIZE_OPTION_SECTION); + if(section!=null) + section.put(SIZE_OPTION, index); + break; + + case COUNT_TYPE: + section = getSection(COUNT_OPTION_SECTION); + if(section!=null) + section.put(COUNT_OPTION, index); + break; + case FILTER_TYPE: + section = getSection(FILTER_OPTION_SECTION); + if(section!=null) + section.put(FILTER_OPTION, index); + break; + case ITEM_TEXT: + section = getSection(FILTER_TEXT_SECTION); + if(section!=null) + section.put(FILTER_TEXT, index); + break; + default: + break; + } + } + + /** + * Get previously selected value for type + * @see #saveDropdownOption(ValueTypes, String) + * @param key + * @return previously selected value for type (one of the public constants described in this class). + */ + public String getPreviousDropdownOption(ValueTypes key) + { + IDialogSettings section = null; + String index = null; + switch (key) { + case SIZE_TYPE: + section = getSection(SIZE_OPTION_SECTION); + if(section != null) + index = section.get(SIZE_OPTION); + break; + case COUNT_TYPE: + section = getSection(COUNT_OPTION_SECTION); + if(section != null) + index = section.get(COUNT_OPTION); + break; + case FILTER_TYPE: + section = getSection(FILTER_OPTION_SECTION); + if(section != null) + index = section.get(FILTER_OPTION); + break; + case ITEM_TEXT: + section = getSection(FILTER_TEXT_SECTION); + if(section != null) + index = section.get(FILTER_TEXT); + break; + default: + break; + } + return index; + } + + /** + * @param sectionName name of the section to be retrieved + * @return section which maps to given name, in dialog_setting.xml file. + */ + protected IDialogSettings getSection(String sectionName) { + IDialogSettings retVal = null; + if (SwmtAnalyserPlugin.getDefault().getDialogSettings() != null) { + retVal = SwmtAnalyserPlugin.getDefault().getDialogSettings().getSection(sectionName); + if (retVal == null) { + retVal = SwmtAnalyserPlugin.getDefault().getDialogSettings().addNewSection(sectionName); + } + } + return retVal; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/FilterTextTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/FilterTextTable.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,438 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; + +import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction; +import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider; +import com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Customized TableViewer UI class for showing items in Graphs Tab. + * + */ +public class FilterTextTable extends Composite implements ISelectionProvider{ + + + /** + * Copy a to clipboard action + */ + private IAction actionContextMenuCopyTo; + + //Check box Table Viewer + private CheckboxTableViewer tableViewer; + //Text box to filter items in table + private Text filterText; + //Drop down to select filter type -> 'Start with' or -> 'Contains' + private Combo filterTypes; + //Label for showing the numbr of checked elements + private Label statusLabel; + //Viewer filter for tableviewer + private TableTextFilter textFilter; + private IGraphTypeSelectionListener graphListener; + //Checkbox state change listener + private CheckBoxStateChangeListener listener; + //Temporary elements + private String tableName; + /** + * Item names for creating {@link TableViewerInputObject} + */ + ArrayList input = new ArrayList(); + + /** + * Save all checked elements in this + */ + Map checked = new HashMap(); + /** + * Threads + */ + static final String THREADS_TITLE = "Threads"; + /** + * Chunks + */ + static final String CHUNKS_TITLE = "Chunks"; + /** + * Disks + */ + static final String DISKS_TITLE = "Disks"; + /** + * System Data + */ + static final String SYSTEM_DATA_TITLE = "System Data"; + + /** + * Construction + * @param graphListener + * @param composite + * @param columnName + */ + public FilterTextTable(IGraphTypeSelectionListener graphListener, Composite composite, String columnName) { + + super(composite, SWT.NONE); + + this.tableName = columnName; + this.graphListener = graphListener; + + setLayout(new GridLayout(2, false)); + GridData g = new GridData(GridData.FILL_BOTH); + setLayoutData(g); + + filterText = new Text(this, SWT.BORDER); + filterText.setText("type filter text"); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = false; + gd.verticalAlignment = SWT.TOP; + filterText.setLayoutData(gd); + filterText.selectAll(); + textFilter = new TableTextFilter(1); + + filterText.addModifyListener(new ModifyListener(){ + public void modifyText(ModifyEvent e) { + String t = ((Text)e.widget).getText(); + textFilter.setFilterText(t); + textFilter.setFilterTypeIndex(filterTypes.getSelectionIndex()); + refreshTableContents(); + } + + }); + + filterTypes = new Combo(this, SWT.BORDER|SWT.READ_ONLY); + filterTypes.setItems(new String[]{"Starts with", "Contains"}); + GridData data = new GridData(); + data.widthHint = 100; + data.heightHint = 15; + filterTypes.select(0); + filterTypes.setLayoutData(data); + filterTypes.addSelectionListener(new SelectionListener() { + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + textFilter.setFilterTypeIndex(filterTypes.getSelectionIndex()); + refreshTableContents(); + } + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + // Not needed/used + } + }); + + tableViewer = CheckboxTableViewer.newCheckList(this, SWT.BORDER|SWT.FULL_SELECTION | SWT.MULTI); + GridData tableData = new GridData(GridData.FILL_BOTH); + tableData.horizontalSpan = 2; + + tableViewer.getTable().setLayoutData(tableData); + + TableColumn tc = new TableColumn(tableViewer.getTable(), SWT.CENTER); + tc.setWidth(50); + tc.setResizable(true); + + TableColumn tc1 = new TableColumn(tableViewer.getTable(), SWT.LEFT); + tc1.setText(columnName); + tc1.setWidth(400); + tc1.setResizable(true); + tc1.addListener(SWT.Selection, new Listener(){ + public void handleEvent(Event event) { + TableColumn sortedColumn = tableViewer.getTable().getSortColumn(); + TableColumn currentSelected = (TableColumn)event.widget; + + int dir = tableViewer.getTable().getSortDirection(); + + if(sortedColumn == currentSelected){ + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + }else + { + tableViewer.getTable().setSortColumn(currentSelected); + dir = SWT.UP; + } + if(currentSelected == tableViewer.getTable().getColumn(1)) + { + tableViewer.setSorter(new Sorter(dir)); + } + tableViewer.getTable().setSortDirection(dir); + } + }); + + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLinesVisible(true); + tableViewer.setContentProvider(new TableStructuredContentProvider(this)); + tableViewer.setLabelProvider(new TableLabelColorProvider()); + + listener = new CheckBoxStateChangeListener(); + tableViewer.addCheckStateListener(listener); + + tableViewer.addFilter(textFilter); + + GridData lGd = new GridData(GridData.FILL_HORIZONTAL); + lGd.verticalAlignment = GridData.END; + statusLabel = new Label(this, SWT.NONE); + statusLabel.setText("Selected : 0"); + statusLabel.setLayoutData(lGd); + + + actionContextMenuCopyTo = new CopyToClipboardAction(this); + + // + // Context menu + // + MenuManager menuMgr = new MenuManager("#ContextMenu1"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + FilterTextTable.this.populateContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(tableViewer.getTable()); + tableViewer.getTable().setMenu(menu); + } + + /** + * Refreshes data table contents. + */ + private void refreshTableContents() { + //Refresh in separate thread to avoid invalid thread access. + Runnable runnable = new Runnable(){ + public void run() { + tableViewer.refresh(); + } + }; + Display.getDefault().syncExec(runnable); + + //After refresh, check the elements again if any selected before. + Iterator> itr = checked.entrySet().iterator(); + while(itr.hasNext()) + { + Entry entry = itr.next(); + for(int i=0; i < tableViewer.getTable().getItemCount(); i++) + { + TableViewerInputObject objNow = (TableViewerInputObject)tableViewer.getElementAt(i); + //If name is same, then update the color and object + if(entry.getKey().equals(objNow.getName())) + { + tableViewer.setChecked(objNow, true); + tableViewer.getTable().getItem(i).setBackground(0, entry.getValue()); + objNow.setColor(entry.getValue()); + CheckStateChangedEvent ev = new CheckStateChangedEvent(tableViewer, objNow, true); + listener.checkStateChanged(ev); + } + } + } + + //If in the filtered list no selection is there, then clear the graph + if(tableViewer.getCheckedElements().length==0) + { + CheckStateChangedEvent ev = new CheckStateChangedEvent(tableViewer, null, false); + listener.checkStateChanged(ev); + } + //Update the status label + statusLabel.setText("Selected : "+tableViewer.getCheckedElements().length); + } + + /** + * Set the input and update label + * @param input + */ + public void setInput(ArrayList input) { + this.input = input; + statusLabel.setText("Selected : 0"); + tableViewer.setInput(this.input); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) + */ + public void setEnabled(boolean arg0) { + filterText.setEnabled(arg0); + filterTypes.setEnabled(arg0); + tableViewer.getTable().setEnabled(arg0); + //tableViewer.setAllGrayed(arg0); + super.setEnabled(arg0); + } + + /** + * Clears the selections in table. + * + */ + public void cancelSelectionList(){ + statusLabel.setText("Selected : 0"); + tableViewer.refresh(); + checked.clear(); + } + + /** + * Set the text to filter and notify listeners + * @param text + */ + public void setFilterText(String text) + { + filterText.setText(text); + filterText.notifyListeners(SWT.Modify, new Event()); + } + + /** + * + * Customized CheckState Listener class. + * + */ + class CheckBoxStateChangeListener implements ICheckStateListener + { + /** + * When CheckBox selection is changed, the tool generates + * random colors and assigns them to selected threads. + * These colors are used to distinguish graphs related to different threads. + * Also, this method informs the listeners about selected threads/chunks/disks/system-elements. + */ + public void checkStateChanged(CheckStateChangedEvent e) { + + TableViewerInputObject obj =((TableViewerInputObject)e.getElement()); + + if(obj!=null) + { + if(e.getChecked()) + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "::::::::"+obj); + Random rand = new Random(); + int r = rand.nextInt(255); + int g = rand.nextInt(255); + int b = rand.nextInt(255); + + if(obj.getColor() == null) + obj.setColor(new Color(Display.getDefault(), r, g, b)); + + if(!checked.containsKey(obj.getName())) + checked.put(obj.getName(), obj.getColor()); + } + else + { + obj.setColor(null); + checked.remove(obj.getName()); + } + tableViewer.update(obj, null); + } + if(tableName.equals(THREADS_TITLE)) + graphListener.notifyThreadsSelection(); + else if(tableName.equals(CHUNKS_TITLE)) + graphListener.notifyChunksSelection(); + else if(tableName.equals(DISKS_TITLE)) + graphListener.notifyDisksSelection(); + else if(tableName.equals(SYSTEM_DATA_TITLE)) + graphListener.notifySysElementsSelection(); + + tableViewer.getTable().deselectAll(); + statusLabel.setText("Selected : "+tableViewer.getCheckedElements().length); + } + + } + + /** + * Returns the table viewer associated with this. + * @return tableViewer + */ + public CheckboxTableViewer getTableViewer() + { + return this.tableViewer; + } + + /** + * @return check state listener associated with this table. + */ + public CheckBoxStateChangeListener getCheckStateListener() + { + return this.listener; + } + + /** + * This sorter class is associated with element name + * + */ + class Sorter extends ViewerSorter + { + int sortDirection; + + Sorter(int sortDirection) + { + this.sortDirection = sortDirection; + } + public int compare(Viewer viewer, Object e1, Object e2) + { + int returnValue = 0; + + TableViewerInputObject o1 = (TableViewerInputObject)e1; + TableViewerInputObject o2 = (TableViewerInputObject)e2; + + returnValue = o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase()); + + if(sortDirection == SWT.UP) + return returnValue; + else + return returnValue * -1; + } + } + + /** + * Populates context menu at run time. + * @param manager Menu manager instance. + */ + private void populateContextMenu(IMenuManager manager) { + manager.add(actionContextMenuCopyTo); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection() + */ + public ISelection getUserSelection() { + return tableViewer.getSelection(); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsContentProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsContentProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Content provider for Graphed Items TableViewer + * + */ +public class GraphedItemsContentProvider implements IStructuredContentProvider { + + @SuppressWarnings("unchecked") + private ArrayList inputs; + + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + @SuppressWarnings("unchecked") + public Object[] getElements(Object arg0) { + inputs = (ArrayList)arg0; + return inputs.toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsHelper.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,355 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; +import java.util.Random; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.TableColumn; + +import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction; +import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphForAllEvents; + +/** + * Helper class for graphed items tab. + * + */ +public class GraphedItemsHelper implements Listener, ISelectionProvider{ + + /** + * Copy a to clipboard action + */ + private IAction actionContextMenuCopyTo; + + + CheckboxTableViewer graphedItemsViewer = null; + + private GraphForAllEvents graphedItemsGraph; + private GraphedItemsSelectionListener graphedItemChangedListener; + + /** + * Construts UI controls over the area of given TabItem. + * @param graphedItemsTab represents Graphed items Tab. + * @param allEventsGraph represents the graph which gets updated based upon + * the actions on UI controls of the Graphed items tab. + */ + public CheckboxTableViewer constructGraphedItemsViewer(TabItem graphedItemsTab, GraphForAllEvents allEventsGraph) + { + this.graphedItemsGraph = allEventsGraph; + + Composite compAllItems = new Composite(graphedItemsTab.getParent(), SWT.NONE); + compAllItems.setLayout(new GridLayout(1, true)); + + + graphedItemsViewer = CheckboxTableViewer.newCheckList(compAllItems, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI ); + graphedItemsViewer.getTable().setLayoutData(new GridData(GridData.FILL_VERTICAL|GridData.FILL_HORIZONTAL)); + + TableColumn tc = new TableColumn(graphedItemsViewer.getTable(), SWT.CENTER); + tc.setWidth(50); + tc.setResizable(true); + + TableColumn elems_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT); + elems_col.setText(GraphedItemsInput.COL1_ELEMENTS); + elems_col.setWidth(600); + elems_col.setResizable(true); + elems_col.addListener(SWT.Selection, this); + + TableColumn event_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT); + event_col.setText(GraphedItemsInput.COL2_EVENT); + event_col.setWidth(150); + event_col.setResizable(true); + event_col.addListener(SWT.Selection, this); + + TableColumn type_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT); + type_col.setText(GraphedItemsInput.COL3_TYPE); + type_col.setWidth(150); + type_col.setResizable(true); + type_col.addListener(SWT.Selection, this); + + graphedItemsViewer.getTable().setHeaderVisible(true); + graphedItemsViewer.getTable().setLinesVisible(true); + + graphedItemsViewer.setContentProvider(new GraphedItemsContentProvider()); + graphedItemsViewer.setLabelProvider(new TableLabelColorProvider()); + + graphedItemChangedListener = new GraphedItemsSelectionListener(allEventsGraph); + graphedItemsViewer.addCheckStateListener(graphedItemChangedListener); + + hookContextMenu(); + + graphedItemsTab.setControl(compAllItems); + + return graphedItemsViewer; + } + + /** + * This method creates the context menu on the Graphed Items Tab + */ + + private void hookContextMenu() + { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(graphedItemsViewer.getTable()); + graphedItemsViewer.getTable().setMenu(menu); + } + + private Color getRandomColor() + { + Random rand = new Random(); + int r = rand.nextInt(255); + int g = rand.nextInt(255); + int b = rand.nextInt(255); + return new Color(Display.getCurrent(), r, g,b); + } + + /** + * The method checks all items in the given viewer and assigns random colors for all checked items. + * @param tableViewer + */ + private void selectAllItems(CheckboxTableViewer tableViewer) + { + tableViewer.setAllChecked(true); + + for(Object obj:tableViewer.getCheckedElements()) + { + if(obj instanceof GraphedItemsInput){ + GraphedItemsInput graphedItem = (GraphedItemsInput)obj; + + if(graphedItem.getColor() == null) + graphedItem.setColor(getRandomColor()); + + tableViewer.update(obj, null); + } + } + + } + + /** + * @param manager -- MenuManager on which actions will be created. + */ + private void fillContextMenu(IMenuManager manager) { + //Popup Action to check all items in the graphed items viewer. + Action checkAllItems = new Action() + { + { + this.setText("Check all"); + this.setToolTipText(""); + } + public void run() + { + selectAllItems(graphedItemsViewer); + notifyGraphedItemsSelection(graphedItemsViewer, graphedItemsGraph); + } + + }; + manager.add(checkAllItems); + + //Popup action to uncheck all items in the graphed items viewer + Action unCheckAllItems = new Action() + { + { + this.setText("Uncheck all"); + } + public void run() + { + for(Object obj:graphedItemsViewer.getCheckedElements()) + { + ((GraphedItemsInput)obj).setColor(null); + graphedItemsViewer.setChecked(obj, false); + graphedItemsViewer.update(obj, null); + CheckStateChangedEvent e = new CheckStateChangedEvent(graphedItemsViewer, obj, false); + graphedItemChangedListener.checkStateChanged(e); + } + this.setToolTipText(""); + } + + }; + manager.add(unCheckAllItems); + + //Popup action to remove all items in the graphed items viewer + Action removeAllItems = new Action() + { + public void run() + { + graphedItemsViewer.setInput(null); + graphedItemsViewer.refresh(); + CheckStateChangedEvent e = new CheckStateChangedEvent(graphedItemsViewer, null, false); + graphedItemChangedListener.checkStateChanged(e); + graphedItemsGraph.removeAllData(); + } + { + this.setText("Remove all"); + this.setToolTipText(""); + } + }; + manager.add(removeAllItems); + + actionContextMenuCopyTo = new CopyToClipboardAction(this); + manager.add(actionContextMenuCopyTo); + } + + /** + * This method updates the graph based on the selections made in the given graphed items viewer. + * @param tableViewer + * @param graphToBeUpdated + */ + private void notifyGraphedItemsSelection(CheckboxTableViewer tableViewer, GraphForAllEvents graphToBeUpdated) + { + Object [] checkedElems = tableViewer.getCheckedElements(); + + ArrayList selectedItems = new ArrayList(); + + for(Object obj:checkedElems) + { + GraphedItemsInput graphInput = (GraphedItemsInput)obj; + selectedItems.add(graphInput); + } + + graphToBeUpdated.setGraphedItemsInput(selectedItems); + graphToBeUpdated.constructGraphArea(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + public void handleEvent(Event event) { + + TableColumn sortedColumn = graphedItemsViewer.getTable().getSortColumn(); + TableColumn currentSelected = (TableColumn)event.widget; + + int dir = graphedItemsViewer.getTable().getSortDirection(); + + if(sortedColumn == currentSelected){ + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + }else + { + graphedItemsViewer.getTable().setSortColumn(currentSelected); + dir = SWT.UP; + } + graphedItemsViewer.setSorter(new Sorter(dir,currentSelected)); + graphedItemsViewer.getTable().setSortDirection(dir); + } + + + /** + * + * Customized CheckStateListener for Graphed Items viewer. + * This listener is associated with the Graphed Items viewer. + * The 'checkStateChanged' method gets invoked, when items are + * checked/unchecked in Graphed Items viewer. + * + */ + class GraphedItemsSelectionListener implements ICheckStateListener + { + private GraphForAllEvents graphToBeUpdated; + + public GraphedItemsSelectionListener(GraphForAllEvents graphToBeUpdated){ + this.graphToBeUpdated = graphToBeUpdated; + } + public void checkStateChanged(CheckStateChangedEvent e) { + + GraphedItemsInput obj =((GraphedItemsInput)e.getElement()); + if(obj!=null) + { + if(e.getChecked()) + { + if(obj.getColor() == null) + obj.setColor(getRandomColor()); + } + else + { + obj.setColor(null); + } + graphedItemsViewer.update(obj, null); + } + + notifyGraphedItemsSelection(graphedItemsViewer,graphToBeUpdated); + } + + + } + + /** + * This sorter class is associated with table in Graphed Items Tab + * It contains logic to sort the table based on various columns. + * + */ + class Sorter extends ViewerSorter + { + int sortDirection; + TableColumn column; + Sorter(int sortDirection, TableColumn column) + { + this.sortDirection = sortDirection; + this.column = column; + } + public int compare(Viewer viewer, Object e1, Object e2) + { + int returnValue = 0; + + GraphedItemsInput o1 = (GraphedItemsInput)e1; + GraphedItemsInput o2 = (GraphedItemsInput)e2; + + if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL1_ELEMENTS)) + returnValue = o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase()); + else if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL2_EVENT)) + returnValue = o1.getEvent().toLowerCase().compareTo(o2.getEvent().toLowerCase()); + else if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL3_TYPE)) + returnValue = o1.getType().toLowerCase().compareTo(o2.getType().toLowerCase()); + + if(sortDirection == SWT.UP) + return returnValue; + else + return returnValue * -1; + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection() + */ + public ISelection getUserSelection() { + return graphedItemsViewer.getSelection(); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsInput.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsInput.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import org.eclipse.swt.graphics.Color; + +/** + * Input class for the tableviewer in GraphedItems tab. + * + */ +public class GraphedItemsInput { + + public static final String COL1_ELEMENTS = "Elements"; + public static final String COL2_EVENT = "Event"; + public static final String COL3_TYPE = "Type"; + + private static final String TAB = "\t"; + + private String name; + private String event; + private String type; + private Color color; + + /** + * Get event parameter + * @return event + */ + public String getEvent() { + return event; + } + /** + * Set event parameter + * @param event + */ + public void setEvent(String event) { + this.event = event; + } + /** + * Get name parameter + * @return name + */ + public String getName() { + return name; + } + /** + * Set name parameter + * @param name + */ + public void setName(String name) { + this.name = name; + } + /** + * Get type parameter + * @return type + */ + public String getType() { + return type; + } + /** + * Set type parameter + * @param type + */ + public void setType(String type) { + this.type = type; + } + /** + * Get color parameter + * @return color + */ + public Color getColor() { + return color; + } + /** + * Set color parameter + * @param color + */ + public void setColor(Color color) { + this.color = color; + } + + /** + * Get tab separated values for this result. + * @return values + */ + public String getTabSeparatedValues() { + StringBuffer b = new StringBuffer(); + b.append(getName()); + b.append(TAB); + b.append(getEvent()); + b.append(TAB); + b.append(getType()); + + return b.toString(); + } + + /** + * Get tab separated headers for this result. + * @return headers with tab as separator + */ + public String getTabSeparatedHeaders() { + StringBuffer b = new StringBuffer(); + b.append(COL1_ELEMENTS); + b.append(TAB); + b.append(COL2_EVENT); + b.append(TAB); + b.append(COL3_TYPE); + + return b.toString(); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesFilter.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,178 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants; +import com.nokia.s60tools.swmtanalyser.analysers.ResultElements; +import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog.FilterInput; + +/** + * Customized ViewerFilter for TableViewer in Analysis tab. + * + */ +public class IssuesFilter extends ViewerFilter { + + //Filter text + private String search_key = null; + //Settings selected in the advanced filter options dialog + private FilterInput adv_options = null; + + /** + * Set filter text + * @param value + */ + public void setFilterText(String value) + { + search_key = value; + } + + /** + * Set advanced filter to issues + * @param adv_option + */ + public void setAdvancedSearchOptions(FilterInput adv_option) + { + this.adv_options = adv_option; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + + //If the search is done using the advanced filter options dialog + if(adv_options!=null) + { + int filter_option = adv_options.getName_Filter_option(); + String filter_text = adv_options.getFilter_text(); + List events = new ArrayList(); + if(adv_options.getEvents()!=null) + events = Arrays.asList(adv_options.getEvents()); + + List severities = new ArrayList(); + if(adv_options.getSeverities()!=null) + severities = Arrays.asList(adv_options.getSeverities()); + + int delta_bytes_option = adv_options.getDelta_bytes_option(); + long s1 = adv_options.getStart_size(); + long e1 = adv_options.getEnd_size(); + + int delta_count_option = adv_options.getDelta_count_option(); + long s2 = adv_options.getStart_count(); + long e2 = adv_options.getEnd_count(); + + if(element instanceof ResultElements) + { + ResultElements item = (ResultElements)element; + String item_name = item.getItemName(); + String event = item.getEvent(); + long delta = item.getDeltaValue(); + AnalyserConstants.Priority p = item.getPriority(); + + boolean flag = true; + + if(filter_option == 0 && filter_text!=null && !item_name.toLowerCase().startsWith(filter_text.toLowerCase())) + return false; + if(filter_option == 1 && filter_text!=null && item_name.toLowerCase().indexOf(filter_text.toLowerCase()) == -1) + return false; + if(events.size()>0 && !events.contains(event)) + return false; + if(severities.size()>0 && !severities.contains(p)) + return false; + if(item.getType().compareTo(AnalyserConstants.DeltaType.SIZE)==0) + { + switch (delta_bytes_option) { + case 0: + //flag = flag && true; + break; + case 1: + if(delta < s1 || delta > e1) + return false; + break; + case 2: + if(delta != s1) + return false; + break; + case 3: + if(delta < s1) + return false; + break; + case 4: + if(delta > s1) + return false; + break; + + default: + break; + } + } + else if(item.getType().compareTo(AnalyserConstants.DeltaType.COUNT)==0) + { + switch (delta_count_option) { + case 0: + //flag = flag && true; + break; + case 1: + if(delta < s2 || delta > e2) + return false; + break; + case 2: + if(delta != s2) + return false; + break; + case 3: + if(delta < s2) + return false; + break; + case 4: + if(delta > s2) + return false; + break; + + default: + break; + } + } + + return flag; + } + } + + //If searching is cancelled. + if(search_key == null) + return true; + + //If search is done using the severity dropdown in the Analysis tab. + if(element instanceof ResultElements) + { + ResultElements item = (ResultElements)element; + AnalyserConstants.Priority p = item.getPriority(); + if(p.name().toLowerCase().matches(search_key.toLowerCase())) + return true; + else + return false; + } + return true; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeContentProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeContentProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes; + +/** + * ContentProvider for table viewer in the Analysis tab. + * + */ +public class IssuesTreeContentProvider implements ITreeContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parent) { + ArrayList total_children = new ArrayList(); + + if(parent instanceof ResultsParentNodes) { + return ((ResultsParentNodes)parent).getChildren(); + } + + return total_children.toArray(); + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object arg0) { + if(arg0 instanceof ResultsParentNodes) + return arg0; + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object arg0) { + return getChildren(arg0)!=null && getChildren(arg0).length > 0; + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + @SuppressWarnings("unchecked") + public Object[] getElements(Object arg0) { + return ((ArrayList)arg0).toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeLabelProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeLabelProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants; +import com.nokia.s60tools.swmtanalyser.analysers.ResultElements; +import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes; + +/** + * LableProvider for the tree viewer in the Analysis tab + * + */ +public class IssuesTreeLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider, ITableFontProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) + */ + public Image getColumnImage(Object arg0, int arg1) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) + */ + public String getColumnText(Object element, int column_index) { + + if(column_index == 1) + { + if(element instanceof ResultsParentNodes) + { + return ((ResultsParentNodes)element).toString(); + } + else if(element instanceof ResultElements) + { + return ((ResultElements)element).getItemName(); + } + } + else if(column_index == 2) + { + if(element instanceof ResultElements) + return ((ResultElements)element).getEvent(); + } + else if(column_index == 3) + { + if(element instanceof ResultElements) + return ((ResultElements)element).getDelta(); + } + else if(column_index == 4) + { + if(element instanceof ResultElements) + return ((ResultElements)element).getPriority().name(); + } + //For internal testing. + /*else if(arg1 == 4) + { + if(arg0 instanceof ResultElements) + return ((ResultElements)arg0).getGrowing_factor()+""; + }*/ + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.BaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void addListener(ILabelProviderListener arg0) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() + */ + public void dispose() { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.BaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) + */ + public boolean isLabelProperty(Object arg0, String arg1) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.BaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener arg0) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object, int) + */ + public Color getBackground(Object element, int columnIndex) { + + if(element instanceof ResultElements ) + { + ResultElements item = (ResultElements)element; + + if(columnIndex == 4) + { + Color background_color = null; + + switch (item.getPriority()) { + case CRITICAL: + background_color = AnalyserConstants.COLOR_SEVERITY_CRITICAL; + break; + case HIGH: + background_color = AnalyserConstants.COLOR_SEVERITY_HIGH; + break; + case NORMAL: + background_color = AnalyserConstants.COLOR_SEVERITY_NORMAL; + break; + + default: + break; + } + return background_color; + } + else if(columnIndex == 0) + { + return item.getColor(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object, int) + */ + public Color getForeground(Object element, int columnIndex) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableFontProvider#getFont(java.lang.Object, int) + */ + public Font getFont(Object arg0, int arg1) { + if(arg0 instanceof ResultsParentNodes) + { + Font f = Display.getCurrent().getSystemFont(); + return new Font(Display.getCurrent(), f.getFontData()[0].getName(), 8, SWT.BOLD); + } + return null; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesViewer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesViewer.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,467 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.util.ArrayList; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; + +import com.nokia.s60tools.swmtanalyser.analysers.ResultElements; +import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes; +import com.nokia.s60tools.swmtanalyser.resources.Tooltips; +import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction; +import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils; +import com.nokia.s60tools.swmtanalyser.ui.graphs.LinearIssuesGraph; + +/** + * Customized tree viewer in the Analysis tab. + * + */ +public class IssuesViewer implements Listener, ICheckStateListener, ISelectionProvider { + + /** + * Copy a to clipboard action + */ + private IAction actionContextMenuCopyTo; + + private Tree issues_tree; + private CheckboxTreeViewer issues_viewer; + private LinearIssuesGraph issue_graph; + + + /** + * Construction + * @param tree + * @param graphToBeUpdated + */ + public IssuesViewer(Tree tree, LinearIssuesGraph graphToBeUpdated) + { + this.issues_tree = tree; + issues_viewer = new CheckboxTreeViewer(tree); + + GridData tableData = new GridData(GridData.FILL_BOTH); + tableData.horizontalSpan = 7; + tableData.grabExcessVerticalSpace = true; + + issues_viewer.getTree().setLayoutData(tableData); + this.issue_graph = graphToBeUpdated; + + issues_viewer.addCheckStateListener(this); + + } + /** + * Create linear analysis results tree and graph + */ + public void createIssuesViewerAndGraph() + { + TreeColumn tc = new TreeColumn(issues_viewer.getTree(), SWT.LEFT); + tc.setWidth(60); + tc.setResizable(true); + + TreeColumn itemName = new TreeColumn(issues_viewer.getTree(), SWT.NONE); + itemName.setText(ResultElements.ITEM_NAME_COLUMN); + itemName.setWidth(300); + itemName.setToolTipText("Name of the thread/chunk/disk etc."); + + TreeColumn event = new TreeColumn(issues_viewer.getTree(), SWT.NONE); + event.setText(ResultElements.EVENT_COLUMN); + event.setWidth(200); + event.setToolTipText("Name of the event."); + + TreeColumn delta = new TreeColumn(issues_viewer.getTree(), SWT.NONE); + delta.setText(ResultElements.DELTA_COLUMN); + delta.setWidth(150); + delta.setToolTipText("Difference between the last and first cycle values."); + + TreeColumn severity = new TreeColumn(issues_viewer.getTree(), SWT.CENTER); + severity.setText(ResultElements.SEVERITY_COLUMN); + severity.setWidth(100); + severity.setResizable(false); + severity.setToolTipText("Severity of the issue."); + + itemName.addListener(SWT.Selection, this); + event.addListener(SWT.Selection, this); + delta.addListener(SWT.Selection,this); + severity.addListener(SWT.Selection, this); + + issues_viewer.getTree().setHeaderVisible(true); + issues_viewer.getTree().setLinesVisible(true); + + issues_tree.setSortColumn(severity); + issues_tree.setSortDirection(SWT.DOWN); + issues_viewer.setSorter(new IssuesSorter(SWT.DOWN, severity)); + + //Showing tooltip for the each issue in the tree view + Listener treeListener = new Listener () { + Shell tip = null; + Label label = null; + public void handleEvent (Event event) { + switch (event.type) { + case SWT.Dispose: + case SWT.KeyDown: + case SWT.MouseExit: + case SWT.MouseMove: { + if (tip == null) break; + tip.dispose (); + tip = null; + label = null; + break; + } + case SWT.MouseHover: { + TreeItem item = issues_tree.getItem (new Point (event.x, event.y)); + if (item != null && getTooltipForItem(item)!="") { + if (tip != null && !tip.isDisposed ()) tip.dispose (); + tip = new Shell (Display.getCurrent().getActiveShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); + tip.setBackground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_BACKGROUND)); + FillLayout layout = new FillLayout (); + layout.marginWidth = 2; + tip.setLayout (layout); + label = new Label (tip, SWT.NONE); + label.setForeground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_FOREGROUND)); + label.setBackground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_BACKGROUND)); + label.setData ("TreeItem", item); + label.setText (getTooltipForItem(item)); + Point size = tip.computeSize (SWT.DEFAULT, SWT.DEFAULT); + Point p = new Point(event.x, event.y); + Point pp = Display.getCurrent().map(issues_tree, null, p); + tip.setBounds (pp.x, pp.y+20, size.x, size.y); + tip.setVisible (true); + } + } + } + } + }; + issues_tree.addListener (SWT.Dispose, treeListener); //When widget disposed + issues_tree.addListener (SWT.KeyDown, treeListener); //When mouse key pressed + issues_tree.addListener (SWT.MouseMove, treeListener); //When mouse moved + issues_tree.addListener (SWT.MouseHover, treeListener); //When mouse hovers over the control + issues_tree.addListener (SWT.MouseExit, treeListener); + + issue_graph.constructGraphArea(); + + hookContextMenu(); + } + + /** + * Sets the content provider for viewer + * @see {@link CheckboxTreeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider)} + * @param contentProvider + */ + public void setContentProvider(ITreeContentProvider contentProvider) + { + issues_viewer.setContentProvider(contentProvider); + } + + /** + * Sets the label provider for viewer + * @see {@link CheckboxTreeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)} + * @param labelProvider + */ + public void setLabelProvider(IssuesTreeLabelProvider labelProvider) + { + issues_viewer.setLabelProvider(labelProvider); + } + + /** + * Adds a filter to viewer + * @see {@link CheckboxTreeViewer#addFilter(ViewerFilter)} + * @param filter + */ + public void addFilter(ViewerFilter filter) + { + issues_viewer.addFilter(filter); + } + + /** + * Refresh the viewer @see + * {@link CheckboxTreeViewer#refresh()} + */ + public void refresh() + { + issues_viewer.refresh(); + } + + /** + * Set the input to viewer and expand + * @see {@link CheckboxTreeViewer#setInput(Object)} + * @see {@link CheckboxTreeViewer#expandAll()} + * @param input + */ + public void setInput(Object input) + { + issues_viewer.setInput(input); + issues_viewer.expandAll(); + } + + /** + * Get the input from viewer + * @see {@link CheckboxTreeViewer#getInput()} + * @param input + */ + public Object getInput() + { + return issues_viewer.getInput(); + } + + /** + * Returns the description for the given event. + * @param item TreeItem of event + * @return tooltip description + */ + public String getTooltipForItem(TreeItem item) + { + String tooltip = item.getText(2); + if(tooltip == "Heap size") + { + tooltip = Tooltips.getTooltip("Tooltips.HeapSize") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "No of Files") + { + tooltip = Tooltips.getTooltip("Tooltips.NoOfFiles1")+item.getText(1)+Tooltips.getTooltip("Tooltips.NoOfFiles2") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "Heap allocated space") + { + tooltip = Tooltips.getTooltip("Tooltips.HeapAllocatedSpace") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "Heap allocated cell count") + { + tooltip = Tooltips.getTooltip("Tooltips.HeapAllocatedCellCount") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "No of PS Handles") + { + tooltip = Tooltips.getTooltip("Tooltips.NoOfPSHandles")+item.getText(1) + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "System Data") + { + tooltip = Tooltips.getTooltip("Tooltips.SystemData") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "RAM used") + { + tooltip = Tooltips.getTooltip("Tooltips.RAMUsed") + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + else if(tooltip == "Disk used") + { + tooltip = Tooltips.getTooltip("Tooltips.DiskUsed")+item.getText(1) + +"\n"+Tooltips.getTooltip("Tooltips.Delta") + +"\n"+Tooltips.getTooltip("Tooltips.Severity"); + } + + return tooltip; + } + + private class IssuesSorter extends ViewerSorter + { + + private int direction; + private TreeColumn givenColumn; + + public IssuesSorter(int direction, TreeColumn sortColumn) + { + this.direction = direction; + this.givenColumn = sortColumn; + } + public int compare(Viewer viewer, Object obj1, Object obj2) + { + int result = 0; + + if(obj1 instanceof ResultElements && obj2 instanceof ResultElements) + { + ResultElements elem1 = (ResultElements)obj1; + ResultElements elem2 = (ResultElements)obj2; + + if(givenColumn.getText().equalsIgnoreCase(ResultElements.DELTA_COLUMN)) + { + result = elem1.compareByDelta(elem2); + } + else if(givenColumn.getText().equalsIgnoreCase(ResultElements.SEVERITY_COLUMN)) + { + result = elem1.compareTo(elem2); + } + else if(givenColumn.getText().equalsIgnoreCase(ResultElements.ITEM_NAME_COLUMN)) + { + result = elem1.getItemName().compareTo(elem2.getItemName()); + } + else if(givenColumn.getText().equalsIgnoreCase(ResultElements.EVENT_COLUMN)) + { + result = elem1.getEvent().compareTo(elem2.getEvent()); + } + if(direction == SWT.UP) + return result * 1; + else + return result * -1; + } + return result; + } + + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + public void handleEvent(Event event) + { + TreeColumn sortedColumn = issues_tree.getSortColumn(); + TreeColumn currentSelected = (TreeColumn)event.widget; + + int dir = issues_tree.getSortDirection(); + + if(sortedColumn == currentSelected){ + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + }else + { + issues_tree.setSortColumn(currentSelected); + dir = SWT.UP; + } + + issues_viewer.setSorter(new IssuesSorter(dir, currentSelected)); + issues_viewer.getTree().setSortDirection(dir); + + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) + */ + public void checkStateChanged(CheckStateChangedEvent event) { + + Object selectedElement = event.getElement(); + + if(selectedElement == null) + return; + + if(selectedElement instanceof ResultsParentNodes) + { + ((CheckboxTreeViewer)(issues_viewer)).setSubtreeChecked(selectedElement, event.getChecked()); + Object [] children = ((ResultsParentNodes)(selectedElement)).getChildren(); + + for(Object obj:children) + { + if(obj instanceof ResultElements) + { + ResultElements res = (ResultElements)obj; + CheckStateChangedEvent stateChangeEvent = new CheckStateChangedEvent(((CheckboxTreeViewer)(issues_viewer)), res, event.getChecked()); + checkStateChanged(stateChangeEvent); + } + } + } + else if(selectedElement instanceof ResultElements) { + { + ResultElements elem = ((ResultElements)selectedElement); + + if(event.getChecked()) + { + if(elem.getColor() == null) + elem.setColor(GraphsUtils.getRandomColor()); + } + else + { + elem.setColor(null); + } + issues_viewer.update(elem, null); + } + notifyIssuesSelection(); + } + + } + + private void notifyIssuesSelection() + { + Object [] checkedElems = ((CheckboxTreeViewer)(issues_viewer)).getCheckedElements(); + + ArrayList selectedItems = new ArrayList(); + + for(Object obj:checkedElems) + { + if(obj instanceof ResultElements) + { + ResultElements elem = (ResultElements)obj; + selectedItems.add(elem); + } + } + + issue_graph.setSelectedIssues(selectedItems); + issue_graph.constructGraphArea(); + } + /** + * This method creates the context menu on the Graphed Items Tab + */ + + private void hookContextMenu() + { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(issues_viewer.getControl()); + issues_viewer.getControl().setMenu(menu); + } + + /** + * @param manager -- MenuManager on which actions will be created. + */ + private void fillContextMenu(IMenuManager manager) { + actionContextMenuCopyTo = new CopyToClipboardAction(this); + manager.add(actionContextMenuCopyTo); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection() + */ + public ISelection getUserSelection() { + return issues_viewer.getSelection(); + } +} \ No newline at end of file diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditor.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1661 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.Random; +import java.util.Map.Entry; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Sash; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.ExpansionAdapter; +import org.eclipse.ui.forms.events.ExpansionEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.forms.widgets.TableWrapData; +import org.eclipse.ui.forms.widgets.TableWrapLayout; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.MultiPageEditorPart; + +import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin; +import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants; +import com.nokia.s60tools.swmtanalyser.analysers.IAnalyser; +import com.nokia.s60tools.swmtanalyser.analysers.ResultElements; +import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes; +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog; +import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog.FilterInput; +import com.nokia.s60tools.swmtanalyser.model.ExcelCreator; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.swmtanalyser.ui.graphs.ChunksGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.DisksGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphForAllEvents; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils; +import com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener; +import com.nokia.s60tools.swmtanalyser.ui.graphs.LinearIssuesGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.SwmtGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.SystemDataGraph; +import com.nokia.s60tools.swmtanalyser.ui.graphs.ThreadsGraph; +import com.nokia.s60tools.swmtanalyser.wizards.ReportGenerationWizard; + +/** + * SWMT Analyser editor view + * + */ +public class SWMTEditor extends MultiPageEditorPart implements SelectionListener, IGraphTypeSelectionListener{ + + // Overview Page Controls + private ScrolledForm form; + private Combo toCombo; + private Button allBtn; + private Button notAllBtn; + private Button export; + + //Trace Page Controls + private TabItem eventsTab; + private Combo eventsCombo; + private List eventList; + private TabFolder innerTabFolder; + private TabItem threadTab; + private TabItem chunksTab; + private TabItem diskTab; + private TabItem sysInfoTab; + private FilterTextTable threadTble; + private FilterTextTable chunkTble; + private FilterTextTable diskTble; + private FilterTextTable sysinfoTble; + + private static enum CATEGORIES { All_events, Chunks, Disk, Files, Heap, HPAS, RAM, System_info }; + private String[] CHUNKS_GRP = { "Global data size", "Non heap chunk size" }; + private String[] DISK_GRP = { "Disk used", "Disk total" }; + private String[] FILES_GRP = { "No of Files" }; + private String[] HEAP_GRP = { "Max size", "Heap size", "Heap allocated space", "Heap free space", "Heap allocated cell count", "Heap free cell count", "Free slack" }; //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ + private String[] HPAS_GRP = { "No of PS Handles" }; + private String[] RAM_GRP = { "RAM used", "RAM total" }; + private String[] SYSINFO_GRP = { "System Data" }; + private String[] ALL_GRP = { "RAM used", "RAM total", "Global data size", "Non heap chunk size", "Disk used", "Disk total", "No of Files", "Max size", "Heap size", "Heap allocated space", "Heap free space", "Heap allocated cell count", "Heap free cell count", "Free slack", "No of PS Handles", "System Data" }; //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ + + //Stores overiew information to be displayed in the first page + private OverviewData ov; + + // All cycles data + private ParsedData parsedData = new ParsedData(); + private ArrayList threads = new ArrayList(); + private ArrayList chunks = new ArrayList(); + private ArrayList nonHeapChunks = new ArrayList(); + private ArrayList disks = new ArrayList(); + + //Four table viewer for 4 tabs in the Graphs tab + private CheckboxTableViewer threadViewer; + private CheckboxTableViewer chunksViewer; + private CheckboxTableViewer disksViewer; + private CheckboxTableViewer sysElemsViewer; + + private String lastSelectedEvent = RAM_GRP[0]; + + private SwmtGraph graph; + private GraphForAllEvents allEventsGraph; + + private String selectedEvent; + private CheckboxTableViewer graphedItemsViewer; + private ArrayList graphed = new ArrayList(); + private TabFolder mainTabFolder; + private Label title; + + private Table issues_table; + private Button viewAll_btn;; + + private int ANALYSIS_PAGE = -1; + private int OVERVIEW_PAGE = -1; + private int GRAPHS_PAGE = -1; + private Tree issues_tree; + private MenuItem analyse_menuItem; + private Combo severity_combo; + private Label severity_label; + private IssuesFilter filter; + private IssuesViewer viewer; + private ArrayList analysis_results_obj = new ArrayList(); + + private static final String NO_ISSUES_MSG = "No Critical issues found."; + private static final String GRAPHED_ITEMS_LABEL = "Graphed items"; + private Button advanced_filter_button; + private Button generate_report_btn; + private SashForm graphSash; + + /** + * Creates a multi-page editor. + */ + public SWMTEditor() { + super(); + } + + /** + * Creates overview page of the SWMT Editor. + */ + private void createOverviewPage() { + Composite composite = new Composite(getContainer(), SWT.NONE); + FillLayout layoutF = new FillLayout(); + composite.setLayout(layoutF); + FormToolkit toolkit = new FormToolkit(composite.getDisplay()); + form = toolkit.createScrolledForm(composite); + form.setText("Overview:"); + + TableWrapLayout layout = new TableWrapLayout(); + layout.leftMargin = 10; + layout.rightMargin = 10; + layout.numColumns = 2; + form.getBody().setLayout(layout); + form.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + if(parsedData.getNumberOfCycles() == 1 && parsedData.getLogData()[0].getCycleNumber() != 1) + form.setMessage("This is a delta log file. It may not contain complete information. \nTo get complete information, selected logs must be in consecutive order starting from cycle 1.", IMessageProvider.WARNING); + + Section section = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED); + TableWrapData td = new TableWrapData(TableWrapData.FILL); + td.align = TableWrapData.FILL; + td.grabHorizontal = true; + + section.setLayoutData(td); + section.addExpansionListener(new ExpansionAdapter() { + public void expansionStateChanged(ExpansionEvent e) { + form.reflow(true); + } + }); + section.setText("Properties"); + section.setDescription("This section describes general information about log files"); + Composite sectionClient = toolkit.createComposite(section); + sectionClient.setLayout(new GridLayout()); + toolkit.createLabel(sectionClient, "Number of Cycles : "+ov.noOfcycles); + + if(ov.noOfcycles > 1) + toolkit.createLabel(sectionClient, "Time Period : "+ov.fromTime + " to " + ov.toTime); + else if(ov.noOfcycles == 1){ + toolkit.createLabel(sectionClient, "Time Period : "+ov.fromTime); + } + if(ov.duration >= 60) + toolkit.createLabel(sectionClient, "Time Duration : "+ov.duration + " sec (" + ov.durationString +")"); //$NON-NLS-3$ + else + toolkit.createLabel(sectionClient, "Time Duration : "+ov.duration + " sec"); + section.setClient(sectionClient); + + Section analysisSection = toolkit.createSection(form.getBody(), Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED); + TableWrapData td3 = new TableWrapData(TableWrapData.FILL_GRAB); + td3.rowspan = 3; + td3.grabHorizontal = true; + td3.grabVertical = true; + analysisSection.setLayoutData(td3); + analysisSection.setText("Analysis"); + Composite analysisComp = toolkit.createComposite(analysisSection); + analysisComp.setLayout(new GridLayout(1, false)); + analysisComp.setLayoutData(new GridData(GridData.FILL)); + + toolkit.createLabel(analysisComp, "Top 5 issues:"); + + issues_table = toolkit.createTable(analysisComp, SWT.FULL_SELECTION|SWT.BORDER|SWT.SINGLE); + GridData table_GD = new GridData(GridData.FILL_HORIZONTAL); + //table_GD.heightHint = 200; + issues_table.setLayoutData(table_GD); + TableColumn col1 = new TableColumn(issues_table, SWT.NONE); + col1.setWidth(250); + col1.setText("Item"); + TableColumn col2 = new TableColumn(issues_table, SWT.NONE); + col2.setWidth(200); + col2.setText("Event"); + issues_table.pack(); + issues_table.setHeaderVisible(true); + issues_table.setToolTipText("Double click to analyse..."); + + issues_table.addSelectionListener(this); + + final Menu menuPopup = new Menu(issues_table); + analyse_menuItem = new MenuItem(menuPopup, SWT.CASCADE); + analyse_menuItem.setText("Analyse..."); + analyse_menuItem.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + //Open Analysis tab + setActivePage(ANALYSIS_PAGE); + //If the issues viewer is in filtered state, then make it to show all the issues. + filter.setFilterText(null); + viewer.refresh(); + + //Find the TreeItem which matches the selection. + TreeItem child_toBeSelected = null; + TreeItem parent_toBeExpanded = null; + for(TreeItem parent:issues_tree.getItems()) + { + parent.setExpanded(true); + parent.notifyListeners(SWT.Expand, new Event()); + for(TreeItem child:parent.getItems()) + { + if(child.getText(1).equals(issues_table.getSelection()[0].getText(0)) && child.getText(2).equals(issues_table.getSelection()[0].getText(1))) + { + parent_toBeExpanded = parent; + child_toBeSelected = child; + break; + } + } + } + + //Select the matched Treeitem in viewer. + if(child_toBeSelected!=null && parent_toBeExpanded !=null) + { + issues_tree.showItem(child_toBeSelected); + issues_tree.select(child_toBeSelected); + issues_tree.setFocus(); + } + } + }); + + + issues_table.setMenu(menuPopup); + + issues_table.addMouseListener(new MouseListener(){ + public void mouseDoubleClick(MouseEvent e) { + if(analyse_menuItem.isEnabled()) + analyse_menuItem.notifyListeners(SWT.Selection, new Event()); + } + public void mouseDown(MouseEvent e) { + } + public void mouseUp(MouseEvent e) { + } + }); + issues_table.pack(); + + viewAll_btn = toolkit.createButton(analysisComp, "View all issues...", SWT.PUSH); + GridData viewAll_GD = new GridData(GridData.FILL); + viewAll_GD.horizontalAlignment = GridData.END; + viewAll_btn.setLayoutData(viewAll_GD); + viewAll_btn.addSelectionListener(this); + analysisSection.setClient(analysisComp); + + Section romDetails = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED); + TableWrapData tableData = new TableWrapData(TableWrapData.FILL); + tableData.align = TableWrapData.FILL; + tableData.grabHorizontal = true; + + romDetails.setLayoutData(tableData); + romDetails.addExpansionListener(new ExpansionAdapter() { + public void expansionStateChanged(ExpansionEvent e) { + form.reflow(true); + } + }); + romDetails.setText("ROM Details"); + romDetails.setDescription("This section displays the ROM information from log files"); + Composite romSection = toolkit.createComposite(romDetails); + romSection.setLayout(new GridLayout()); + + CycleData firstCycle = parsedData.getLogData()[0]; + + toolkit.createLabel(romSection, "ROM Checksum : " + firstCycle.getRomCheckSum()); + toolkit.createLabel(romSection, "ROM Version : " + firstCycle.getRomVersion()); + romDetails.setClient(romSection); + + Section section2 = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED); + TableWrapData td2 = new TableWrapData(TableWrapData.FILL); + section2.setLayoutData(td2); + section2.addExpansionListener(new ExpansionAdapter() { + public void expansionStateChanged(ExpansionEvent e) { + form.reflow(true); + } + }); + section2.setText("Export Options"); + section2.setDescription("Specify the export options"); + Composite sectionClient2 = toolkit.createComposite(section2); + sectionClient2.setLayout(new GridLayout(4, false)); + + GridData gd1 = new GridData(); + gd1.horizontalSpan = 4; + allBtn = toolkit.createButton(sectionClient2, "All",SWT.RADIO); + notAllBtn = toolkit.createButton(sectionClient2, "Selected log files",SWT.RADIO); + allBtn.setLayoutData(gd1); + allBtn.setSelection(true); + allBtn.addSelectionListener(this); + + notAllBtn.setLayoutData(gd1); + notAllBtn.addSelectionListener(this); + + toolkit.createLabel(sectionClient2, "From"); + Label fromLabel = new Label(sectionClient2, SWT.NONE); + + toolkit.createLabel(sectionClient2, " To"); + toCombo = new Combo(sectionClient2, SWT.DROP_DOWN|SWT.READ_ONLY); + toCombo.setEnabled(false); + toCombo.addSelectionListener(this); + + Composite exportComp = new Composite(sectionClient2,SWT.NONE); + exportComp.setLayout(new GridLayout()); + GridData exGD = new GridData(); + exGD.horizontalSpan = 4; + exportComp.setLayoutData(exGD); + export = toolkit.createButton(exportComp, "Export as XLS...", SWT.PUSH); + export.addSelectionListener(this); + + section2.setClient(sectionClient2); + + OVERVIEW_PAGE = addPage(composite); + setPageText(OVERVIEW_PAGE, "Overview"); + + + CycleData [] parsed_cycles = parsedData.getLogData(); + + if(parsedData.getNumberOfCycles() == 1) + { + int cycleNo = parsed_cycles[0].getCycleNumber(); + fromLabel.setText(Integer.toString(cycleNo)); + toCombo.add(Integer.toString(cycleNo)); + } + else + { + fromLabel.setText("1"); + for (int i = 1 ; i <= parsed_cycles.length ; i++) + { + toCombo.add(Integer.toString(i)); + } + } + + toCombo.select(parsed_cycles.length -1); + + } + + /** + * Creates Graphs page of the SWMT Editor. + * + */ + private void createGraphsPage() + { + Composite parent = new Composite(getContainer(), SWT.NONE); + parent.setLayout(new FormLayout()); + + Composite titleBar = new Composite(parent, SWT.NONE); + Composite holder = new Composite(parent, SWT.NONE); + + title = new Label(titleBar, SWT.CENTER|SWT.BORDER); + title.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE)); + title.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + Font roman_8 = new Font(parent.getDisplay(), "Arial", 10, SWT.BOLD); + title.setFont(roman_8); + title.setText(""); + + FormData data = new FormData(); + data.left = new FormAttachment(0); + data.right = new FormAttachment(100); + title.setLayoutData(data); + + FormData formData = new FormData(); + formData.top = new FormAttachment(0); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + titleBar.setLayoutData(formData); + titleBar.setLayout(new FormLayout()); + + // FormData for the overall holder composite + formData = new FormData(); + formData.top = new FormAttachment(titleBar); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + holder.setLayoutData(formData); + holder.setLayout(new FormLayout()); + + SashForm graphSash = new SashForm(holder, SWT.VERTICAL|SWT.SMOOTH|SWT.BORDER); + graphSash.SASH_WIDTH = 5; + graphSash.setLayout(new FillLayout()); + + Composite bottomComposite = new SashForm(holder, SWT.VERTICAL); + final Sash acrossSash = new Sash(holder, SWT.HORIZONTAL); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(acrossSash); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + graphSash.setLayoutData(formData); + graphSash.setLayout(new FormLayout()); + + // FormData for bottom composite + formData = new FormData(); + formData.top = new FormAttachment(acrossSash); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + bottomComposite.setLayoutData(formData); + bottomComposite.setLayout(new FormLayout()); + + // FormData for acrossSash + // Put it initially in the middle + formData = new FormData(); + formData.top = new FormAttachment(50); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + acrossSash.setLayoutData(formData); + + final FormData acrossSashData = formData; + final Composite parentFinal = acrossSash.getParent(); + acrossSash.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + if (event.detail != SWT.DRAG) { + acrossSashData.top = new FormAttachment(0, event.y); + parentFinal.layout(); + } + } + }); + graph = new SwmtGraph(graphSash); + allEventsGraph = new GraphForAllEvents(graphSash); + + graph.setInputCyclesData(parsedData); + allEventsGraph.setInputCyclesData(parsedData); + + graph.constructGraphArea(); + + mainTabFolder = new TabFolder(bottomComposite, SWT.NONE); + mainTabFolder.setLayout(new FillLayout(2)); + GridData tabGD=new GridData(GridData.FILL_HORIZONTAL); + mainTabFolder.setLayoutData(tabGD); + mainTabFolder.addSelectionListener(this); + + //Construct Events Tab + constructEventTabsArea(mainTabFolder); + //Construct Graphed Items Tab + TabItem graphedItemsTab = new TabItem(mainTabFolder,SWT.NONE); + graphedItemsTab.setText(GRAPHED_ITEMS_LABEL); + + GraphedItemsHelper graphedTabHelper = new GraphedItemsHelper(); + graphedItemsViewer = graphedTabHelper.constructGraphedItemsViewer(graphedItemsTab, allEventsGraph); + + GRAPHS_PAGE = addPage(parent); + setPageText(GRAPHS_PAGE, " Graphs "); + + if(threads != null) + threadTble.setInput(threads); + if(chunks != null) + chunkTble.setInput(chunks); + if(disks != null) + diskTble.setInput(disks); + + sysinfoTble.setInput(GenericGraph.getGraphableKernels()); + + + + } + + /** + * Creates Anlysis page in the SWMT Editor + * + */ + private void createAnalysisPage() + { + Composite parentComposite = new Composite(getContainer(), SWT.NONE); + parentComposite.setLayout(new FormLayout()); + + Composite titleBar = new Composite(parentComposite, SWT.NONE); + Composite holder = new Composite(parentComposite, SWT.NONE); + + Label graph_title = new Label(titleBar, SWT.CENTER|SWT.BORDER); + graph_title.setBackground(parentComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE)); + graph_title.setForeground(parentComposite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + Font roman_8 = new Font(parentComposite.getDisplay(), "Arial", 10, SWT.BOLD); + graph_title.setFont(roman_8); + graph_title.setText(""); + + FormData formData = new FormData(); + formData.top = new FormAttachment(0); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + titleBar.setLayoutData(formData); + titleBar.setLayout(new FormLayout()); + + FormData data = new FormData(); + data.left = new FormAttachment(0); + data.right = new FormAttachment(100); + graph_title.setLayoutData(data); + + // FormData for the overall holder composite + formData = new FormData(); + formData.top = new FormAttachment(titleBar); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + holder.setLayoutData(formData); + holder.setLayout(new FormLayout()); + + graphSash = new SashForm(holder, SWT.VERTICAL|SWT.SMOOTH|SWT.BORDER); + graphSash.SASH_WIDTH = 5; + graphSash.setLayout(new FillLayout()); + + Composite bottomComposite = new SashForm(holder, SWT.VERTICAL); + final Sash acrossSash = new Sash(holder, SWT.HORIZONTAL); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(acrossSash); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + graphSash.setLayoutData(formData); + graphSash.setLayout(new FormLayout()); + + // FormData for bottom + formData = new FormData(); + formData.top = new FormAttachment(acrossSash); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + bottomComposite.setLayoutData(formData); + bottomComposite.setLayout(new FormLayout()); + + // FormData for acrossSash + // Put it initially in the middle + formData = new FormData(); + formData.top = new FormAttachment(50); + formData.width = 20; + formData.left = new FormAttachment(0); + formData.right = new FormAttachment(100); + acrossSash.setLayoutData(formData); + + final FormData acrossSashData = formData; + final Composite parentFinal = acrossSash.getParent(); + acrossSash.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + if (event.detail != SWT.DRAG) { + acrossSashData.top = new FormAttachment(0, event.y); + parentFinal.layout(); + } + } + }); + + Composite parent = new Composite(bottomComposite, SWT.NONE); + parent.setLayout(new GridLayout(7, false)); + parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label title = new Label(parent, SWT.WRAP); + title.setText("Linear Analysis Results"); + title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + //Action button used for creation of report file. + generate_report_btn = new Button(parent, SWT.PUSH); + generate_report_btn.setText("Generate report..."); + generate_report_btn.setToolTipText("Click here to generate pdf report for the selected issues."); + generate_report_btn.addSelectionListener(this); + + Label separator = new Label(parent, SWT.SEPARATOR); + GridData sepGD = new GridData(); + sepGD.heightHint = 25; + separator.setLayoutData(sepGD); + + Label severity = new Label(parent, SWT.NONE); + severity.setText("Severity:"); + + severity_label = new Label(parent, SWT.WRAP); + severity_label.setText(" "); + GridData d = new GridData(GridData.FILL); + d.heightHint = 20; + severity_label.setLayoutData(d); + + severity_combo = new Combo(parent, SWT.BORDER|SWT.READ_ONLY); + d = new GridData(); + d.widthHint = 100; + severity_combo.setLayoutData(d); + severity_combo.setItems(new String[]{"All", AnalyserConstants.Priority.CRITICAL.name(), AnalyserConstants.Priority.HIGH.name(),AnalyserConstants.Priority.NORMAL.name(), "Custom filter"}); + severity_combo.addSelectionListener(this); + severity_combo.select(0); + severity_combo.setToolTipText("Severity of an issue."); + + //Action button used to launch Custom filter dialog. + advanced_filter_button = new Button(parent, SWT.PUSH); + advanced_filter_button.setText("Set Custom filter..."); + advanced_filter_button.addSelectionListener(this); + advanced_filter_button.setToolTipText("Advanced settings to filter issues below."); + advanced_filter_button.setEnabled(false); + + issues_tree = new Tree(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.CHECK); + GridData gd = new GridData(GridData.FILL_BOTH); + gd.horizontalSpan = 7; + gd.grabExcessVerticalSpace = true; + issues_tree.addSelectionListener(this); + + LinearIssuesGraph issue_graph = new LinearIssuesGraph(graphSash); + issue_graph.setLogData(parsedData); + + //Creates issues viewer. + viewer = new IssuesViewer(issues_tree, issue_graph); + viewer.createIssuesViewerAndGraph(); + viewer.setContentProvider(new IssuesTreeContentProvider()); + viewer.setLabelProvider(new IssuesTreeLabelProvider()); + filter = new IssuesFilter(); + viewer.addFilter(filter); + + ANALYSIS_PAGE = addPage(parentComposite); + setPageText(ANALYSIS_PAGE, " Analysis "); + + SWMTAnalysisRunnable start_analysis = new SWMTAnalysisRunnable(); + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); + Shell shell = win != null ? win.getShell() : null; + try { + new ProgressMonitorDialog(shell).run(true, true, start_analysis); + } catch (InvocationTargetException err) { + err.printStackTrace(); + } catch (InterruptedException err) { + err.printStackTrace(); + } + viewer.setInput(analysis_results_obj); + + //Set top 5 issues in the overview tab + setTopIssues(analysis_results_obj); + + issues_tree.setFocus(); + } + + /** + * Construts UI controls under Events Tab area. + * @param mainTabFolder represents parent folder + */ + private void constructEventTabsArea(TabFolder mainTabFolder) + { + eventsTab = new TabItem(mainTabFolder,SWT.NONE); + eventsTab.setText(" Events "); + + //Events Tab => events list and 4 inner tabs + SashForm form=new SashForm(mainTabFolder, SWT.BORDER|SWT.HORIZONTAL|SWT.SMOOTH); + form.setLayout(new GridLayout()); + + Composite eventC = new Composite(form, SWT.NONE); + eventC.setLayout(new GridLayout(1,false)); + eventC.setLayoutData(new GridData(GridData.FILL_BOTH)); + + eventsCombo = new Combo(eventC, SWT.BORDER|SWT.V_SCROLL | SWT.READ_ONLY); + + GridData comboGD = new GridData(GridData.FILL_HORIZONTAL); + eventsCombo.setLayoutData(comboGD); + for(CATEGORIES value : CATEGORIES.values()) + eventsCombo.add(value.toString()); + eventsCombo.addSelectionListener(this); + + + eventList = new List(eventC, SWT.BORDER|SWT.SINGLE|SWT.V_SCROLL|SWT.H_SCROLL); + GridData listGD = new GridData(GridData.FILL_BOTH); + listGD.grabExcessVerticalSpace = true; + eventList.setLayoutData(listGD); + eventList.addSelectionListener(this); + + innerTabFolder = new TabFolder(form, SWT.NONE); + innerTabFolder.setLayout(new GridLayout()); + GridData innertabGD = new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL); + innertabGD.verticalSpan = 2; + innerTabFolder.setLayoutData(innertabGD); + innerTabFolder.addSelectionListener(this); + + threadTab = new TabItem(innerTabFolder,SWT.NONE); + threadTab.setText(" Threads "); + + Composite compositeThrd = new Composite(innerTabFolder, SWT.NONE); + compositeThrd.setLayout(new GridLayout(1, true)); + threadTble = new FilterTextTable(this, compositeThrd, FilterTextTable.THREADS_TITLE); + this.threadViewer = threadTble.getTableViewer(); + + GridData table_layout_data = new GridData(GridData.FILL_BOTH); + table_layout_data.grabExcessVerticalSpace = true; + + compositeThrd.setLayoutData(table_layout_data); + threadTab.setControl(compositeThrd); + + chunksTab = new TabItem(innerTabFolder,SWT.NONE); + chunksTab.setText(" Chunks "); + + Composite compositeChnk = new Composite(innerTabFolder, SWT.NONE); + compositeChnk.setLayout(new GridLayout(1, true)); + chunkTble = new FilterTextTable(this, compositeChnk, FilterTextTable.CHUNKS_TITLE); + compositeChnk.setLayoutData(table_layout_data); + chunksTab.setControl(compositeChnk); + this.chunksViewer = chunkTble.getTableViewer(); + + diskTab = new TabItem(innerTabFolder,SWT.NONE); + diskTab.setText(" Disks "); + + Composite compositeDisk = new Composite(innerTabFolder, SWT.NONE); + compositeDisk.setLayout(new GridLayout(1, false)); + compositeDisk.setLayoutData(table_layout_data); + diskTble = new FilterTextTable(this, compositeDisk, FilterTextTable.DISKS_TITLE); + diskTab.setControl(compositeDisk); + this.disksViewer = diskTble.getTableViewer(); + + sysInfoTab = new TabItem(innerTabFolder,SWT.NONE); + sysInfoTab.setText(" System Data "); + + Composite compositeSysinfo = new Composite(innerTabFolder, SWT.NONE); + compositeSysinfo.setLayout(new GridLayout(1, false)); + compositeSysinfo.setLayoutData(table_layout_data); + sysinfoTble = new FilterTextTable(this, compositeSysinfo, FilterTextTable.SYSTEM_DATA_TITLE); + sysInfoTab.setControl(compositeSysinfo); + this.sysElemsViewer = sysinfoTble.getTableViewer(); + + eventsCombo.select(0); + eventsCombo.notifyListeners(SWT.Selection, new Event()); + + form.setWeights(new int[] {30,70}); + form.SASH_WIDTH = 1; + eventsTab.setControl(form); + } + + /** + * Creates the pages of the multi-page editor. + */ + protected void createPages() { + + if(parsedData == null || parsedData.getNumberOfCycles() == 0) + return; + + createOverviewPage(); + + if(parsedData.getNumberOfCycles() > 1) + { + createGraphsPage(); + createAnalysisPage(); + } + else + { + TableItem no_issues_item = new TableItem(issues_table,SWT.NONE); + no_issues_item.setText(NO_ISSUES_MSG); + viewAll_btn.setEnabled(false); + } + } + + /** + * The method picks up the top 5 critical issues from the given list of issues + * and displays them in the overview page. + * @param issues_results + */ + public void setTopIssues(ArrayList issues_results) + { + if(issues_results.size() == 0) + { + TableItem item = new TableItem(issues_table,SWT.NONE); + item.setText(NO_ISSUES_MSG); + return; + } + + ArrayList critical_issues = new ArrayList(); + + for(Object obj:issues_results) + { + if(obj instanceof ResultsParentNodes) + { + ResultsParentNodes parent = (ResultsParentNodes)obj; + Object[] children = parent.getChildren(); + + for(Object issue:children) + { + if(issue instanceof ResultElements) + { + ResultElements issue_elem = (ResultElements)(issue); + if(issue_elem.getPriority() == AnalyserConstants.Priority.CRITICAL) + critical_issues.add(issue_elem); + } + } + } + } + + if(critical_issues.size() == 0) + { + TableItem item = new TableItem(issues_table,SWT.NONE); + item.setText(NO_ISSUES_MSG); + return; + } + else + { + Collections.sort(critical_issues); + + for(int index = critical_issues.size()-1, i=1; i <=5;i++,index--) + { + if(index < 0) + break; + + ResultElements temp = critical_issues.get(index); + TableItem item = new TableItem(issues_table,SWT.NONE); + item.setText(new String[]{temp.getItemName(),temp.getEvent()}); + } + } + + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.part.MultiPageEditorPart#dispose() + */ + public void dispose() { + super.dispose(); + } + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor) + */ + public void doSave(IProgressMonitor monitor) { + getEditor(0).doSave(monitor); + } + /** + * Saves the multi-page editor's document as another file. + * Also updates the text for page 0's tab, and updates this multi-page editor's input + * to correspond to the nested editor's. + * @see org.eclipse.ui.part.EditorPart#doSaveAs() + */ + public void doSaveAs() { + IEditorPart editor = getEditor(0); + editor.doSaveAs(); + setPageText(0, editor.getTitle()); + setInput(editor.getEditorInput()); + } + + /** + * Go to marker + * @see IDE#gotoMarker(IEditorPart, IMarker) + * @param marker + */ + public void gotoMarker(IMarker marker) { + setActivePage(0); + IDE.gotoMarker(getEditor(0), marker); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.MultiPageEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput) + */ + public void init(IEditorSite site, IEditorInput editorInput) + throws PartInitException { + if (!(editorInput instanceof SWMTEditorInput)) + throw new PartInitException("Invalid Input: Must be SWMTEditorInput"); + parsedData = ((SWMTEditorInput)editorInput).getParsedData(); + ov = ((SWMTEditorInput)editorInput).getOverview(); + + SWMTLogReaderUtils util = new SWMTLogReaderUtils(); + + threads = util.getAllThreadNames(parsedData); + if(threads != null) + Collections.sort(threads); + + chunks = util.getAllGlobalChunkNames(parsedData); + if(chunks != null) + Collections.sort(chunks); + + nonHeapChunks = util.getAllNonHeapChunkNames(parsedData); + if(nonHeapChunks != null) + Collections.sort(nonHeapChunks); + + disks = util.getAllDiskNames(parsedData); + if(disks != null) + Collections.sort(disks); + + super.init(site, editorInput); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed() + */ + public boolean isSaveAsAllowed() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + + //When Export button is selected, data from given log files + //will be exported to an excel file. + if(e.widget == export) + { + FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); + dlg.setFilterExtensions(new String[]{"*.xls"}); + String fileName = dlg.open(); + if(fileName==null) + return; + + SWMTExcelCreationRunnableWithProcess process = new SWMTExcelCreationRunnableWithProcess(fileName, parsedData, toCombo.getSelectionIndex()+1); + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); + Shell shell = win != null ? win.getShell() : null; + try { + new ProgressMonitorDialog(shell).run(true, true, process); + } catch (InvocationTargetException err) { + err.printStackTrace(); + } catch (InterruptedException err) { + err.printStackTrace(); + } + } + else if(e.widget == allBtn) + { + toCombo.setEnabled(false); + } + else if(e.widget == notAllBtn) + { + toCombo.setEnabled(true); + } + else if(e.widget == viewAll_btn) + { + this.setActivePage(ANALYSIS_PAGE); + } + /* + * When Events list selection is changed, all previous selections should be cleared + * and they should be moved to Graphed items tab. + * Also, listeners of enabled tables should be notified. + */ + else if(e.widget == eventList) + { + selectedEvent = eventList.getSelection()[0]; + title.setText(selectedEvent); + updateGraphedItemsList(lastSelectedEvent); + + if(!selectedEvent.equals(lastSelectedEvent)) + { + chunkTble.cancelSelectionList(); + threadTble.cancelSelectionList(); + diskTble.cancelSelectionList(); + sysinfoTble.cancelSelectionList(); + } + + if(!selectedEvent.equals(lastSelectedEvent) && graph != null) + graph.clearGraph(); + + if(Arrays.asList(RAM_GRP).contains(selectedEvent)) + { + threadTble.setEnabled(false); + chunkTble.setEnabled(false); + diskTble.setEnabled(false); + sysinfoTble.setEnabled(false); + + DisksGraph diskGraph = new DisksGraph(); + GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent); + diskGraph.setEvent(eventType); + diskGraph.setCyclesData(parsedData); + + if(graph != null) + graph.redraw(diskGraph); + } + else + { + if(Arrays.asList(CHUNKS_GRP).contains(selectedEvent)) + { + if(Arrays.asList(CHUNKS_GRP).indexOf(selectedEvent)==0 && !selectedEvent.equals(lastSelectedEvent)) + chunkTble.setInput(chunks); + else if(Arrays.asList(CHUNKS_GRP).indexOf(selectedEvent)==1 && !selectedEvent.equals(lastSelectedEvent)) + chunkTble.setInput(nonHeapChunks); + innerTabFolder.setSelection(chunksTab); + + CheckStateChangedEvent event = new CheckStateChangedEvent(chunksViewer, null, false); + + if(chunkTble.getCheckStateListener() != null) + chunkTble.getCheckStateListener().checkStateChanged(event); + } + else if(Arrays.asList(HEAP_GRP).contains(selectedEvent) || Arrays.asList(FILES_GRP).contains(selectedEvent) || Arrays.asList(HPAS_GRP).contains(selectedEvent)) + { + innerTabFolder.setSelection(threadTab); + + CheckStateChangedEvent event = new CheckStateChangedEvent(threadViewer, null, false); + if(threadTble.getCheckStateListener() != null) + threadTble.getCheckStateListener().checkStateChanged(event); + } + else if(Arrays.asList(DISK_GRP).contains(selectedEvent)) + { + innerTabFolder.setSelection(diskTab); + + CheckStateChangedEvent event = new CheckStateChangedEvent(disksViewer, null, false); + if(diskTble.getCheckStateListener() != null) + diskTble.getCheckStateListener().checkStateChanged(event); + } + else if(Arrays.asList(SYSINFO_GRP).contains(selectedEvent)) + { + innerTabFolder.setSelection(sysInfoTab); + + CheckStateChangedEvent event = new CheckStateChangedEvent(sysElemsViewer, null, false); + + if(sysinfoTble.getCheckStateListener() != null) + sysinfoTble.getCheckStateListener().checkStateChanged(event); + } + + threadTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==threadTab); + chunkTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==chunksTab); + diskTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==diskTab); + sysinfoTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==sysInfoTab); + + } + + lastSelectedEvent = selectedEvent; + } + //Events list will be modified based on the selection of + //event category from the drop down box. + else if(e.widget == eventsCombo) + { + eventList.removeAll(); + CATEGORIES index = CATEGORIES.valueOf(eventsCombo.getText()); + switch(index) + { + case All_events: + eventList.setItems(ALL_GRP); + break; + case Chunks: + eventList.setItems(CHUNKS_GRP); + break; + case Disk: + eventList.setItems(DISK_GRP); + break; + case Files: + eventList.setItems(FILES_GRP); + break; + case Heap: + eventList.setItems(HEAP_GRP); + break; + case HPAS: + eventList.setItems(HPAS_GRP); + break; + case RAM: + eventList.setItems(RAM_GRP); + break; + case System_info: + eventList.setItems(SYSINFO_GRP); + break; + } + eventList.select(0); + + if(eventList.getItemCount() > 0) + { + eventList.notifyListeners(SWT.Selection, new Event()); + } + } + else if(e.widget == mainTabFolder && mainTabFolder.getSelectionIndex() != -1 && + mainTabFolder.getSelection()[0].getText().trim().equalsIgnoreCase(GRAPHED_ITEMS_LABEL)) + { + selectedEvent = eventList.getSelection()[0]; + updateGraphedItemsList(selectedEvent); + + title.setText("Graphed Items"); + + Object [] checkedElems = graphedItemsViewer.getCheckedElements(); + ArrayList selectedItems = new ArrayList(); + + for(Object obj:checkedElems) + { + GraphedItemsInput graphInput = (GraphedItemsInput)obj; + selectedItems.add(graphInput); + } + + allEventsGraph.setGraphedItemsInput(selectedItems); + allEventsGraph.constructGraphArea(); + + } + else if(e.widget == mainTabFolder && mainTabFolder.getSelectionIndex() != -1 && mainTabFolder.getSelection()[0] == eventsTab) + { + if(graphedItemsViewer.getInput() == null) + { + graphed.clear(); + } + graph.constructGraphArea(); + + if(eventList.getSelectionIndex() != -1){ + title.setText(eventList.getItem(eventList.getSelectionIndex())); + eventList.notifyListeners(SWT.Selection, new Event()); + } + else + title.setText(""); + + } + + //Issues list gets modified based on the selection of Severity + //from the drop down box. + else if(e.widget == severity_combo) + { + advanced_filter_button.setEnabled(false); + filter.setAdvancedSearchOptions(null); + Image img = null; + String icon_name = ""; + switch(severity_combo.getSelectionIndex()) + { + case 1: + icon_name = "\\red.png"; + filter.setFilterText(AnalyserConstants.Priority.CRITICAL.name()); + break; + case 2: + icon_name = "\\yellow.png"; + filter.setFilterText(AnalyserConstants.Priority.HIGH.name()); + break; + case 3: + icon_name = "\\green.png"; + filter.setFilterText(AnalyserConstants.Priority.NORMAL.name()); + break; + case 4: + advanced_filter_button.setEnabled(true); + default: + icon_name = null; + filter.setFilterText(null); + break; + } + if(icon_name!=null) + { + try { + img = new Image( Display.getCurrent(), SwmtAnalyserPlugin.getPluginInstallPath() + "\\icons" + icon_name); + } catch (RuntimeException e1) { + e1.printStackTrace(); + } + } + severity_label.setImage(img); + issues_tree.setFocus(); + viewer.refresh(); + } + else if(e.widget == issues_table) + { + analyse_menuItem.setEnabled(!issues_table.getSelection()[0].getText(0).startsWith(NO_ISSUES_MSG)); + } + else if(e.widget == advanced_filter_button) + { + AdvancedFilterDialog dlg = new AdvancedFilterDialog(Display.getCurrent().getActiveShell()); + int status = dlg.open(); + if(status == Dialog.OK) + { + FilterInput input = dlg.getFilterOptions(); + filter.setAdvancedSearchOptions(input); + issues_tree.setFocus(); + viewer.refresh(); + } + } + else if(e.widget == generate_report_btn) + { + //Save graph in temporary location + GC gc = new GC(graphSash); + Image image = new Image(Display.getCurrent(), graphSash.getClientArea().width, graphSash.getClientArea().height); + graphSash.setFocus(); + gc.copyArea(image, 0, 0); + gc.dispose(); + ImageData data = image.getImageData(); + ImageLoader loader = new ImageLoader(); + loader.data = new ImageData[] {data}; + loader.save(SwmtAnalyserPlugin.getPluginInstallPath()+"\\swmt_graph.bmp", SWT.IMAGE_BMP); + image.dispose(); + + // Now open the wizard + Runnable showWizardRunnable = new Runnable(){ + public void run(){ + WizardDialog wizDialog; + ReportGenerationWizard wiz = new ReportGenerationWizard(ov, parsedData.getLogData()[0].getRomCheckSum(), parsedData.getLogData()[0].getRomVersion(), issues_tree); + wizDialog = new WizardDialog(Display.getCurrent().getActiveShell(), wiz); + wizDialog.create(); + wizDialog.getShell().setSize(400, 500); + wizDialog.addPageChangedListener(wiz); + wizDialog.open(); + } + }; + Display.getDefault().asyncExec(showWizardRunnable); + } + } + + /** + * SWMT specific runnable process for creating excel. + * + */ + private class SWMTExcelCreationRunnableWithProcess implements IRunnableWithProgress + { + private String fileName; + private CycleData [] data = new CycleData [0]; + private int exportFilesNo; + private OverviewData ovData; + public SWMTExcelCreationRunnableWithProcess(String fileName, ParsedData parsedData,int exportFiles) { + this.data = parsedData.getLogData(); + this.fileName = fileName; + this.exportFilesNo = exportFiles; + } + + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + createExcel(monitor); + } + + private void createExcel(IProgressMonitor monitor) + { + monitor.beginTask("Parsing log files...", 10); + ExcelCreator creator = new ExcelCreator(fileName); + ovData = (new SWMTLogReaderUtils()).getOverviewInformationFromCyclesData(data, this.exportFilesNo); + creator.setOverviewPageInput(ovData); + + ArrayList exportedCycles = new ArrayList(); + + if(this.exportFilesNo >= 255) + { + int extras = this.exportFilesNo - 254; + ArrayList series = new ArrayList(extras); + + if(extras ==1) + { + series.add(this.exportFilesNo/2); + creator.setSkipFileConstant(series); + } + else + { + int temp = this.exportFilesNo; + while(series.size()!=extras) + { + temp = temp/2; + for(int i=2; i threadNames = new ArrayList(); + ArrayList threadColors = new ArrayList(); + + for(Object obj: checkedElements) + { + if(obj instanceof TableViewerInputObject) + { + TableViewerInputObject checkedItem = (TableViewerInputObject)obj; + + threadNames.add(checkedItem.getName()); + threadColors.add(checkedItem.getColor()); + } + } + + //Graph class will be informed about the selected event and selected threads. + ThreadsGraph thGraph = new ThreadsGraph(); + GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent); + thGraph.setEvent(eventType); + thGraph.setUserSelectedItems(threadNames); + thGraph.setCyclesData(parsedData); + thGraph.setColors(threadColors); + + graph.redraw(thGraph); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifyChunksSelection() + */ + public void notifyChunksSelection() + { + Object [] checkedElements = this.chunksViewer.getCheckedElements(); + + ArrayList chunkNames = new ArrayList(); + ArrayList chunkColors = new ArrayList(); + + for(Object obj: checkedElements) + { + if(obj instanceof TableViewerInputObject) + { + TableViewerInputObject checkedItem = (TableViewerInputObject)obj; + + chunkNames.add(checkedItem.getName()); + chunkColors.add(checkedItem.getColor()); + } + } + + //Graph class will be informed about the selected event and selected chunks. + ChunksGraph chnkGraph = new ChunksGraph(); + GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent); + chnkGraph.setEvent(eventType); + chnkGraph.setUserSelectedItems(chunkNames); + chnkGraph.setCyclesData(parsedData); + chnkGraph.setColors(chunkColors); + + graph.redraw(chnkGraph); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifyDisksSelection() + */ + public void notifyDisksSelection() + { + Object [] checkedElements = this.disksViewer.getCheckedElements(); + + ArrayList diskNames = new ArrayList(); + ArrayList diskColors = new ArrayList(); + + for(Object obj: checkedElements) + { + if(obj instanceof TableViewerInputObject) + { + TableViewerInputObject checkedItem = (TableViewerInputObject)obj; + + diskNames.add(checkedItem.getName()); + diskColors.add(checkedItem.getColor()); + } + } + //Graph class will be informed about the selected event and selected disks. + DisksGraph diskGraph = new DisksGraph(); + GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent); + diskGraph.setEvent(eventType); + diskGraph.setUserSelectedItems(diskNames); + diskGraph.setCyclesData(parsedData); + diskGraph.setColors(diskColors); + + this.setGraphTitle(selectedEvent); + graph.redraw(diskGraph); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifySysElementsSelection() + */ + public void notifySysElementsSelection() + { + Object [] checkedElements = this.sysElemsViewer.getCheckedElements(); + + ArrayList sysElemNames = new ArrayList(); + ArrayList sysElemColors = new ArrayList(); + + for(Object obj: checkedElements) + { + if(obj instanceof TableViewerInputObject) + { + TableViewerInputObject checkedItem = (TableViewerInputObject)obj; + + sysElemNames.add(checkedItem.getName()); + sysElemColors.add(checkedItem.getColor()); + } + } + + //Graph class will be informed about the selected event and selected system elements. + SystemDataGraph sysDataGraph = new SystemDataGraph(); + GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent); + sysDataGraph.setEvent(eventType); + sysDataGraph.setUserSelectedItems(sysElemNames); + sysDataGraph.setCyclesData(parsedData); + sysDataGraph.setColors(sysElemColors); + + graph.redraw(sysDataGraph); + } + + /** + * Changes the graph title with the given name + * @param name graph name to be set + */ + private void setGraphTitle(String name) + { + if(this.title != null) + title.setText(name); + } + + /** + * WHen Graphed items tab is selected, the items selected in the events tab will be moved + * to Graphed items tab. + * @param event + */ + public void updateGraphedItemsList(String event) + { + if(threadTble.getEnabled()) + { + Iterator> itr = threadTble.checked.entrySet().iterator(); + while(itr.hasNext()) + { + Entry entry = itr.next(); + GraphedItemsInput item = new GraphedItemsInput(); + graph.storeClearedEventValues(entry.getKey(), allEventsGraph); + + item.setName(entry.getKey()); + item.setEvent(event); + item.setColor(entry.getValue()); + item.setType("Thread"); + if(!checkItemInTheList(item,graphed)) + graphed.add(item); + } + } + else if(chunkTble.getEnabled()) + { + Iterator> itr = chunkTble.checked.entrySet().iterator(); + while(itr.hasNext()) + { + Entry entry = itr.next(); + GraphedItemsInput item = new GraphedItemsInput(); + graph.storeClearedEventValues(entry.getKey(), allEventsGraph); + + item.setName(entry.getKey()); + item.setColor(entry.getValue()); + item.setEvent(event); + item.setType("Chunk"); + if(!checkItemInTheList(item,graphed)) + graphed.add(item); + } + } + else if(diskTble.getEnabled()) + { + Iterator> itr = diskTble.checked.entrySet().iterator(); + while(itr.hasNext()) + { + Entry entry = itr.next(); + GraphedItemsInput item = new GraphedItemsInput(); + graph.storeClearedEventValues(entry.getKey(), allEventsGraph); + + item.setName(entry.getKey()); + item.setColor(entry.getValue()); + item.setEvent(event); + item.setType("Disk"); + if(!checkItemInTheList(item,graphed)) + graphed.add(item); + } + } + else if(sysinfoTble.getEnabled()) + { + Iterator> itr = sysinfoTble.checked.entrySet().iterator(); + while(itr.hasNext()) + { + Entry entry = itr.next(); + GraphedItemsInput item = new GraphedItemsInput(); + graph.storeClearedEventValues(entry.getKey(), allEventsGraph); + + item.setName(entry.getKey()); + item.setColor(entry.getValue()); + item.setEvent(event); + item.setType("System Data"); + if(!checkItemInTheList(item,graphed)) + graphed.add(item); + } + } + else if(Arrays.asList(RAM_GRP).contains(event)) + { + GraphedItemsInput item = new GraphedItemsInput(); + graph.storeClearedEventValues(event, allEventsGraph); + + item.setName(event); + item.setEvent(event); + item.setType("Memory"); + if(!checkItemInTheList(item,graphed)) + graphed.add(item); + } + + if(graphed.size()>0) + { + graphedItemsViewer.setInput(graphed); + graphedItemsViewer.setAllChecked(true); + for(Object obj : graphedItemsViewer.getCheckedElements()) + { + GraphedItemsInput item = (GraphedItemsInput)obj; + if(item.getColor() == null) + item.setColor(getRandomColor()); + graphedItemsViewer.update(item, null); + } + } + } + + /** + * The given item from the given list is checked. + * @param item + * @param list + * @return + */ + public boolean checkItemInTheList(GraphedItemsInput item, ArrayList list) + { + for(GraphedItemsInput obj: list) + { + if(item.getEvent().equals(obj.getEvent()) && item.getName().equals(obj.getName()) && item.getType().equals(obj.getType())) + return true; + } + return false; + } + + /** + * Generates random color. + * @return a random color + */ + public Color getRandomColor() + { + Random rand = new Random(); + int r = rand.nextInt(255); + int g = rand.nextInt(255); + int b = rand.nextInt(255); + return new Color(Display.getCurrent(), r, g,b); + } + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditorInput.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditorInput.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; + +/** + * SWMT Analyser specific input to the SWMT Editor. + * + */ +public class SWMTEditorInput implements IEditorInput { + + private ParsedData parsedData = new ParsedData(); + private OverviewData overview = new OverviewData(); + + /** + * Get parsed data + * @return parsed data + */ + public ParsedData getParsedData() { + return parsedData; + } + /** + * Set parsed data + * @param parsedData + */ + public void setParsedData(ParsedData parsedData) { + this.parsedData = parsedData; + } + /** + * Get overview + * @return overview + */ + public OverviewData getOverview() { + return overview; + } + /** + * Set overview + * @param overview + */ + public void setOverview(OverviewData overview) { + this.overview = overview; + } + /** + * Constructor + * @param parsedData + * @param ov + */ + public SWMTEditorInput(ParsedData parsedData, OverviewData ov) { + this.parsedData = parsedData; + this.overview = ov; + } + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#exists() + */ + public boolean exists() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + public ImageDescriptor getImageDescriptor() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + public String getName() { + return "Result of " + parsedData.getNumberOfCycles() + " SWMT logs"; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + public IPersistableElement getPersistable() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + public String getToolTipText() { + return "Result of " + parsedData.getNumberOfCycles()+" SWMT Log files"; + } + + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + return null; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object o) { + if(!(o instanceof SWMTEditorInput)) + return false; + + SWMTEditorInput input = (SWMTEditorInput)o; + + CycleData[] currentLogData = this.parsedData.getLogData(); + CycleData[] givenLogData = input.parsedData.getLogData(); + + if (this.parsedData.getNumberOfCycles() != input.parsedData.getNumberOfCycles()) + return false; + else if(currentLogData == null || givenLogData== null) + return false; + else + { + for (int i=0; i items = new ArrayList(); + for(String name: table.input) + { + TableViewerInputObject obj = new TableViewerInputObject(name, null); + items.add(obj); + } + return items.toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableTextFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableTextFilter.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * Filter class for the all tables + * + */ +public class TableTextFilter extends ViewerFilter { + + private String filterText = ""; + private int columnIndex = 0; + private int filterTypeIndex = 0; + + /** + * Constructor + * @param columnIndex + */ + public TableTextFilter(int columnIndex) { + super(); + this.columnIndex = columnIndex; + } + + /** + * Get filter text + * @return filter text + */ + public String getFilterText() { + return filterText; + } + + /** + * Get column index + * @return column index + */ + public int getColumnIndex() { + return columnIndex; + } + + /** + * Set column index + * @param columnIndex + */ + public void setColumnIndex(int columnIndex) { + this.columnIndex = columnIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (filterText.length() > 0) { + String name = ((ITableLabelProvider)((TableViewer) viewer).getLabelProvider()).getColumnText(element, columnIndex); + if(filterTypeIndex == 0){ + return (name.toLowerCase().startsWith(this.filterText.toLowerCase())); + } + else{ + return (name.toLowerCase().indexOf(this.filterText.toLowerCase()) > -1); + } + } else + return true; + } + + /** + * Set filter text + * @param filterText + */ + public void setFilterText(String filterText) { + this.filterText = filterText; + } + + /** + * Set filter type index + * @param index + */ + public void setFilterTypeIndex(int index) { + this.filterTypeIndex = index; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableViewerInputObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableViewerInputObject.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.editors; + +import org.eclipse.swt.graphics.Color; + +/** + * Input object for 4 tables in events tab + * + */ +public class TableViewerInputObject { + private Color color; + private String name; + + /** + * Constructor + * @param name + * @param color + */ + public TableViewerInputObject(String name, Color color) { + this.color = color; + this.name = name; + } + /** + * Get color + * @return color + */ + public Color getColor() { + return color; + } + /** + * Set color + * @param color + */ + public void setColor(Color color) { + this.color = color; + } + /** + * Get name + * @return name + */ + public String getName() { + return name; + } + /** + * Set name + * @param name + */ + public void setName(String name) { + this.name = name; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/exception/SwmtFormatException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/exception/SwmtFormatException.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.exception; + +/** + * SWMT Analyser specific exception. + */ +public class SwmtFormatException extends Exception { + + /** + * Default serial ID + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + * @param msg + */ + public SwmtFormatException(String msg) + { + super(msg); + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/ExcelCreator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/ExcelCreator.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,2148 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.model; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFFont; +import org.apache.poi.hssf.usermodel.HSSFRichTextString; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.ChunksData; +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.DiskOverview; +import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.data.SystemData; +import com.nokia.s60tools.swmtanalyser.data.ThreadData; +import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Creates Excel when log files exported. + * + */ +public class ExcelCreator { + + private String fileName; + private FileOutputStream out; + + private HSSFWorkbook wb; + private OverviewData ovData; + private ArrayList constants = new ArrayList(); + + private Map styles; + private ParsedData logData; + private Map> heapData = new HashMap> (); + private Map> glodData = new HashMap> (); + private Map> chunkData = new HashMap> (); + private Map deltaData = new HashMap (); + private Map glodDeltaData = new HashMap (); + private Map chunkDeltaData = new HashMap (); + private ArrayList heapThreads; + private ArrayList glodChunks; + private ArrayList nonHeapChunks; + + private long totalHeapSizeChange =0; + private long totalFreeCellChange =0; + private long totalAllocCellChange =0; + private long totalFreeSpaceChange =0; + private long totalAllocSpaceChange =0; + private long totalSlackSpaceChange =0; + private long totalFilesChange =0; + private long totalHandlesChange =0; + private int j = 0; + + private static final String NOT_AVAILABLE = "N/A"; + + /** + * Construction + * @param fileName + */ + public ExcelCreator(String fileName) { + //create a new workbook + wb = new HSSFWorkbook(); + this.fileName = fileName; + } + + /** + * Set overview data + * @param ovdata + */ + public void setOverviewPageInput(OverviewData ovdata) + { + this.ovData = ovdata; + } + + /** + * Set all the parsed data of log files. + * @param cyclesData + */ + public void setInputCyclesData(ParsedData cyclesData) + { + this.logData = cyclesData; + } + + /** + * The cycle numbers to be skipped when there are more than 254 cycles. + * @param constants + */ + public void setSkipFileConstant(ArrayList constants) + { + this.constants = constants; + } + + private boolean updateMonitor(IProgressMonitor monitor, String message) + { + if(monitor!=null) + monitor.subTask(message); + if(monitor.isCanceled()) + { + monitor.done(); + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + return true; + } + + /** + * Create a excel document + * @param monitor + * @return true if document was created successfully false otherwise. + */ + public boolean createExcel(IProgressMonitor monitor) + { + + File file = new File(fileName); + + if(file.exists() && !file.delete()){ + Runnable p = new Runnable(){ + public void run() { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", fileName + "file already exists and could not be deleted.\nPlease close it if open and try again."); + } + }; + Display.getDefault().asyncExec(p); + return false; + } + + try { + out = new FileOutputStream(fileName); + } catch (FileNotFoundException e) { + Runnable p = new Runnable(){ + public void run() { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Error in creating file " + fileName); + } + }; + Display.getDefault().asyncExec(p); + return false; + + } + + styles = createStyles(wb); + + SWMTLogReaderUtils utilsObj = new SWMTLogReaderUtils(); + + readGlobalDataFromAllCycles(glodData, logData); + getFieldDifferencesForAllGlodChunks(glodDeltaData, logData); + + readChunkDataFromAllCycles(chunkData, logData); + getFieldDifferencesForAllChunks(chunkDeltaData, logData); + + readHeapDataFromAllCycles(heapData, logData); + getFieldDifferencesForAllThreads(deltaData, logData); + + heapThreads = utilsObj.getAllHeapThreads(logData); + Collections.sort(heapThreads); + + if(!updateMonitor(monitor, "Creating overview sheet...")) + return false; + createOverViewTab(); + + if(!updateMonitor(monitor, "Creating disk memory sheet...")) + return false; + createDiskVariationSheet(); + + if(!updateMonitor(monitor, "Creating global chunks sheet...")) + return false; + createGlobalChunksSheet(); + + if(!updateMonitor(monitor, "Creating non heap chunks sheet...")) + return false; + createNonHeapChunkSheet(); + + if(!updateMonitor(monitor, "Creating heap size sheet...")) + return false; + createHeapSizeTab(); + + if(!updateMonitor(monitor, "Creating heap allocated space sheet...")) + return false; + createHeapAllocSpaceTab(); + + if(!updateMonitor(monitor, "Creating heap free space sheet...")) + return false; + createHeapFreeSpaceTab(); + + if(!updateMonitor(monitor, "Creating allocated cells sheet...")) + return false; + createAllocatedCellsTab(); + + if(!updateMonitor(monitor, "Creating free cells sheet...")) + return false; + createFreeCellsTab(); + + if(!updateMonitor(monitor, "Creating free slack sheet...")) + return false; + createFreeSlackTab(); + + if(!updateMonitor(monitor, "Creating largest allocated cells sheet...")) + return false; + createLargestAllocSizeTab(); + + if(!updateMonitor(monitor, "Creating largest free size sheet...")) + return false; + createLargestFreeSizeTab(); + + if(!updateMonitor(monitor, "Creating window groups sheet...")) + return false; + createWindowGroupSheet(); + + // write the workbook to the output stream + // close our file (don't blow out our file handles + try { + wb.write(out); + out.close(); + } catch (IOException err) { + err.printStackTrace(); + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + return true; + } + + private boolean createOverViewTab() + { + //create a new sheet + HSSFSheet sheet = wb.createSheet(); + // declare a row object reference + HSSFRow row = null; + // declare a cell object reference + HSSFCell cell = null; + + //set the sheet name in Unicode + wb.setSheetName(0, "Overview"); + + row=sheet.createRow(0); + //r.setHeight((short)500); + + cell= row.createCell(0); + cell.setCellStyle(styles.get("header")); + cell.setCellValue(new HSSFRichTextString("Overview")); + + row=sheet.createRow(1); + cell=row.createCell(0); + cell.setCellValue(new HSSFRichTextString("Number of Cycles")); + cell=row.createCell(1); + cell.setCellStyle(styles.get("cell_number")); + + CycleData firstCycle = logData.getLogData()[0]; + + if(ovData.noOfcycles == 1) + cell.setCellValue(new HSSFRichTextString(ovData.noOfcycles + " (" + firstCycle.getCycleNumber() + ")")); + else + cell.setCellValue(ovData.noOfcycles); + + row=sheet.createRow(2); + cell=row.createCell(0); + cell.setCellValue(new HSSFRichTextString("Number of Cycles Truncated")); + cell=row.createCell(1); + cell.setCellValue(constants.size()); + + row=sheet.createRow(3); + cell = row.createCell(0); + cell.setCellValue(new HSSFRichTextString("Time Period")); + HSSFCell timePeriod = row.createCell(1); + + row=sheet.createRow(4); + cell=row.createCell(0); + cell.setCellValue(new HSSFRichTextString("Time Duration")); + cell=row.createCell(1); + cell.setCellValue(new HSSFRichTextString(ovData.duration + " sec(" + ovData.durationString + ")")); + + row=sheet.createRow(5); + cell=row.createCell(0); + cell.setCellValue(new HSSFRichTextString("ROM Checksum")); + cell=row.createCell(1); + cell.setCellValue(new HSSFRichTextString(firstCycle.getRomCheckSum())); + + row=sheet.createRow(6); + cell=row.createCell(0); + cell.setCellValue(new HSSFRichTextString("ROM Version")); + cell=row.createCell(1); + cell.setCellValue(new HSSFRichTextString(firstCycle.getRomVersion())); + + sheet.createRow(7); + sheet.createRow(8); + sheet.createRow(9); + + row = sheet.createRow(10); + cell = row.createCell(0); + cell.setCellStyle(styles.get("header2")); + cell.setCellValue(new HSSFRichTextString("")); + + cell = row.createCell(1); + cell.setCellStyle(styles.get("header2")); + cell.setCellValue(new HSSFRichTextString("Delta")); + + HSSFRow totalHeapSizeRow = sheet.createRow(11); + cell = totalHeapSizeRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Heap Size")); + + HSSFRow freeCellRow = sheet.createRow(12); + cell = freeCellRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Free Cell count")); + + HSSFRow alloCellRow = sheet.createRow(13); + cell = alloCellRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Allocated Cell count")); + + HSSFRow freeSpaceRow = sheet.createRow(14); + cell = freeSpaceRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Free space")); + + HSSFRow allocSpaceRow = sheet.createRow(15); + cell = allocSpaceRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Allocated space")); + + HSSFRow slackSpaceRow = sheet.createRow(16); + cell = slackSpaceRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Slack space")); + + HSSFRow filesRow = sheet.createRow(17); + cell = filesRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Total files")); + + HSSFRow psHandlesRow = sheet.createRow(18); + cell = psHandlesRow.createCell(0); + cell.setCellStyle(styles.get("cell_bold")); + cell.setCellValue(new HSSFRichTextString("Total P&S Handles")); + + sheet.createRow(19); + sheet.createRow(20); + sheet.createRow(21); + sheet.createRow(22); + + row = sheet.createRow(23); + createOverviewFields(row); + + createDataInOverView(sheet, 24); + + cell = totalHeapSizeRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalHeapSizeChange); + + cell = freeCellRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalFreeCellChange); + + cell = alloCellRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalAllocCellChange); + + cell = freeSpaceRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalFreeSpaceChange); + + cell = allocSpaceRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalAllocSpaceChange); + + cell = slackSpaceRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalSlackSpaceChange); + + cell = filesRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalFilesChange); + + cell = psHandlesRow.createCell(1); + cell.setCellStyle(styles.get("blue_font")); + cell.setCellValue(totalHandlesChange); + + sheet.autoSizeColumn((short)0); + sheet.autoSizeColumn((short)1); + sheet.autoSizeColumn((short)2); + sheet.autoSizeColumn((short)3); + sheet.autoSizeColumn((short)4); + sheet.autoSizeColumn((short)5); + sheet.autoSizeColumn((short)6); + sheet.autoSizeColumn((short)7); + sheet.autoSizeColumn((short)8); + sheet.autoSizeColumn((short)9); + sheet.autoSizeColumn((short)10); + sheet.autoSizeColumn((short)11); + + + if(ovData.noOfcycles > 1) + timePeriod.setCellValue(new HSSFRichTextString(ovData.fromTime + " to " + ovData.toTime)); + else + timePeriod.setCellValue(new HSSFRichTextString(ovData.fromTime)); + + return true; + } + + /** + * This method creates the sheet for RAM and DISK Memory data. + * It shows the variation of RAM and Disk Memory in each cycle. + * + */ + private void createDiskVariationSheet() { + //create a new sheet + HSSFSheet sheet = wb.createSheet(); + // declare a row object reference + HSSFRow row = null; + HSSFRow description = null; + // declare a cell object reference + HSSFCell cell = null; + + //set the sheet name in Unicode + wb.setSheetName(1, "RAM and Disk Memory"); + + row = sheet.createRow(0); + //r.setHeight((short)500); + + cell = row.createCell(0); + cell.setCellStyle(styles.get("header")); + cell.setCellValue(new HSSFRichTextString("RAM and Disk Memory")); + + description = sheet.createRow(1); + + //creates an empty row + row = sheet.createRow(2); + + row = sheet.createRow(3); + + cell = row.createCell(0); + cell.setCellStyle(styles.get("header2")); + cell.setCellValue(new HSSFRichTextString("")); + + addCycleIntervals(row); + + cell = row.createCell((int)(row.getLastCellNum())); + cell.setCellStyle(styles.get("header2")); + cell.setCellValue(new HSSFRichTextString("Delta")); + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + ArrayList diskNames = utils.getAllDiskNames(logData); + + int rowNo = 4; + + row = sheet.createRow(rowNo); + cell = row.createCell(0); + cell.setCellStyle(styles.get("cell_normal")); + cell.setCellValue(new HSSFRichTextString("RAM (Used)")); + + ArrayList systemData = utils.getSystemDataFromAllCycles(logData); + + long [] usedMemValues = new long[logData.getNumberOfCycles()]; + + j=1; + for(int i=0; i values = utils.getUsedMemoryAndSizesForDisk(name, logData); + long [] usedSizes = new long[values.size()]; + + j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = heapData.get(heap.toLowerCase()); + + if(heapValues != null) + { + int j=1; + for(int i=0; i heapValues = glodData.get(heap); + + int j=1; + for(int i=0; i chunkValues = chunkData.get(heap); + + int j=1; + for(int i=0; i wndg_names = utils.getWindowGroupNames(logData); + + int rowNo = 4; + + if(wndg_names == null) + return; + else + { + for(String name:wndg_names) + { + row = sheet.createRow(rowNo++); + cell = row.createCell(0); + cell.setCellStyle(styles.get("cell_normal")); + cell.setCellValue(new HSSFRichTextString(name)); + + ArrayList events_list = utils.getAllWindowGroupEvents(name, logData); + + int j = 1; + + for(int i=0; i 0) + tmp.append(" NoEvent(" + eventSet.getEvent_0_count() + ")"); + if(eventSet.getEvent_1_count() > 0) + tmp.append(" NameChanged(" + eventSet.getEvent_1_count() + ")"); + if(eventSet.getEvent_2_count() > 0) + tmp.append(" FocusGained(" + eventSet.getEvent_2_count() + ")"); + if(eventSet.getEvent_3_count() > 0) + tmp.append(" FocusLost(" + eventSet.getEvent_3_count() + ")"); + + cell.setCellValue(new HSSFRichTextString(tmp.toString())); + } + + } + } + + for(int i=0; i <= logData.getNumberOfCycles(); i++) + sheet.autoSizeColumn((short)i); + + cell = description.createCell(0); + cell.setCellValue(new HSSFRichTextString("Specifies the type and number of events for each window group, in each cycle.")); + } + } + /** + * create set of cell styles + */ + private Map createStyles(HSSFWorkbook wb){ + Map styles = new HashMap(); + + HSSFCellStyle style; + HSSFFont headerFont = wb.createFont(); + headerFont.setColor(HSSFColor.WHITE.index); + headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); + headerFont.setFontHeightInPoints((short)18); + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_LEFT); + style.setFillForegroundColor(HSSFColor.BLUE.index); + style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style.setFont(headerFont); + styles.put("header", style); + + HSSFFont font1 = wb.createFont(); + font1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + font1.setFontHeightInPoints((short)12); + font1.setFontName(HSSFFont.FONT_ARIAL); + font1.setColor(HSSFColor.WHITE.index); + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_CENTER); + style.setFillForegroundColor(HSSFColor.BLUE.index); + style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style.setFont(font1); + style.setWrapText(true); + styles.put("header2", style); + + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_LEFT); + style.setFillForegroundColor(HSSFColor.BLUE.index); + style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style.setFont(font1); + style.setWrapText(true); + styles.put("header1", style); + + HSSFFont font3 = wb.createFont(); + font3.setColor(HSSFColor.BLACK.index); + font3.setFontHeightInPoints((short)10); + font3.setFontName(HSSFFont.FONT_ARIAL); + font3.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_LEFT); + style.setFont(font3); + styles.put("cell_bold", style); + + HSSFFont font5 = wb.createFont(); + font5.setColor(HSSFColor.BLACK.index); + font5.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_LEFT); + style.setFont(font5); + styles.put("cell_normal", style); + + HSSFFont font4 = wb.createFont(); + font4.setFontHeightInPoints((short)10); + font4.setColor(HSSFColor.WHITE.index); + style = createBorderedStyle(wb); + style.setFillForegroundColor(HSSFColor.BLUE.index); + style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style.setFont(font4); + styles.put("cell_blue_font_white", style); + + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); + styles.put("cell_number", style); + + HSSFFont blue_font = wb.createFont(); + blue_font.setFontHeightInPoints((short)10); + blue_font.setColor(HSSFColor.BLUE.index); + style = createBorderedStyle(wb); + style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); + style.setFont(blue_font); + styles.put("blue_font", style); + + return styles; + } + + private HSSFCellStyle createBorderedStyle(HSSFWorkbook wb){ + HSSFCellStyle style = wb.createCellStyle(); + style.setBorderRight(HSSFCellStyle.BORDER_THIN); + style.setRightBorderColor(HSSFColor.BLACK.index); + style.setBorderBottom(HSSFCellStyle.BORDER_THIN); + style.setBottomBorderColor(HSSFColor.BLACK.index); + style.setBorderLeft(HSSFCellStyle.BORDER_THIN); + style.setLeftBorderColor(HSSFColor.BLACK.index); + style.setBorderTop(HSSFCellStyle.BORDER_THIN); + style.setTopBorderColor(HSSFColor.BLACK.index); + return style; + } + + /** + * This method adds cells with values of time intervals between + * consecutive cycles to given row. + * @param row + */ + private void addCycleIntervals(HSSFRow row) + { + HSSFCell cell = null; + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + cell = row.createCell(1); + cell.setCellStyle(styles.get("header2")); + cell.setCellValue(0); + + if(logData == null) + return; + + long prevDuration = 0; + + int i; + String currentTime = ""; + String prevTime = ""; + int j=1; + int filesSkipped = 1; + + CycleData [] cycles = logData.getLogData(); + + for(i=1; i allThreads = utils.getAllThreadNames(logData); + Collections.sort(allThreads); + + long [] maxHeapSizes = new long[allThreads.size()]; + long [] heapSizes = new long[allThreads.size()]; + long [] freeCells = new long[allThreads.size()]; + long [] allocCells = new long[allThreads.size()]; + long [] freeSpace = new long[allThreads.size()]; + long [] allocSpace = new long[allThreads.size()]; + long [] slackSpace = new long[allThreads.size()]; + long [] totalFiles = new long[allThreads.size()]; + long [] totalHandles = new long[allThreads.size()]; + long [] totalStacks = new long[allThreads.size()]; + + int i =0; + + for(String thName:allThreads) + { + if(thName.startsWith("MemSpy") && thName.endsWith("::MemSpy")) + continue; + + HSSFRow row = sheet.createRow(rowNo); + HSSFCell cell = row.createCell(0); + + cell.setCellStyle(styles.get("cell_normal")); + cell.setCellValue(new HSSFRichTextString(thName)); + + cell = row.createCell(1); + cell.setCellStyle(styles.get("cell_normal")); + + if(logData.getNumberOfCycles() == 1) + { + cell.setCellValue(new HSSFRichTextString("Alive")); + } + else + { + int status = utils.getThreadStatusFromAllCycles(thName, logData); + + if(status == 0) + cell.setCellValue(new HSSFRichTextString("Dead")); + else if(status == 1 || status == 2) + cell.setCellValue(new HSSFRichTextString("Alive")); + else + cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE)); + } + + ThreadData threadDelta = deltaData.get(thName.toLowerCase()); + + cell = row.createCell(2); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getMaxHeapSize()); + + maxHeapSizes[i] = threadDelta.getMaxHeapSize(); + /*ArrayList heapThreads = utils.getAllHeapThreads(logData); + long delta = 0; + long lastValue = 0; + + ArrayList heapData = utils.getHeapDataFromAllCycles(thName, logData); + + if(utils.getHeapStatusFromAllCycles(thName, logData) == 0) + { + //Display zeros for all heap fields + maxHeapSize = 0; + delta = 0; + } + else{ + lastValue = heapData.get(logData.size()-1).getHeapChunkSize(); + maxHeapSize = heapData.get(logData.size()-1).getMaxHeapSize(); + + long firstValue = 0; + + for(int i=heapData.size()-2; i>=0; i--) + { + ThreadData data = heapData.get(i); + if(data.getStatus() != CycleData.Deleted){ + firstValue = data.getHeapChunkSize(); + } + else + break; + } + + if(firstValue != -1) + delta = lastValue - firstValue; + } */ + + //cell.setCellValue(maxHeapSize); + + cell = row.createCell(3); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getHeapChunkSize()); + heapSizes[i] = threadDelta.getHeapChunkSize(); + + cell = row.createCell(4); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getHeapAllocatedSpace()); + allocSpace[i] = threadDelta.getHeapAllocatedSpace(); + + cell = row.createCell(5); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getHeapFreeSpace()); + freeSpace[i] = threadDelta.getHeapFreeSpace(); + + cell = row.createCell(6); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getAllocatedCells()); + allocCells[i] = threadDelta.getAllocatedCells(); + + cell = row.createCell(7); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getFreeCells()); + freeCells[i] = threadDelta.getFreeCells(); + + cell = row.createCell(8); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getFreeSlackSize()); + slackSpace[i] = threadDelta.getFreeSlackSize(); + + cell = row.createCell(9); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getStackSize()); + totalStacks[i] = threadDelta.getStackSize(); + + cell = row.createCell(10); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getOpenFiles()); + totalFiles[i] = threadDelta.getOpenFiles(); + + cell = row.createCell(11); + cell.setCellStyle(styles.get("cell_number")); + cell.setCellValue(threadDelta.getPsHandles()); + totalHandles[i] = threadDelta.getPsHandles(); + + i++; + + rowNo++; + } + + if(allThreads.size() > 0) + { + + HSSFRow totalRow = sheet.createRow(rowNo); + + long totalMaxHeapSize = utils.calculateAndGetTotal(maxHeapSizes); + long totalStackSize = utils.calculateAndGetTotal(totalStacks); + totalHeapSizeChange = utils.calculateAndGetTotal(heapSizes); + totalFreeCellChange = utils.calculateAndGetTotal(freeCells); + totalAllocCellChange = utils.calculateAndGetTotal(allocCells); + totalFreeSpaceChange = utils.calculateAndGetTotal(freeSpace); + totalAllocSpaceChange = utils.calculateAndGetTotal(allocSpace); + totalSlackSpaceChange = utils.calculateAndGetTotal(slackSpace); + totalFilesChange = utils.calculateAndGetTotal(totalFiles); + totalHandlesChange = utils.calculateAndGetTotal(totalHandles); + + HSSFCell cell = totalRow.createCell(2); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalMaxHeapSize); + + cell = totalRow.createCell(3); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalHeapSizeChange); + + cell = totalRow.createCell(4); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalAllocSpaceChange); + + cell = totalRow.createCell(5); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalFreeSpaceChange); + + cell = totalRow.createCell(6); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalAllocCellChange); + + cell = totalRow.createCell(7); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalFreeCellChange); + + cell = totalRow.createCell(8); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalSlackSpaceChange); + + cell = totalRow.createCell(9); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalStackSize); + + cell = totalRow.createCell(10); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalFilesChange); + + cell = totalRow.createCell(11); + cell.setCellStyle(styles.get("cell_blue_font_white")); + cell.setCellValue(totalHandlesChange); + } + + } + private void readHeapDataFromAllCycles(Map> map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + //heapThreads = utils.getAllHeapThreads(logData); + + ArrayList allThreads = utils.getAllThreadNames(logData); + for(String heap:allThreads) + { + //ignoring the data related to MemSpy threads + if(heap.startsWith("MemSpy") && heap.endsWith("::MemSpy")) + continue; + + ArrayList heapData = utils.getHeapDataFromAllCycles(heap, logData); + + map.put(heap.toLowerCase(), heapData); + } + } + + private void readGlobalDataFromAllCycles(Map> map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + glodChunks = utils.getAllGlobalChunkNames(logData); + + Collections.sort(glodChunks); + for(String glod:glodChunks) + { + ArrayList globData = utils.getGLOBDataFromAllCycles(glod, logData); + map.put(glod, globData); + } + } + + private void readChunkDataFromAllCycles(Map> map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + nonHeapChunks = utils.getAllNonHeapChunkNames(logData); + + Collections.sort(nonHeapChunks); + for(String chunk:nonHeapChunks) + { + ArrayList globData = utils.getChunkDataFromAllCycles(chunk, logData); + map.put(chunk, globData); + } + } + + private void getFieldDifferencesForAllThreads(Map map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + ArrayList allThreads = utils.getAllThreadNames(logData); + + for(String s:allThreads) + { + //ignoring the data related to MemSpy threads + if(s.startsWith("MemSpy") && s.endsWith("::MemSpy")) + continue; + + ThreadData delta = utils.getChangeinHeapData(s, heapData.get(s.toLowerCase()), logData); + + map.put(s.toLowerCase(), delta); + } + } + + private void getFieldDifferencesForAllGlodChunks(Map map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + ArrayList allGlodChunks = utils.getAllGlobalChunkNames(logData); + + for(String s:allGlodChunks) + { + long delta = utils.getChangeinGlodChunksData(s, logData); + + map.put(s, delta+""); + } + } + + private void getFieldDifferencesForAllChunks(Map map, ParsedData logData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + ArrayList allChunks = utils.getAllNonHeapChunkNames(logData); + + for(String s:allChunks) + { + long delta = utils.getChangeinChunksData(s, logData); + + map.put(s, delta+""); + } + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,1361 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.model; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +import org.eclipse.core.runtime.IProgressMonitor; + +import com.nokia.s60tools.swmtanalyser.data.ChunksData; +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.DiskOverview; +import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks; +import com.nokia.s60tools.swmtanalyser.data.KernelElements; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.data.StackData; +import com.nokia.s60tools.swmtanalyser.data.SystemData; +import com.nokia.s60tools.swmtanalyser.data.ThreadData; +import com.nokia.s60tools.swmtanalyser.data.ThreadSegments; +import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData; +import com.nokia.s60tools.swmtanalyser.data.WindowGroups; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Helper class which has some util methods. + * + */ +public class SWMTLogReaderUtils { + + private static final String CHECK_SUM = "Checksum"; + private static final String VERSION = "Version"; + + /** + * Construction + */ + public SWMTLogReaderUtils() { + } + + /** + * Parse all the given text log files and create store the basic data in CycleData object for each file. + * @param inputFiles + * @param cycles + * @param monitor + * @return null if everything was OK, error message if otherwise. + */ + public String getCycleDataArrayFromLogFiles(ArrayList inputFiles, ArrayList cycles, IProgressMonitor monitor) + { + int i = 0; + for(String path: inputFiles) + { + i++; + if(monitor != null) + { + if(monitor.isCanceled()) + return null; + if(i == inputFiles.size()/2) + monitor.worked(5); + } + File aFile = new File(path); + ArrayList lines = new ArrayList(); + int lineNum; + try { + BufferedReader input = new BufferedReader(new FileReader(aFile)); + try { + String line = null; + lineNum = 0; + while (( line = input.readLine()) != null){ + + //Increment line number + lineNum++; + + line = line.trim(); + //Ignoring newlines and lines which are having only spaces + if(line.length() == 0) + continue; + + //Line must start with test [MemSpy], if not it is invalid input. + if(!line.startsWith("[MemSpy]")) + { + return "Error in the log ("+path+"): at line " + lineNum + "\nLine does not start with [MemSpy]."; + } + + if(line.contains("Type")) + break; + + //Add valid line to array + lines.add(line); + + } + } + finally { + input.close(); + } + } + catch (IOException ex){ + ex.printStackTrace(); + return ex.getMessage(); + } + + String cycleNumLine = null; + String timeLine = null; + + String romCheckSum = null; + String romVersion = null; + + for(String str:lines) + { + if(str.contains("Cycle number")) + cycleNumLine = str; + if(str.contains("Time")) + timeLine = str; + + if(str.contains("ROM") && str.contains(CHECK_SUM)) + romCheckSum = str; + else if(str.contains("ROM") && str.contains(VERSION)) + romVersion = str; + } + + if(cycleNumLine == null || timeLine == null) + return "Error in the Log " + path + "\n The log might not contain Cycle number or Time information. Please check"; + + if(romCheckSum == null || romVersion == null) + return "Error in the Log " + path + "\n The log might not contain ROM information. Please check"; + + //Read cycle number + String num = cycleNumLine.substring(cycleNumLine.indexOf("Cycle number") + 12).trim(); + int cycleNo = Integer.parseInt(num); + + //Read Time + String time = timeLine.substring(timeLine.indexOf("Time") + 4).trim(); + + String checkSum = romCheckSum.substring(romCheckSum.indexOf(CHECK_SUM) + (CHECK_SUM).length()).trim(); + String romVer = romVersion.substring(romVersion.indexOf(VERSION) + (VERSION).length()).trim(); + + CycleData cycleData = new CycleData(); + cycleData.setTime(time); + cycleData.setCycleNumber(cycleNo); + cycleData.setFileName(path); + cycleData.setRomCheckSum(checkSum); + cycleData.setRomVersion(romVer); + + cycles.add(cycleData); + } + + return null; + } + + /** + * Gets the overview information till the selected log file. + * @param allCyclesData CycleData list + * @param toCycle Cycle number till where you want to export + * @return OverviewData + */ + public OverviewData getOverviewInformationFromCyclesData(CycleData[] allCyclesData, int toCycle) + { + OverviewData overview = new OverviewData(); + overview.noOfcycles = toCycle; + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); + Date aDate=null; + Date bDate=null; + try { + aDate = sdf.parse(allCyclesData[0].getTime()); + bDate = sdf.parse(allCyclesData[toCycle-1].getTime()); + } catch (ParseException e) { + e.printStackTrace(); + } + + long t1= aDate.getTime(); + long t2= bDate.getTime(); + //time difference in seconds + overview.duration = (t2-t1)/1000; + //Get date and time in the format like : Jan 7, 2008 1:56:44 PM + overview.fromTime = DateFormat.getDateTimeInstance().format(aDate); + overview.toTime = DateFormat.getDateTimeInstance().format(bDate); + overview.durationString = millisecondToDHMS(overview.duration*1000); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Cycle Numbers :" + overview.noOfcycles ); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Period :" + overview.fromTime + " to " + overview.toTime ); + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Duration :" + overview.duration + " sec (" + overview.durationString + ")"); + + return overview; + } + + /** + * Returns the difference between two time strings + * @param startTime + * @param endTime + * @return difference between startTime and endTime in seconds. + */ + public long getDurationInSeconds(String startTime, String endTime) + { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); + + Date aDate=null; + Date bDate=null; + + try { + aDate = sdf.parse(startTime); + bDate = sdf.parse(endTime); + } catch (ParseException e) { + return -1; + } + + long t1= aDate.getTime(); + long t2= bDate.getTime(); + //time difference in seconds + return (t2-t1)/1000; + + } + /** + * converts time (in milliseconds) to + * "d, h, min, sec" + * @return time in readable format. + */ + public String millisecondToDHMS(long duration) { + long ONE_SECOND = 1000; + long ONE_MINUTE = ONE_SECOND * 60; + long ONE_HOUR = ONE_MINUTE * 60; + long ONE_DAY = ONE_HOUR * 24; + + String res = ""; + long temp = 0; + if (duration >= ONE_SECOND) { + temp = duration / ONE_DAY; + if (temp > 0) { + res = temp + " d"; + duration -= temp * ONE_DAY; + + if (duration >= ONE_MINUTE) { + res += ", "; + } + } + + temp = duration / ONE_HOUR; + if (temp > 0) { + res += temp + " h"; + duration -= temp * ONE_HOUR; + if (duration >= ONE_MINUTE) { + res += ", "; + } + } + + temp = duration / ONE_MINUTE; + if (temp > 0) { + res += temp + " min"; + duration -= temp * ONE_MINUTE; + + if(duration >= ONE_SECOND) { + res += ", "; + } + } + + temp = duration / ONE_SECOND; + if (temp > 0) { + res += temp + " sec"; + } + return res; + } + else { + return "0 sec"; + } + } + + /** + * This will check whether the CycleData objects are in concecutive order and + * if not, this will return the reordered list. + * @param allCyclesData + * @return Reordered list, if any cycle data is missing null will be returned + */ + public ArrayList checkCycleOrder(ArrayList allCyclesData) + { + ArrayList orderedCycles = new ArrayList(); + + /*for(int i=0; i0 && before[0].getCycleNumber() == 1) + { + int i= 1; + for (CycleData data: before) { + data.setCycleNumber(i); + orderedCycles.add(data); + i++; + } + return orderedCycles; + } + else + return null; + } + + /** + * This method fetches list of all newly created disk names from all the + * cycles. If only one cycle is selected it fetches list of new and updated disk names. + * @param data specifies list of CycleData to be parsed + * @return list of disknames from all the cycles + */ + public ArrayList getAllDiskNames(ParsedData data) + { + if(data == null || data.getNumberOfCycles() ==0) + return null; + + CycleData [] parsed_cycles = data.getLogData(); + + CycleData firstCycle = parsed_cycles[0]; + firstCycle.parseDisksList(); + ArrayList totalDisks = new ArrayList(firstCycle.getNewlyCreatedDisks()); + + if(parsed_cycles.length == 1) + { + ArrayList updatedDisks = firstCycle.getUpdatedDisks(); + + for(String disk:updatedDisks) + { + if(!totalDisks.contains(disk)) + totalDisks.add(disk); + } + + return totalDisks; + } + for(int i=1; i newDisks = cycle.getNewlyCreatedDisks(); + + for(String disk:newDisks) + { + if(!totalDisks.contains(disk)) + totalDisks.add(disk); + } + } + + return totalDisks; + } + + /** + * This method fetches Used Memory and Size data for a given disk from given list of cycledata. + * @param diskName name of the disk, whose used memory and size must be fetched. + * @param data list of cycledata which needs to be parsed. + * @return list of used memory and size values for all cycles. + */ + public ArrayList getUsedMemoryAndSizesForDisk(String diskName, ParsedData parsedData) + { + + ArrayList diskTotalData = new ArrayList(); + DiskOverview prevData = new DiskOverview(); + + CycleData [] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + DiskOverview ov = null; + + if(!cycle.getDeletedDisks().contains(diskName)){ + DiskOverview tmp = cycle.getDiskUsedAndFreeSize(diskName); + + if(tmp != null) + ov = new DiskOverview(tmp); + else + { + ov = new DiskOverview(prevData); + + if(prevData.getStatus() == CycleData.New) + ov.setStatus(CycleData.Alive); + } + + } + else + ov = new DiskOverview(); + + diskTotalData.add(ov); + prevData = ov; + } + + /*for(int i=0;i getSystemDataFromAllCycles(ParsedData parsedData) + { + + ArrayList systemData = new ArrayList(); + SystemData prevData = new SystemData(); + + CycleData [] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + SystemData ov = new SystemData(prevData); + + long freeMem = cycle.getFreeMemory(); + long totalMem = cycle.getTotalMemory(); + + if(freeMem != -1) + { + ov.setFreeMemory(freeMem); + } + if(totalMem != -1) + ov.setTotalMemory(totalMem); + + systemData.add(ov); + prevData = ov; + } + + /*for(int i=0;i getAllThreadNames(ParsedData data) + { + if(data == null || data.getNumberOfCycles() == 0) + return null; + + CycleData[] parsed_cycles = data.getLogData(); + CycleData firstCycle = parsed_cycles[0]; + firstCycle.parseAllThreads(); + ArrayList totalThreads = new ArrayList(firstCycle.getNewlyCreatedThreads()); + + if(parsed_cycles.length == 1) + { + ArrayList updatedThreads = firstCycle.getUpdatedThreads(); + + for(String thread:updatedThreads) + { + if(!totalThreads.contains(thread)) + totalThreads.add(thread); + } + + ArrayList threadsFromAllViews = getThreadsFromAllViews(firstCycle); + + for(String thread:threadsFromAllViews) + { + if(!totalThreads.contains(thread)) + totalThreads.add(thread); + } + + return totalThreads; + } + for(int i=1; i newThreads = cycle.getNewlyCreatedThreads(); + + for(String thread:newThreads) + { + if(!totalThreads.contains(thread)) + totalThreads.add(thread); + } + } + + return totalThreads; + } + + /** + * This method fetches list of all heap thread names from all the cycles. + * If only one cycle is selected it fetches list of new and updated heap thread names. + * @param data specifies list of CycleData to be parsed + * @return list of those thread names which contain heap information, in one or many cycles. + */ + public ArrayList getAllHeapThreads(ParsedData parsedData) + { + + CycleData [] logData = parsedData.getLogData(); + CycleData firstCycle = logData[0]; + + firstCycle.parseAllHeaps(); + ArrayList totalHeaps = new ArrayList(firstCycle.getNewHeapThreads()); + + if(logData.length == 1) + { + ArrayList updatedHeaps = firstCycle.getAliveHeapThreads(); + + for(String thread:updatedHeaps) + { + if(!totalHeaps.contains(thread)) + totalHeaps.add(thread); + } + + return totalHeaps; + } + for(int i=1; i newHeaps = cycle.getNewHeapThreads(); + + for(String thread:newHeaps) + { + if(!totalHeaps.contains(thread)) + totalHeaps.add(thread); + } + } + + return totalHeaps; + } + + /** + * This method fetches all the data for a given thread from given list of cycledata. + * @param threadName name of the thread whose data is needed. + * @param cycles list of cycledata structures to be parsed for the thread data. + * @return list of ThreadData structures. Each structure holds values of given thread fields in each cycle. + */ + public ArrayList getHeapDataFromAllCycles(String threadName, ParsedData parsedData) + { + ArrayList allData = new ArrayList(); + + ThreadData prevData = new ThreadData(threadName); + CycleData[] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + ThreadData currentData = null; + + cycle.parseAllThreads(); + + //Fetch the data for this thread in this cycle. + //If no data in this cycle, copy the data from the previous cycle. + + ThreadData tmp = cycle.getHeapData(threadName); + + if(tmp != null) + currentData = tmp; + else{ + currentData = new ThreadData(prevData); + if(prevData.getStatus() == CycleData.New) + currentData.setStatus(CycleData.Alive); + } + + StackData stakData = cycle.getStackData(threadName); + + if(stakData != null) + { + currentData.setStackStatus(stakData.getStatus()); + currentData.setStackSize(stakData.getSize()); + } + else + { + if(prevData.getStackStatus() == CycleData.New) + currentData.setStackStatus(CycleData.Alive); + else + currentData.setStackStatus(prevData.getStackStatus()); + + currentData.setStackSize(prevData.getStackSize()); + } + + int openFilesCnt = cycle.getNewOpenFiles(threadName); + int closedFilesCnt = cycle.getDeletedFiles(threadName); + + int newPSHandlesCnt = cycle.getNewPSHandles(threadName); + int deletedPSHandlesCnt = cycle.getDeletedPSHandles(threadName); + + if(cycles.length == 1) + { + int updatedFiles = cycle.getUpdatedFiles(threadName); + int updatedPSHandles = cycle.getUpdatedPSHandles(threadName); + + currentData.setOpenFiles(openFilesCnt + updatedFiles); + currentData.setPsHandles(newPSHandlesCnt + updatedPSHandles); + } + + else + { + openFilesCnt += prevData.getOpenFiles(); + + openFilesCnt -= closedFilesCnt; + currentData.setOpenFiles(openFilesCnt); + + newPSHandlesCnt += prevData.getPsHandles(); + newPSHandlesCnt -= deletedPSHandlesCnt; + + currentData.setPsHandles(newPSHandlesCnt); + } + + if(cycle.getDeletedThreads().contains(threadName)) + currentData.setKernelHandleDeleted(true); + + currentData.setCycleNumber(cycle.getCycleNumber()); + allData.add(currentData); + prevData = currentData; + } + + return allData; + } + + /** + * Returns the array of global data chunks list of given chunk + * from all the log files data. + * @param chunkName + * @param cycles + * @return List of {@link GlobalDataChunks} with given chunk name + */ + public ArrayList getGLOBDataFromAllCycles(String chunkName, ParsedData logData) + { + + ArrayList allData = new ArrayList(); + + GlobalDataChunks prevData = new GlobalDataChunks(); + + CycleData [] logCycles = logData.getLogData(); + + for(CycleData cycle:logCycles) + { + GlobalDataChunks currentData = null; + GlobalDataChunks tmp = cycle.getGlobalChunkDataFor(chunkName); + if(tmp != null) + currentData = tmp; + else{ + currentData = new GlobalDataChunks(prevData); + + if(prevData.getAttrib() == CycleData.New) + currentData.setAttrib(CycleData.Alive); + } + + if(cycle.getDeletedChunkNames().contains(chunkName)) + currentData.setKernelHandleDeleted(true); + + allData.add(currentData); + prevData = currentData; + } + + return allData; + } + + /** + * Returns the array of chunks data list of given chunk + * from all the log files data. + * @param chunkName + * @param cycles + * @return list of {@link ChunksData} with given name + */ + public ArrayList getChunkDataFromAllCycles(String chunkName, ParsedData logData) + { + ArrayList allData = new ArrayList(); + + ChunksData prevData = new ChunksData(); + + CycleData[] cycles = logData.getLogData(); + for(CycleData cycle:cycles) + { + ChunksData currentData = null; + ChunksData tmp = cycle.getChunkDataFor(chunkName); + if(tmp != null) + currentData = tmp; + else{ + currentData = new ChunksData(prevData); + if(prevData.getAttrib() == CycleData.New) + currentData.setAttrib(CycleData.Alive); + } + + if(cycle.getDeletedChunkNames().contains(chunkName)) + currentData.setKernelHandleDeleted(true); + + allData.add(currentData); + prevData = currentData; + } + + return allData; + } + + /** + * This method returns the array of kernel elements data from all the given log files data. + * @param parsedData + * @return array of kernel elements + */ + public ArrayList getKerenelElemsFromAllCycles(ParsedData parsedData) + { + ArrayList allData = new ArrayList(); + KernelElements prevData = new KernelElements(); + + CycleData [] cycles = parsedData.getLogData(); + for(CycleData cycle:cycles) + { + KernelElements currentData = cycle.getAllOpenKernelElements(); + + int timers = currentData.getNumberOfTimers(); + int semaphores = currentData.getNumberOfSemaphores(); + int servers = currentData.getNumberOfServers(); + int sessions = currentData.getNumberOfSessions(); + int processes = currentData.getNumberOfProcesses(); + int threads = currentData.getNumberOfThreads(); + int chunks = currentData.getNumberOfChunks(); + int msgQueues = currentData.getNumberOfMsgQueues(); + + + if(parsedData.getNumberOfCycles() != 1) + { + + timers += prevData.getNumberOfTimers(); + semaphores += prevData.getNumberOfSemaphores(); + sessions += prevData.getNumberOfSessions(); + servers += prevData.getNumberOfServers(); + processes += prevData.getNumberOfProcesses(); + threads += prevData.getNumberOfThreads(); + chunks += prevData.getNumberOfChunks(); + msgQueues += prevData.getNumberOfMsgQueues(); + + //newTimers -= closedTimers; + currentData.setNumberOfTimers(timers); + currentData.setNumberOfSemaphores(semaphores); + currentData.setNumberOfProcesses(processes); + currentData.setNumberOfSessions(sessions); + currentData.setNumberOfServers(servers); + currentData.setNumberOfThreads(threads); + currentData.setNumberOfChunks(chunks); + currentData.setNumberOfMsgQueues(msgQueues); + + } + allData.add(currentData); + prevData = currentData; + + } + return allData; + } + /** + * + * @param threadName name of thread whose status is needed. + * @param data list of cycledata to be parsed + * @return the recent status of the thread from given cycles. + */ + public int getThreadStatusFromAllCycles(String threadName, ParsedData parsedData) + { + int status = -1; + + CycleData [] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + cycle.parseAllThreads(); + if(cycle.getNewlyCreatedThreads().contains(threadName)) + status = CycleData.New; + else if(cycle.getUpdatedThreads().contains(threadName)) + status = CycleData.Alive; + else if(cycle.getDeletedThreads().contains(threadName)) + status = CycleData.Deleted; + + } + return status; + } + + /** + * + * @param threadName name of thread whose heap status is needed. + * @param data list of cycledata to be parsed + * @return the recent status of the given thread's heap. + */ + public int getHeapStatusFromAllCycles(String threadName, ParsedData parsedData) + { + int status = 0; + CycleData [] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + cycle.parseAllHeaps(); + + ArrayList newHeapThreads = convertAllStringsToLowerCase(cycle.getNewHeapThreads()); + ArrayList aliveHeaps = convertAllStringsToLowerCase(cycle.getAliveHeapThreads()); + ArrayList deletedHeaps = convertAllStringsToLowerCase(cycle.getDeletedHeapThreads()); + + if(newHeapThreads.contains(threadName.toLowerCase()) || + aliveHeaps.contains(threadName.toLowerCase())) + status = 1; + else if(deletedHeaps.contains(threadName.toLowerCase())) + status = 0; + } + + return status; + } + + /** + * Get the stack status of a given thread name + * @param threadName name of thread whose heap status is needed. + * @param data list of cycledata to be parsed + * @return the recent status of the given thread's stack. + */ + public int getStackStatusFromAllCycles(String threadName, ParsedData parsedData) + { + int status = 0; + CycleData[] cycles = parsedData.getLogData(); + + for(CycleData cycle:cycles) + { + ArrayList newStacks = convertAllStringsToLowerCase(cycle.getNewStackThreads()); + ArrayList aliveStacks = convertAllStringsToLowerCase(cycle.getAliveStackThreads()); + ArrayList deletedStacks = convertAllStringsToLowerCase(cycle.getDeletedStackThreads()); + + if(newStacks.contains(threadName.toLowerCase()) || + aliveStacks.contains(threadName.toLowerCase())) + status = 1; + else if(deletedStacks.contains(threadName.toLowerCase())) + status = 0; + } + + return status; + } + + /** + * Get the delta data for the given threadname from all the cycles. + * @param threadName name of the thread + * @param logData list of cycledata to be parsed. + * @return the ThreadData structure which holds the differences for various + * fields in the lastCycle and the cycle in which the thread has actually started. + */ + public ThreadData getChangeinHeapData(String threadName, ArrayList allCyclesData, ParsedData logData) + { + ThreadData heapDataChange = new ThreadData(threadName); + + //If the heap for this thread is already deleted all the + //heap related fields will be set to 0. + if(getHeapStatusFromAllCycles(threadName, logData) == 0) + { + //Display zeros for all heap fields + heapDataChange.setMaxHeapSize(0); + heapDataChange.setHeapChunkSize(0); + heapDataChange.setHeapAllocatedSpace(0); + heapDataChange.setHeapFreeSpace(0); + heapDataChange.setAllocatedCells(0); + heapDataChange.setFreeCells(0); + heapDataChange.setFreeSlackSize(0); + heapDataChange.setLargestAllocCellSize(0); + heapDataChange.setLargestFreeCellSize(0); + + } + else{ + + ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1); + + //Get the heap values from the cycle in which the + //thread is started. + ThreadData firstHeapData = null; + + for(int i=allCyclesData.size()-2; i>=0; i--) + { + ThreadData data = allCyclesData.get(i); + if(data.getStatus() != CycleData.Deleted){ + firstHeapData = data; + } + else + break; + } + + if(firstHeapData != null) + { + heapDataChange.setMaxHeapSize(firstHeapData.getMaxHeapSize()); + long changeInHeapSize = lastHeapData.getHeapChunkSize() - firstHeapData.getHeapChunkSize(); + long changeInAllocSpace = lastHeapData.getHeapAllocatedSpace() - firstHeapData.getHeapAllocatedSpace(); + long changeInFreeSpace = lastHeapData.getHeapFreeSpace() - firstHeapData.getHeapFreeSpace(); + long changeInAllocCells = lastHeapData.getAllocatedCells() - firstHeapData.getAllocatedCells(); + long changeInFreeCells = lastHeapData.getFreeCells() - firstHeapData.getFreeCells(); + long changeInSlackSize = lastHeapData.getFreeSlackSize() - firstHeapData.getFreeSlackSize(); + long changeInLargestAllocCell = lastHeapData.getLargestAllocCellSize() - firstHeapData.getLargestAllocCellSize(); + long changeInLargestFreeCell = lastHeapData.getLargestFreeCellSize() - firstHeapData.getLargestFreeCellSize(); + + heapDataChange.setHeapChunkSize(changeInHeapSize); + heapDataChange.setHeapAllocatedSpace(changeInAllocSpace); + heapDataChange.setHeapFreeSpace(changeInFreeSpace); + heapDataChange.setAllocatedCells(changeInAllocCells); + heapDataChange.setFreeCells(changeInFreeCells); + heapDataChange.setFreeSlackSize(changeInSlackSize); + heapDataChange.setLargestAllocCellSize(changeInLargestAllocCell); + heapDataChange.setLargestFreeCellSize(changeInLargestFreeCell); + + } + else + { + heapDataChange.setMaxHeapSize(lastHeapData.getMaxHeapSize()); + heapDataChange.setHeapChunkSize(lastHeapData.getHeapChunkSize()); + heapDataChange.setHeapAllocatedSpace(lastHeapData.getHeapAllocatedSpace()); + heapDataChange.setHeapFreeSpace(lastHeapData.getHeapFreeSpace()); + heapDataChange.setAllocatedCells(lastHeapData.getAllocatedCells()); + heapDataChange.setFreeCells(lastHeapData.getFreeCells()); + heapDataChange.setFreeSlackSize(lastHeapData.getFreeSlackSize()); + heapDataChange.setLargestAllocCellSize(lastHeapData.getLargestAllocCellSize()); + heapDataChange.setLargestFreeCellSize(lastHeapData.getLargestFreeCellSize()); + } + } + + ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1); + + if(getStackStatusFromAllCycles(threadName, logData) == 0) + { + heapDataChange.setStackSize(0); + } + else + { + heapDataChange.setStackSize(lastHeapData.getStackSize()); + } + + heapDataChange.setOpenFiles(lastHeapData.getOpenFiles()); + + if(lastHeapData.getPsHandles() == -1) + heapDataChange.setPsHandles(0); + else + heapDataChange.setPsHandles(lastHeapData.getPsHandles()); + + return heapDataChange; + } + + /** + * Returns the start and end cycle numbers for the threads having multiple instances + * @param threadData list + * @return start and end cycle numbers + */ + public ThreadSegments [] getHeapSegments(ArrayList threadData) + { + ArrayList thSegments = new ArrayList(); + boolean is_thread_started = false; + ThreadSegments segment = null; + + for(ThreadData data: threadData) + { + if(data.getStatus() == CycleData.New && !is_thread_started) + { + segment = new ThreadSegments(); + is_thread_started = true; + segment.setStartCycle(data.getCycleNumber()); + } + if((data.getStatus() == CycleData.Deleted || data.getCycleNumber() == threadData.size()) && is_thread_started) + { + is_thread_started = false; + if(segment != null){ + segment.setEndCycle(data.getCycleNumber()); + thSegments.add(segment); + } + } + } + return thSegments.toArray(new ThreadSegments[0]); + } + /** + * Returns the delta value for the given global chunk. + * @param chunkName + * @param logData + * @return delta value for the given global chunk + */ + public long getChangeinGlodChunksData(String chunkName, ParsedData logData) + { + + ArrayList heapData = getGLOBDataFromAllCycles(chunkName, logData); + + + if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted) + return 0; + else + { + long lastValue = heapData.get(heapData.size()-1).getSize(); + long firstValue = 0; + for(GlobalDataChunks data: heapData) + { + if(data.getSize() != -1) + { + firstValue = data.getSize(); + break; + } + } + return lastValue - firstValue; + } + } + + /** + * Returns the delta value for the given chunk. + * @param chunkName + * @param logData + * @return delta value for the given chunk + */ + public long getChangeinChunksData(String chunkName, ParsedData logData) + { + ArrayList heapData = getChunkDataFromAllCycles(chunkName, logData); + + if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted) + return 0; + else + { + long lastValue = heapData.get(heapData.size()-1).getSize(); + long firstValue = 0; + for(ChunksData data: heapData) + { + if(data.getSize() != -1) + { + firstValue = data.getSize(); + break; + } + } + return lastValue - firstValue; + } + } + + /** + * Return sum of the given delta values. + * @param deltaValues + * @return the sum of all given values + */ + public long calculateAndGetTotal(long[] deltaValues) + { + long total = 0; + + for(long value:deltaValues) + { + total = total + value; + } + return total; + } + + /** + * Returns time intervals for all the given cycles. + * @param parsedData + * @return intervals + */ + public int [] getTimeIntervalsFromLogData(ParsedData parsedData) + { + CycleData [] cyclesData = parsedData.getLogData(); + + if(cyclesData == null) + return null; + + int [] timeIntervals = new int[cyclesData.length]; + + timeIntervals[0] = 0; + + for(int i=1; i=0;i--) + { + if(valuesArr[i] != -1) + firstValue = valuesArr[i]; + else + break; + } + + if(lastValue != -1) + { + if(firstValue != -1) + return lastValue - firstValue; + else + return lastValue; + } + else + return 0; + } + + /** + * Returns unique list of global chunk names from all the log files. + * @see GlobalDataChunks#getChunkName() + * @param data + * @return list about global chunk names + */ + public ArrayList getAllGlobalChunkNames(ParsedData data) + { + if(data == null || data.getNumberOfCycles() == 0) + return null; + + CycleData [] parsed_cycles = data.getLogData(); + ArrayList globalChunkNames = new ArrayList(); + + for(CycleData cycle: parsed_cycles) + { + if(cycle.getGlobalDataChunksList()!=null) + for(GlobalDataChunks chunkName:cycle.getGlobalDataChunksList()) + { + if(!globalChunkNames.contains(chunkName.getChunkName())) + globalChunkNames.add(chunkName.getChunkName()); + } + } + + return globalChunkNames; + } + + /** + * Returns unique list of non heap chunk names from all the log files. + * @see ChunksData#getChunkName() + * @param data + * @return List of non heap chunk names + */ + public ArrayList getAllNonHeapChunkNames(ParsedData data) + { + if(data == null || data.getNumberOfCycles() == 0) + return null; + + ArrayList chunkNames = new ArrayList(); + CycleData [] parsed_cycles = data.getLogData(); + + for(CycleData cycle: parsed_cycles) + { + if(cycle.getChunksList()!=null) + for(ChunksData chunkName:cycle.getChunksList()) + { + if(!chunkNames.contains(chunkName.getChunkName())) + chunkNames.add(chunkName.getChunkName()); + } + } + + return chunkNames; + } + + /** + * This method returns unique list of window group names from all the log files. + * @param data + * @return window group names + */ + public ArrayList getWindowGroupNames(ParsedData data) + { + if(data == null || data.getNumberOfCycles() == 0) + return null; + + ArrayList wndgNames = new ArrayList(); + CycleData [] parsed_cycles = data.getLogData(); + + for(CycleData cycle: parsed_cycles) + { + for(WindowGroups name:cycle.getWindowGroupsData()) + { + if(!wndgNames.contains(name.getName())) + wndgNames.add(name.getName()); + } + } + + return wndgNames; + } + + /** + * Get {@link WindowGroupEventData} for given window group name + * @param windowGroupName + * @param logData + * @return list of window group data + */ + public ArrayList getAllWindowGroupEvents(String windowGroupName, ParsedData logData) + { + if(logData == null || logData.getNumberOfCycles() == 0) + return null; + + CycleData [] parsed_cycles = logData.getLogData(); + + ArrayList eventsData = new ArrayList(); + + WindowGroupEventData prevData = null; + + for(CycleData cycle:parsed_cycles) + { + WindowGroupEventData currentData; + + if(prevData == null) + currentData = new WindowGroupEventData(); + else + currentData = new WindowGroupEventData(prevData); + + for(WindowGroups grp: cycle.getWindowGroupsData()) + { + if(grp.getName().equalsIgnoreCase(windowGroupName)) + { + if(grp.getStatus() == CycleData.New || grp.getStatus() == CycleData.Alive) + currentData.incrementEventCount(grp.getEvent()); + else if(grp.getStatus() == CycleData.Deleted) + currentData.decrementEventCount(grp.getEvent()); + } + } + + prevData = currentData; + eventsData.add(currentData); + } + + return eventsData; + } + /** + * Get all threads names from data + * @param data + * @return List of thread names. + */ + public ArrayList getThreadsFromAllViews(CycleData data) + { + ArrayList threads = new ArrayList(); + + data.parseAllHeaps(); + + for(String threadName:data.getNewHeapThreads()) + { + if(!threads.contains(threadName)) + threads.add(threadName); + } + + for(String threadName:data.getAliveHeapThreads()) + { + if(!threads.contains(threadName)) + threads.add(threadName); + } + + for(String threadName:data.getNewStackThreads()) + { + if(!threads.contains(threadName)) + threads.add(threadName); + } + + for(String threadName:data.getAliveStackThreads()) + { + if(!threads.contains(threadName)) + threads.add(threadName); + } + + for(String threadName:data.getFileThreads()) + { + if(!threads.contains(threadName)) + threads.add(threadName); + } + + for(String threadName:data.getHPASThreads()) + { + if(threadName.length() !=0 && !threads.contains(threadName)) + threads.add(threadName); + } + return threads; + } + + /** + * Gets the total for given delta values. + * @param deltaValues + * @return total delta values counted together + */ + public long getTotal(ArrayList deltaValues) + { + long total = 0; + for(String value:deltaValues) + { + if(value != "N/A") + total = total + Long.parseLong(value); + } + return total; + } + + /** + * Converts all given strings to lower case. + * @param inputList + * @return + */ + private ArrayList convertAllStringsToLowerCase(ArrayList inputList) + { + ArrayList outputList = new ArrayList(); + if(inputList != null) + { + for(int i=0;itrue if ROM Checksum is OK false otherwise. + */ + public boolean checkRomInfo(ArrayList cycleData) + { + boolean result = true; + + for(int i = 0; i<=cycleData.size()-2; i++) + { + String currentCheckSum = cycleData.get(i).getRomCheckSum(); + String nextCheckSum = cycleData.get(i+1).getRomCheckSum(); + + String currentVersion = cycleData.get(i).getRomVersion(); + String nextVersion = cycleData.get(i+1).getRomVersion(); + + if((!currentCheckSum.equals(nextCheckSum)) || (!currentVersion.equals(nextVersion))) + { + result = false; + break; + } + } + + return result; + } + + /** + * Check timestamps from consecutive cycles + * if log n+1 time stamp is lesser than log n then return log n+1 cycle number. else return 0 + * @param allcycleData + * @return Returns cycle number or 0 + */ + public int checkTimeStamp(ArrayList allcycleData){ + + for(int i=1;i iter = ((IStructuredSelection) selection) + .iterator(); + List items = new ArrayList(); + + String tab = "\t"; + boolean isHeaderFound = false; + String headers = null; + //Get all selected items + while (iter.hasNext()) { + Object o = iter.next(); + String str = null; + //Copy from Graphs + if(o instanceof TableViewerInputObject){ + TableViewerInputObject to = (TableViewerInputObject)o; + str = to.getName(); + } + //Copy from Graphed items + else if(o instanceof GraphedItemsInput){ + GraphedItemsInput gi = (GraphedItemsInput)o; + str = gi.getTabSeparatedValues(); + //Adding headers when found out at least one data item + if(!isHeaderFound){ + headers = gi.getTabSeparatedHeaders(); + isHeaderFound = true; + } + } + //Copy from Analysis (data) + else if(o instanceof ResultElements){ + ResultElements re = (ResultElements)o; + str = tab + re.getTabSeparatedValues(); + //Adding headers when found out at least one data item + if(!isHeaderFound){ + headers = tab + re.getTabSeparatedHeaders(); + isHeaderFound = true; + } + } + //Copy from Analysis (parent node) + else if(o instanceof ResultsParentNodes){ + ResultsParentNodes rpn = (ResultsParentNodes)o; + str = rpn.toString(); + } + //Else it's internal error if we can't found proper handle to class given to Copy. + else{ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Unable to found Copy functionality to Object: (" +o + "), Class: " +o.getClass()); + } + + if(str != null){ + items.add(str); + } + + } + + //If at least one data item was found, also data headers will be added, but only once. + if(headers != null){ + items.add(0, headers); + } + + StringArrayClipboardCopyHandler copyHandler = new StringArrayClipboardCopyHandler(); + copyHandler.acceptAndCopy(items); + + } catch (Exception e) { + e.printStackTrace(); + SwmtAnalyserPlugin.getConsole().println(e.getMessage(), + IConsolePrintUtility.MSG_ERROR); + } + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/ISelectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/ISelectionProvider.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.actions; + +import org.eclipse.jface.viewers.ISelection; + +/** + * Interface for provide selection that User has been made in UI + */ +public interface ISelectionProvider { + + + /** + * Get selection that user has made in UI + * @return selection made in UI + */ + public ISelection getUserSelection(); + + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/SwmtAnalyser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/SwmtAnalyser.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,193 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.actions; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin; +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.editors.SWMTEditorInput; +import com.nokia.s60tools.swmtanalyser.exception.SwmtFormatException; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.swmtanalyser.model.SwmtParser; +import com.nokia.s60tools.util.console.IConsolePrintUtility; + +/** + * Interface to start analysis. + * + */ +public class SwmtAnalyser { + + private static final String SWMT_EDITOR_ID = "com.nokia.s60tools.swmtanalyser.editors.SWMTEditor"; + private ArrayList inputs; + private ArrayList cycleData; + private String status = null; + private boolean isCancelled; + private SWMTLogReaderUtils logReader = new SWMTLogReaderUtils(); + private String parserError; + + /** + * Construction for creating SWMT Analyser to editor area. + * @param console + */ + public SwmtAnalyser(IConsolePrintUtility console) { + SwmtAnalyserPlugin.getDefault().setConsole(console); + } + + /** + * Analyse given logs files. + * @param swmtFiles list of swmt log files to be analysed + */ + public void analyse(ArrayList swmtFilePaths) + { + if(swmtFilePaths != null) + { + inputs = swmtFilePaths; + cycleData = new ArrayList(); + + isCancelled = false; + IRunnableWithProgress op = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + monitor.beginTask("Reading log files..", 10); + status = logReader.getCycleDataArrayFromLogFiles(inputs, cycleData, monitor); + if(monitor.isCanceled()) + isCancelled = true; + + monitor.done(); + } + }; + + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); + + Shell shell = win != null ? win.getShell() : null; + try { + new ProgressMonitorDialog(shell).run(true, true, op); + } catch (InvocationTargetException e) { + e.printStackTrace(); + return; + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + if(isCancelled) + return; + + if(status != null) + { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", status); + return; + } + else if(cycleData.size()>1) + { + cycleData = logReader.checkCycleOrder(cycleData); + if(cycleData==null) + { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Invalid order of the log files. The selected files must be in consecutive order and must start from the first cycle."); + return; + } + + if(!logReader.checkRomInfo(cycleData)) + { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Selected logs do not have common ROM Checksum and Version. Hence, they cannot be compared."); + return; + } + int ret = logReader.checkTimeStamp(cycleData); + if(ret!= 0) + { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "In selected logs, the time stamp of log cycle "+ ret +" is lesser than log cycle "+ (ret -1)+". Hence, they cannot be analysed together."); + return; + } + } + else if(cycleData.size() == 1 && cycleData.get(0).getCycleNumber() != 1) + { + boolean ok = MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "SWMT Analyser", "This is a delta file. It does not contain the complete information. Do you still want to continue ?"); + if(!ok) + return; + } + + //Files are valid and the cycle numbers are in order. + //So, get overview information to be displayed in the editor view + OverviewData ov = logReader.getOverviewInformationFromCyclesData(cycleData.toArray(new CycleData[0]),cycleData.size()); + + Runnable runnable = new Runnable(){ + public void run() { + for(int i=0; i> chunksData = new HashMap>(); + private HashMap> nonHeapChunksData = new HashMap>(); + + private HashMap pointsData = new HashMap(); + + private double visY; + private double multiplier; + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics) + */ + public void paint(Graphics graphics) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START"); + + ArrayList chunksList = this.getUserSelectedItems(); + + if(chunksList == null) + return; + + // Storing original settings before graphs are painted with case-specific settings + int origLineWidth = graphics.getLineWidth(); + Color origColor = graphics.getForegroundColor(); + int origLineStyle = graphics.getLineStyle(); + + // Setting graph drawing specific settings + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + graphics.setLineStyle(SWT.LINE_SOLID); + + int [] listX = this.calculateTimeIntervals(); + this.lastSampleTime = listX[listX.length-1]; + + int k=0; + + for(String chnk: chunksList) + { + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + valuesToBePlotted = getGlobalChnkSizeData(chnk); + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + valuesToBePlotted = getNonHeapChnkSizeData(chnk); + + int [] points = new int[valuesToBePlotted.length *2]; + + double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + boolean handleDeleted = false; + + List> ListOfSolidLinePoints = new ArrayList>(); + ArrayList solidLinePoints = new ArrayList(); + + for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++) + { + if (valuesToBePlotted[i] <= 0){ + // Not showing zero values to a user, not meaningful data + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "continued because value <= 0"); + continue; + } + + int x_point = (int)(listX[i]/getScale()); + int y_point =(int) (visY - valuesToBePlotted[i] /multiplier); + + points[j] = x_point; + points[++j] = y_point; + + if(!handleDeleted){ + if(y_point > 0){ + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + boolean handleStatus = getHandleStatus(i+1, chnk); + + if(handleStatus && !handleDeleted){ + handleDeleted = true; + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + solidLinePoints = new ArrayList(); + } + + if(handleDeleted && getChunkStatus(i+1, chnk)== CycleData.New ) + { + handleDeleted = false; + if(y_point > 0){ + // Graphing only positive values + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + points[i] = x_point; + points[i+1] = y_point; + } + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + graphics.setForegroundColor(this.getColors().get(k)); + graphics.setLineWidth(2); + + for(int i=0; i < ListOfSolidLinePoints.size(); i++) + { + int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i)); + + if(solidPts != null) + { + if(ListOfSolidLinePoints.size() > 1) + { + int instance_id = i+1; + graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15); + } + graphics.setLineStyle(SWT.LINE_SOLID); + graphics.drawPolyline(solidPts); + + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, solidPts); + } + } + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + + pointsData.put(chnk, line); + + k++; + } + + // Restoring original settings before paint call + graphics.setLineStyle(origLineStyle); + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END"); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC) + */ + public void paintYAxis(GC gc) { + + visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY; + + double yIncrement = visY / 10; + int previousBottom = 0; + + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + + String legend = ""; + + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + Point extent = gc.stringExtent(legend); + + gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1); + + if (y >= previousBottom) + { + gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + + final Image image = this.getVerticalLabel("Bytes"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -(int)visY/3, 1); + + transform.dispose(); + gc.dispose(); + + } + + private void fetchEntireDataForSelectedChunks() + { + ArrayList selectedChunks = this.getUserSelectedItems(); + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + for(String chunk:selectedChunks) + { + ArrayList chnkData = utils.getGLOBDataFromAllCycles(chunk, this.getCyclesData()); + chunksData.put(chunk, chnkData); + } + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + for(String chunk:selectedChunks) + { + ArrayList chnkData = utils.getChunkDataFromAllCycles(chunk, this.getCyclesData()); + nonHeapChunksData.put(chunk, chnkData); + } + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData() + */ + public void prepareData() { + fetchEntireDataForSelectedChunks(); + + for(String chnk:getUserSelectedItems()) + { + int [] valuesToBePlotted = null; + + switch(this.getEvent()) + { + case GLOBAL_DATA_SIZE: + valuesToBePlotted = getGlobalChnkSizeData(chnk); + break; + case NON_HEAP_CHUNK_SIZE: + valuesToBePlotted = getNonHeapChnkSizeData(chnk); + break; + } + + if(valuesToBePlotted == null) + continue; + + int maxValue = calculateMaxValue(valuesToBePlotted); + + if(maxValue > maxBytes) + maxBytes = maxValue; + } + + } + + private boolean getHandleStatus(int cycleNo, String chunkName) + { + boolean status = false; + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList glod_data = chunksData.get(chunkName); + + status = glod_data.get(cycleNo -1).isKernelHandleDeleted(); + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList chunks_data = nonHeapChunksData.get(chunkName); + + status = chunks_data.get(cycleNo -1).isKernelHandleDeleted(); + } + + return status; + } + + private int getChunkStatus(int cycleNo, String chunkName) + { + int status = 0; + + if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList glod_data = chunksData.get(chunkName); + + status = glod_data.get(cycleNo -1).getAttrib(); + } + else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList chunks_data = nonHeapChunksData.get(chunkName); + + status = chunks_data.get(cycleNo -1).getAttrib(); + } + + return status; + } + private int [] getGlobalChnkSizeData(String chnkName) + { + ArrayList data = chunksData.get(chnkName); + + int [] values = new int[data.size()]; + + for(int i=0; i data = nonHeapChunksData.get(chnkName); + + int [] values = new int[data.size()]; + + for(int i=0; i (int)visY) + return null; + + String text = ""; + + double xValue = x + timeOffset; + int scaledX = (int)(xValue * getScale()); + + double valY = visY - y; + double bytes = valY * multiplier; + + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + text += scaledX + " s, " + scaledY; + for(String chnk: getUserSelectedItems()) + { + Polyline line = pointsData.get(chnk); + + if(line != null && line.containsPoint(x, y)) + text += "\n" + chnk; + } + + return text; + } + + /** + * Get {@link GlobalDataChunks} for given chunk name + * @param chnkName + * @return List of chunks with given name + */ + public ArrayList getGlobalChunkData(String chnkName) + { + return chunksData.get(chnkName); + } + + /** + * Get {@link ChunksData} for given chunk name + * @param chnkName + * @return List of data with given name + */ + public ArrayList getNonHeapChunkData(String chnkName) + { + return nonHeapChunksData.get(chnkName); + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/CommonGraphConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/CommonGraphConstants.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +/** + * Contains constants that are shared by multiple graph + * drawing related classes. + */ +public class CommonGraphConstants { + + /** + * Context menu title for action: Show Entire Graph + */ + public static final String SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE = "Show Entire Graph"; + /** + * Context menu title for action: Save graph... + */ + public static final String SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE = "Save graph..."; + /** + * Room reserved for Y-axis legend in X-axis direction. + */ + public static final int YLEGENDSPACE = 60; + /** + * Room reserved for X-axis legend in Y-axis direction. + */ + public static final int XLEGENDSPACE = 50; + /** + * Default line width for the graphs. + */ + protected static final int DEFAULT_GRAPH_LINE_WIDTH = 2; + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/DisksGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/DisksGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,431 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.DiskOverview; +import com.nokia.s60tools.swmtanalyser.data.SystemData; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * This class contains all needed logic to paint data related to Disks. + */ +public class DisksGraph extends GenericGraph { + + private HashMap> totalDiskData = new HashMap>(); + private HashMap pointsData = new HashMap(); + + private double visY; + private double multiplier; + + private int [] Ram_Used_Values; + private int [] Ram_Total_Values; + private ArrayList sysData; + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics) + */ + public void paint(Graphics graphics) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START"); + + // Storing original graphics settings + Color origColor = graphics.getForegroundColor(); + int origLineWidth = graphics.getLineWidth(); + + int [] listX = this.calculateTimeIntervals(); + + this.lastSampleTime = listX[listX.length-1]; + + if(this.getEvent().equals(EventTypes.RAM_USED) || this.getEvent().equals(EventTypes.RAM_TOTAL)) + { + if(this.getEvent().equals(EventTypes.RAM_USED)) + { + valuesToBePlotted = Ram_Used_Values; + } + else if(this.getEvent().equals(EventTypes.RAM_TOTAL)) + { + valuesToBePlotted = Ram_Total_Values; + } + + if(valuesToBePlotted == null) + return; + + int [] points = new int[valuesToBePlotted.length *2]; + + double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + + for (int i = 0, j = 0; i < valuesToBePlotted.length; i++) + { + points[j++] = (int)(listX[i]/getScale()); + + points[j] =(int) (visY - valuesToBePlotted[i] /multiplier); + + if (points[j] < 0) + points[j] = 0; + + j++; + } + + graphics.setForegroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); + graphics.drawPolyline(points); + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, points); + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + + if(this.getEvent().equals(EventTypes.RAM_USED)) + { + pointsData.put("RAM Used", line); + } + else if(this.getEvent().equals(EventTypes.RAM_TOTAL)) + { + pointsData.put("RAM Total", line); + } + + } + else{ + ArrayList disksList = this.getUserSelectedItems(); + + if(disksList == null) + return; + + int k=0; + + for(String disk: disksList){ + + ArrayList data = totalDiskData.get(disk); + + valuesToBePlotted = new int[data.size()]; + + for(int i =0; i= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + + String legend = ""; + + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + Point extent = gc.stringExtent(legend); + + gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1); + + if (y >= previousBottom) + { + gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + + final Image image = this.getVerticalLabel("Bytes"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -(int)visY/3, 1); + + transform.dispose(); + gc.dispose(); + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData() + */ + public void prepareData() { + + EventTypes event = this.getEvent(); + if(this.getEvent().equals(EventTypes.RAM_USED) || this.getEvent().equals(EventTypes.RAM_TOTAL)) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + sysData = utils.getSystemDataFromAllCycles(this.getCyclesData()); + int [] eventVals; + + switch(event) + { + case RAM_USED: + eventVals = getRamUsedMemFromSysData(sysData); + break; + case RAM_TOTAL: + eventVals = getRamTotalMemFromSysData(sysData); + break; + default: + eventVals = new int[1]; + break; + } + + int maxValue = calculateMaxValue(eventVals); + + if(maxValue > maxBytes){ + maxBytes = maxValue; + } + + return; + } + fetchEntireDataForSelectedDisks(); + + for(String disk:getUserSelectedItems()) + { + ArrayList data = totalDiskData.get(disk); + + int[] eventValues = new int[data.size()]; + for(int i =0; i maxBytes){ + maxBytes = maxValue; + } + } + + } + + } + + private void fetchEntireDataForSelectedDisks() + { + ArrayList selectedDisks = this.getUserSelectedItems(); + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + for(String disk:selectedDisks) + { + ArrayList diskData = utils.getUsedMemoryAndSizesForDisk(disk, this.getCyclesData()); + totalDiskData.put(disk, diskData); + } + } + + private int getEventValueFromDisksData(DiskOverview diskData, EventTypes event) + { + int value = 0; + + switch(event) + { + case DISK_USED_SIZE: + value = (int) diskData.getUsedSize(); + break; + case DISK_TOTAL_SIZE: + value = (int) diskData.getSize(); + break; + default: + value = 0; + break; + } + + return value; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int) + */ + public String getToolTipText(int x, int y) + { + if(y > (int)visY) + return null; + + String text = ""; + double xValue = x + timeOffset; + int scaledX = (int)(xValue * getScale()); + + double valY = visY - y; + double bytes = valY * multiplier; + + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + text += scaledX + " s, " + scaledY; + + if(this.getEvent().equals(EventTypes.RAM_USED)) + { + Polyline line = pointsData.get("RAM Used"); + + if(line != null && line.containsPoint(x, y)) + text += "\n RAM Used"; + } + else if (this.getEvent().equals(EventTypes.RAM_TOTAL)) + { + Polyline line = pointsData.get("RAM Total"); + + if(line != null && line.containsPoint(x, y)) + text += "\n RAM Total"; + } + else + { + for(String disk: getUserSelectedItems()) + { + Polyline line = pointsData.get(disk); + + if(line != null && line.containsPoint(x, y)) + text += "\n" + disk; + } + } + + return text; + } + + + private int [] getRamUsedMemFromSysData(ArrayList sysData) + { + Ram_Used_Values = new int[sysData.size()]; + + for(int i=0; i sysData) + { + Ram_Total_Values = new int[sysData.size()]; + + for(int i=0; i getDiskData(String diskName) + { + return totalDiskData.get(diskName); + } + + /** + * Get {@link SystemData} + * @return system data + */ + public ArrayList getSystemData() + { + return sysData; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GenericGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GenericGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,385 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.text.DecimalFormat; +import java.util.ArrayList; + +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.KernelElements; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; + +public abstract class GenericGraph { + + // + // Constants + // + + /** + * Mega Byte format + */ + protected static final DecimalFormat MBformat = new DecimalFormat("#####.0"); + /** + * Byte format + */ + protected static final DecimalFormat Bytes_Format = new DecimalFormat("#####.##"); + /** + * Label for time in X axis + */ + protected static final String TIME_X_AXIS_LABEL = "Time (h:min:s)"; + + // + // Members + // + private EventTypes event; + private ArrayList userSelectedItems; + private ArrayList colors; + private ParsedData parsedData; + private double scale = 1.0; + + + protected int maxBytes = 10; + protected int[] valuesToBePlotted = null; + protected int lastSampleTime = 0; + protected int visualSizeY = 0; + protected int timeOffset = 0; + + /** + * Event types to map the event names into corresponding event enumerators. + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils#EVENT_NAMES_ARR + */ + public enum EventTypes {GLOBAL_DATA_SIZE, NON_HEAP_CHUNK_SIZE, DISK_USED_SIZE, DISK_TOTAL_SIZE, NO_OF_FILES, MAX_HEAP_SIZE, HEAP_SIZE, HEAP_ALLOC_SPACE, HEAP_FREE_SPACE, HEAP_ALLOC_CELL_COUNT, HEAP_FREE_CELL_COUNT, HEAP_FREE_SLACK, NO_OF_PSHANDLES, RAM_USED, RAM_TOTAL, SYSTEM_DATA}; + + private static ArrayList graphableKernels = new ArrayList(); + + /** + * Get graphable kernels + * @return the graphable kernels + */ + public static ArrayList getGraphableKernels() { + return graphableKernels; + } + + static{ + graphableKernels.add("Number of Processes"); + graphableKernels.add("Number of Threads"); + graphableKernels.add("Number of Timers"); + graphableKernels.add("Number of Semaphores"); + graphableKernels.add("Number of Servers"); + graphableKernels.add("Number of Sessions"); + graphableKernels.add("Number of Chunks"); + graphableKernels.add("Number of Msg. Queues"); + } + + /** + * Get cycles data + * @return cycle data + */ + public ParsedData getCyclesData() { + return parsedData; + } + + /** + * Set cycles data + * @param parsedData + */ + public void setCyclesData(ParsedData parsedData) { + this.parsedData = parsedData; + } + + /** + * Get event + * @return event + */ + public EventTypes getEvent() { + return event; + } + + /** + * Set event + * @param event + */ + public void setEvent(EventTypes event) { + this.event = event; + } + + /** + * Get items that user has been selected + * @return selected items + */ + public ArrayList getUserSelectedItems() { + return userSelectedItems; + } + + /** + * Set items that user has been selected + * @param userSelectedItems + */ + public void setUserSelectedItems(ArrayList userSelectedItems) { + this.userSelectedItems = userSelectedItems; + } + + /** + * Draw contents to drawn area + * @param graphics + */ + public abstract void paint(Graphics graphics); + /** + * Prepare data for drawing + */ + public abstract void prepareData(); + /** + * Draw headers to Y axis + * @param gc + */ + public abstract void paintYAxis(GC gc); + /** + * Get tool tip text for coordinates + * @param x + * @param y + * @return tooltip text + */ + public abstract String getToolTipText(int x, int y); + + /** + * Draw lines to background + * @param canvas + * @param graphics + */ + public void drawBackGroundLines(FigureCanvas canvas, Graphics graphics) + { + Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle()); + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200))); + graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170))); + + int height = canvas.getClientArea().height; + int width = canvas.getClientArea().width; + + graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50)); + + double visY = height - CommonGraphConstants.XLEGENDSPACE; + + int k = 0; + + for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++) + { + for (int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5) + { + if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1); + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + // horizontal lines + if (width > 0) + { + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + if (x % 100 == 0) + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + else + graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200))); + + for (int y = 0; y < height; y += 5) + { + if ((y / 5) % 2 == 0) + graphics.drawLine(x, y, x, y + 5); + } + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + double time = (double) x; + TimeObject timeObj = new TimeObject(time, scale); + graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13); + if(timeObj.hasDays()){ + graphics.drawString(timeObj.getDays(), x + 5, height - 26); + } + } + Image img = getVerticalLabel(TIME_X_AXIS_LABEL); + graphics.drawImage(img, width/2, height-30); + } + + /** + * Called when horizontal bar is moved in graphs, to set X location of current selection. + * @param x X-location of {@link org.eclipse.draw2d.geometry.Point} + */ + public void setScrolledXOrigin(int x) + { + this.timeOffset = x; + } + + /** + * Get cycle times from parsed data + * @return list of times + */ + protected int [] calculateTimeIntervals() + { + int [] time = new int[parsedData.getNumberOfCycles()]; + int prevDuration = 0; + time[0] = 0; + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + CycleData [] cycles = parsedData.getLogData(); + for(int i=1; i maxValue) + maxValue = values[i]; + } + + return maxValue; + } + + /** + * Get colors + * @return colors + */ + public ArrayList getColors() { + return colors; + } + + /** + * Set colors + * @param colors + */ + public void setColors(ArrayList colors) { + this.colors = colors; + } + + /** + * Get label for vertical axis + * @param name + * @return label + */ + protected Image getVerticalLabel(String name) + { + return GraphsUtils.getVerticalLabel(name, 110, 15, 9); + } + + /** + * Get scale + * @return scale + */ + public double getScale() { + return scale; + } + + /** + * Set scale + * @param scale + */ + public void setScale(double scale) { + this.scale = scale; + } + + /** + * Set visual size + * @param height + */ + public void setVisualSize(int height) + { + this.visualSizeY = height; + } + + /** + * Get count for wanted item + * @param item + * @param kernelsList + * @return count of items wanted + */ + protected int [] getValuesForGivenKerenelElement(String item, ArrayList kernelsList) + { + int [] values = new int[kernelsList.size()]; + + int index = graphableKernels.indexOf(item); + + for(int i=0; i> heapData = new HashMap>(); + private HashMap> globalDataChunks = new HashMap>(); + private HashMap> nonHeapChnksData = new HashMap>(); + private HashMap> disksData = new HashMap>(); + private HashMap valuesForSelectedItems = new HashMap(); + private HashMap pointsData = new HashMap(); + + private ArrayList systemData = new ArrayList(); + private ArrayList kernelData = new ArrayList(); + + private ArrayList graphedItemsInput = new ArrayList(); + private ParsedData parsedData = new ParsedData(); + + private FigureCanvas yAxis; + private int maxBytes = 10; + private int maxCount = 10; + private double scale = 1.0; + private int timeOffset = 0; + + private double visY; + private FigureCanvas figureCanvas; + + private static DecimalFormat MBformat = new DecimalFormat("#####.0"); + private static DecimalFormat Bytes_Format = new DecimalFormat("#####.##"); + + private int [] timeSamples; + private int lastTimeSample; + private FigureCanvas numberAxis; + + private boolean scalingNeeded; + + private IAction showEntireGraph; + private IAction saveGraph; + + /** + * Constructor + * @param composite + */ + public GraphForAllEvents(Composite composite) + { + this.parentComposite = composite; + } + + /** + * Set graphed items + * @param input + */ + public void setGraphedItemsInput(ArrayList input) + { + this.graphedItemsInput = input; + } + /** + * Set heap data + * @param thName + * @param values + */ + public void setHeapSizeForThread(String thName, ArrayList values) + { + heapData.put(thName, values); + } + + /** + * Set global data chunks + * @param chnkName + * @param values + */ + public void setGlobalChunkSizeForChunk(String chnkName, ArrayList values) + { + globalDataChunks.put(chnkName, values); + } + + /** + * Set non heap chunk data + * @param chnkName + * @param values + */ + public void setNonHeapChunkSizeForChunk(String chnkName, ArrayList values) + { + nonHeapChnksData.put(chnkName, values); + } + + /** + * Set disk data + * @param diskName + * @param values + */ + public void setDiskData(String diskName, ArrayList values) + { + disksData.put(diskName, values); + } + + /** + * Set cycles data + * @param cyclesData + */ + public void setInputCyclesData(ParsedData cyclesData) + { + this.parsedData = cyclesData; + timeSamples = this.calculateTimeIntervals(); + lastTimeSample = timeSamples[timeSamples.length-1]; + } + + /** + * Set kernel data + * @param kernelData + */ + public void setKernelData(ArrayList kernelData) + { + this.kernelData = kernelData; + } + + /** + * Set System data + * @param sysData + */ + public void setSystemData(ArrayList sysData) + { + this.systemData = sysData; + } + + /** + * Create Graphed items area + */ + public void constructGraphArea() + { + //Prepare data + prepareData(); + + if(parsedData == null || parentComposite == null) + return; + + Control [] children = parentComposite.getChildren(); + + if(children != null) + { + for(Control child:children) + child.dispose(); + } + + scalingNeeded = true; + timeOffset = 0; + + Composite parent = new Composite(parentComposite, SWT.NONE); + parent.setLayout(new FormLayout()); + + yAxis = new FigureCanvas(parent); + + numberAxis = new FigureCanvas(parent); + figureCanvas = new FigureCanvas(parent); + FormData formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.width = 50; + numberAxis.setLayoutData(formData); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(numberAxis); + formData.width = 60; + yAxis.setLayoutData(formData); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT); + formData.right = new FormAttachment(100); + + figureCanvas.setLayoutData(formData); + + yAxis.setBackground(ColorConstants.white); + numberAxis.setBackground(ColorConstants.white); + + yAxis.addPaintListener(new PaintListener() + { + public void paintControl(PaintEvent event) { + GC localGC = event.gc; + + org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea(); + + visY = rect.height - CommonGraphConstants.XLEGENDSPACE; + + int countOfYAxisLabels = 10; + double yIncrement = visY / countOfYAxisLabels; + int previousBottom = 0; + + double multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + + for (int k = countOfYAxisLabels; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + String legend = ""; + + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + Point extent = localGC.stringExtent(legend); + + localGC.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, 60, (int)y + 1); + + if (y >= previousBottom) + { + localGC.drawString(legend, 60 - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + localGC.setLineWidth(2); + localGC.drawLine(CommonGraphConstants.YLEGENDSPACE, 0, 60, rect.height); + + final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Bytes"); + + localGC.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + localGC.setTransform(transform); + localGC.drawImage(image, -(int)visY/3, 1); + + transform.dispose(); + localGC.dispose(); + } + }); + + numberAxis.addPaintListener(new PaintListener() + { + public void paintControl(PaintEvent event) { + + GC localGC = event.gc; + org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea(); + visY = rect.height - CommonGraphConstants.XLEGENDSPACE; + double yIncrement = visY / 10; + int previousBottom = 0; + double multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + int yValue = (int)(yIncrement * multiplier) * k; + String legend = yValue + ""; + Point extent = localGC.stringExtent(legend); + localGC.drawLine(50 - 3, (int)y + 1, 50, (int)y + 1); + if (y >= previousBottom) + { + localGC.drawString(legend, 50 - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + localGC.setLineWidth(2); + localGC.drawLine(50, 0, 50, rect.height); + + final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Count"); + localGC.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + localGC.setTransform(transform); + localGC.drawImage(image, -(int)visY/3, 10); + + transform.dispose(); + localGC.dispose(); + + } + }); + + + figureCanvas.setBackground(ColorConstants.white); + Panel panel = new Panel() + { + public void paint(Graphics graphics) + { + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "GraphForAllEvents/Panel/paint START"); + + drawBackGroundLines(figureCanvas,graphics); + paintData(graphics); + + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "GraphForAllEvents/Panel/paint END"); + + } + }; + + panel.setLayoutManager(new FlowLayout()); + figureCanvas.setContents(panel); + figureCanvas.addMouseMoveListener(this); + + final ScrollBar horizontalBar = figureCanvas.getHorizontalBar(); + horizontalBar.addSelectionListener(new SelectionListener() + { + + public void widgetDefaultSelected(SelectionEvent arg0) { + + } + + public void widgetSelected(SelectionEvent event) { + timeOffset = figureCanvas.getViewport().getViewLocation().x; + figureCanvas.redraw(); + + } + + }); + + figureCanvas.addControlListener(new ControlAdapter() + { + public void controlResized(ControlEvent e) { + horizontalBar.setPageIncrement(figureCanvas.getBounds().width); + + if(scalingNeeded) + { + zoomGraph(); + scalingNeeded = false; + } + yAxis.redraw(); + numberAxis.redraw(); + figureCanvas.redraw(); + + } + }); + + zoomGraph(); + hookContextMenu(); + parentComposite.layout(true); + } + + /** + * Adds Pop-Up menu items on th graph area. + * + */ + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(figureCanvas); + figureCanvas.setMenu(menu); + } + + protected void fillContextMenu(IMenuManager manager) { + zoomIn = new Action() + { + public void run() + { + zoomIn(); + } + { + this.setText(ZOOM_IN_CONTEXT_MENU_TITLE); + } + }; + + zoomOut = new Action() + { + public void run() + { + zoomOut(); + } + { + this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE); + } + }; + showEntireGraph = new Action() + { + public void run() + { + zoomGraph(); + } + { + this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + saveGraph = new Action() + { + public void run() + { + GraphsUtils.saveGraph(parentComposite); + } + { + this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + + copy = new CopyImageToClipboardAction(this); + + manager.add(zoomIn); + manager.add(new Separator()); + manager.add(zoomOut); + manager.add(new Separator()); + manager.add(showEntireGraph); + manager.add(saveGraph); + manager.add(copy); + + // Finally updating action states + updateViewActionEnabledStates(); + + } + + /** + * Sets enabled/disabled states for actions commands + * on this view, based on the current application state. + * This method should be called whenever an operation is + * started or stopped that might have effect on action + * button states. + */ + private void updateViewActionEnabledStates() { + setEnableState(zoomIn, !(this.scale == GraphsUtils.nextScale(scale, false))); + boolean zoomOutEnableCondition1 = !(this.scale == GraphsUtils.nextScale(scale, true)); + boolean zoomOutEnableCondition2 = !(this.lastTimeSample / this.scale <= figureCanvas.getClientArea().width); + setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn() + */ + protected void zoomIn() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "GraphForAllEvents - Zoom In"); + //Preconditions checked already in updateViewActionEnabledStates + this.scale = GraphsUtils.nextScale(scale, false); + figureCanvas.redraw(); + setNewSize(); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut() + */ + protected void zoomOut() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "GraphForAllEvents - Zoom Out"); + //Preconditions checked already in updateViewActionEnabledStates + this.scale = GraphsUtils.nextScale(this.scale, true); + setNewSize(); + } + + /** + * This method zoom in the graph area to the maximum possible scale + * and then zooms out, so that it fits in the canvas area + */ + private void zoomGraph() + { + int width = figureCanvas.getClientArea().width; + + if(width <=0 ) + return; + + double new_scale = this.scale; + + double prevNew = new_scale; + + //first zoom in until it is too big to fit + while (this.lastTimeSample / new_scale <= width) + { + new_scale = GraphsUtils.nextScale(new_scale, false); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + } + // now zoom out until it just fits + while (this.lastTimeSample / new_scale > width) + { + new_scale = GraphsUtils.nextScale(new_scale, true); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + } + + if (new_scale == this.scale) + return; + + this.scale = new_scale; + setNewSize(); + } + + /** + * This method sets the size of the panel, when scale is changed. + * When graph extends beyond visible area, horizontal scroll bar appears automatically. + */ + private void setNewSize() + { + int lastSample = this.lastTimeSample; + + int prefSize = (int)(lastSample/scale); + + timeOffset = 0; + Panel panel = (Panel)(figureCanvas.getContents()); + panel.setPreferredSize(prefSize + 100, 0); + + if (prefSize >= figureCanvas.getClientArea().width) { + timeOffset = figureCanvas.getViewport().getViewLocation().x; + panel.setSize(prefSize + 100, 0); + } + + } + + /** + * @param canvas + * @param graphics + */ + private void drawBackGroundLines(FigureCanvas canvas, Graphics graphics) + { + Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle()); + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200))); + graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170))); + + int height = canvas.getClientArea().height; + int width = canvas.getClientArea().width; + + graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50)); + + double visY = height - CommonGraphConstants.XLEGENDSPACE; + + int k = 0; + + for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++) + { + for(int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5) + { + if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1); + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + // horizontal lines + if (width > 0) + { + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + if (x % 100 == 0) + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + else + graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200))); + + for (int y = 0; y < height; y += 5) + { + if ((y / 5) % 2 == 0) + graphics.drawLine(x, y, x, y + 5); + } + + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + double time = (double) x; + TimeObject timeObj = new TimeObject(time, scale); + graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13); + if(timeObj.hasDays()){ + graphics.drawString(timeObj.getDays(), x + 5, height - 26); + } + } + Image img = GraphsUtils.getDoubleYAxisVerticalLabel(GenericGraph.TIME_X_AXIS_LABEL); + graphics.drawImage(img, width/2, height-30); + + } + private void paintData(Graphics graphics) + { + DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData START"); + + Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle()); + + if(this.graphedItemsInput == null) + return; + + int [] listX = timeSamples; + + for(GraphedItemsInput item:graphedItemsInput) + { + int [] valuesToBePlotted = valuesForSelectedItems.get(item); + + if(valuesToBePlotted == null) + continue; + + int [] points = new int[valuesToBePlotted.length *2]; + + double visY = canvasRect.height - CommonGraphConstants.XLEGENDSPACE; + + EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent()); + + double multiplier = 1; + boolean isThreadEvent = false; + boolean isChunkEvent = false; + + switch (eventType) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case SYSTEM_DATA: + multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + break; + default: + multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + break; + } + + switch(eventType) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case MAX_HEAP_SIZE: + case HEAP_SIZE: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case HEAP_ALLOC_SPACE: + case HEAP_FREE_SLACK: + case HEAP_FREE_SPACE: + isThreadEvent = true; + break; + case GLOBAL_DATA_SIZE: + case NON_HEAP_CHUNK_SIZE: + isChunkEvent = true; + break; + } + + // Scaling values before actual drawing + for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++) + { + // Scaling X-coordinate value + int x_point = (int)(listX[i]/scale); + + // Scaling positive Y-coordinate value and ... + int y_point = NOT_DRAWN_DATA_POINT; // ... zero and negative ones are not drawn + if (valuesToBePlotted[i] > 0){ + y_point = (int) (visY - valuesToBePlotted[i] /multiplier); + } + + // Storing value + points[j] = x_point; + points[++j] = y_point; + } + + // Storing original values + Color origColor = graphics.getForegroundColor(); + int origLineWidth = graphics.getLineWidth(); + int origLineStyle = graphics.getLineStyle(); + + graphics.setForegroundColor(item.getColor()); + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + + if(isThreadEvent){ + paintThreadEvents(graphics, points, item.getName()); + } + else if(isChunkEvent) + { + paintChunkEvents(graphics, points, item.getName(), item.getEvent()); + } + else{ + graphics.drawPolyline(points); + } + + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, points); + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + pointsData.put(item, line); + + // Restoring original values + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + graphics.setLineStyle(origLineStyle); + } + + DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData END"); + } + + /** + * prepare data for drawing + */ + private void prepareData() + { + maxBytes = 10; + maxCount = 10; + + for(GraphedItemsInput obj:graphedItemsInput) + { + String itemName = obj.getName(); + String event = obj.getEvent(); + + int [] values = getValuesForGivenItemAndEvent(itemName, event); + + if(values == null) + { + continue; + } + valuesForSelectedItems.put(obj, values); + + int maxValue = calculateMaxValue(values); + + EventTypes eventType = GraphsUtils.getMappedEvent(event); + + switch(eventType) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case SYSTEM_DATA: + if(maxValue > maxCount){ + maxCount = maxValue; + } + break; + default: + if(maxValue > maxBytes){ + maxBytes = maxValue; + } + break; + } + } + } + + private int [] getValuesForGivenItemAndEvent(String itemName, String event) + { + EventTypes eventType = GraphsUtils.getMappedEvent(event); + int [] valuesForSelectedItem = null; + + switch(eventType) + { + case GLOBAL_DATA_SIZE: + valuesForSelectedItem = getGlobalChunkSize(itemName, globalDataChunks); + break; + case NON_HEAP_CHUNK_SIZE: + valuesForSelectedItem = getNonHeapChunkSize(itemName, nonHeapChnksData); + break; + case DISK_USED_SIZE: + valuesForSelectedItem = getUsedDiskSize(itemName, disksData); + break; + case DISK_TOTAL_SIZE: + valuesForSelectedItem = getTotalDiskSize(itemName, disksData); + break; + case NO_OF_FILES: + valuesForSelectedItem = getAllFiles(itemName, heapData); + break; + case MAX_HEAP_SIZE: + valuesForSelectedItem = getMaxHeapSize(itemName, heapData); + break; + case HEAP_SIZE: + valuesForSelectedItem = getHeapSize(itemName, heapData); + break; + case HEAP_ALLOC_SPACE: + valuesForSelectedItem = getHeapAllocSpace(itemName, heapData); + break; + case HEAP_FREE_SPACE: + valuesForSelectedItem = getHeapFreeSpace(itemName, heapData); + break; + case HEAP_ALLOC_CELL_COUNT: + valuesForSelectedItem = getHeapAllocCellsCount(itemName, heapData); + break; + case HEAP_FREE_CELL_COUNT: + valuesForSelectedItem = getHeapFreeCellsCount(itemName, heapData); + break; + case HEAP_FREE_SLACK: + valuesForSelectedItem = getHeapFreeSlack(itemName, heapData); + break; + case NO_OF_PSHANDLES: + valuesForSelectedItem = getPSHandles(itemName, heapData); + break; + case RAM_USED: + valuesForSelectedItem = getUsedRam(systemData); + break; + case RAM_TOTAL: + valuesForSelectedItem = getTotalRam(systemData); + break; + case SYSTEM_DATA: + valuesForSelectedItem = getDataForSystemElement(itemName, kernelData); + break; + } + return valuesForSelectedItem; + } + + private int[] getDataForSystemElement(String itemName, ArrayList kernelData) + { + SystemDataGraph sysGraph = new SystemDataGraph(); + return sysGraph.getValuesForGivenKerenelElement(itemName, kernelData); + } + private int[] getTotalRam(ArrayList systemData) { + + int [] totalRam = new int[systemData.size()]; + + for(int i=0; i < systemData.size(); i++) + { + totalRam[i] = (int)systemData.get(i).getTotalMemory(); + } + return totalRam; + } + + private int[] getUsedRam(ArrayList systemData) { + int [] usedRam = new int[systemData.size()]; + + for(int i=0; i < systemData.size(); i++) + { + usedRam[i] = (int)(systemData.get(i).getTotalMemory() - systemData.get(i).getFreeMemory()); + } + return usedRam; + } + + private int[] getPSHandles(String itemName, HashMap> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] psValues = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] freeSlack = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] freeCellsCount = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] allocCellsCount = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] heapFreeSpace = new int [totalData.size()]; + + for(int i=0; i> heapData) { + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] heapAllocSpace = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] heapSize = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] maxHeapSize = new int [totalData.size()]; + + for(int i=0; i> heapData) { + + ArrayList totalData = heapData.get(itemName); + + if(totalData != null) + { + int [] allFiles = new int [totalData.size()]; + + for(int i=0; i> disksData) { + + ArrayList totalData = disksData.get(itemName); + + if(totalData != null) + { + int [] diskSize = new int [totalData.size()]; + + for(int i=0; i> disksData) { + + ArrayList totalData = disksData.get(itemName); + + if(totalData != null) + { + int [] diskSize = new int [totalData.size()]; + + for(int i=0; i> nonHeapChnksData) { + + ArrayList totalData = nonHeapChnksData.get(itemName); + + if(totalData != null) + { + int [] chunkSizes = new int[totalData.size()]; + + for(int i=0; i> glodData) { + + ArrayList totalData = glodData.get(itemName); + + if(totalData != null) + { + int [] chnkSize = new int [totalData.size()]; + + for(int i=0; i maxValue) + maxValue = values[i]; + } + return maxValue + 1000; + } + + private int [] calculateTimeIntervals() + { + CycleData [] cyclesData = parsedData.getLogData(); + int [] time = new int[cyclesData.length]; + int prevDuration = 0; + time[0] = 0; + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + for(int i=1; i (int)visY) + figureCanvas.setToolTipText(null); + + String text = ""; + double xValue = x + timeOffset; + int scaledX = (int)(xValue * scale); + double valY = visY - y; + + double count_multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + double bytes_multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + + String scaledY_1 = getFormattedValues(valY * bytes_multiplier); + int scaledY_2 = (int)(Math.round((valY * count_multiplier))); + + text += scaledX + "s " + scaledY_1 + " , " + scaledY_2 ; + + for(GraphedItemsInput item:graphedItemsInput) + { + Polyline line = pointsData.get(item); + + if(line != null && line.containsPoint(x, y)) + { + text += "\n" + item.getName(); + + if(!item.getName().equalsIgnoreCase(item.getEvent())) + text += " -- " + item.getEvent(); + } + } + + figureCanvas.setToolTipText(text); + figureCanvas.redraw(); + } + + private String getFormattedValues(double bytes) + { + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + return scaledY; + } + + /** + * Clear all data from items + */ + public void removeAllData() + { + heapData.clear(); + globalDataChunks.clear(); + nonHeapChnksData.clear(); + disksData.clear(); + systemData.clear(); + kernelData.clear(); + valuesForSelectedItems.clear(); + pointsData.clear(); + } + + /** + * Paints thread related events. + * @param graphics graphics context + * @param points points to draw in array [X0, Y0, X1, Y1, ... ] with zero Y-values pruned out + * @param threadName name of the thread + */ + private void paintThreadEvents(Graphics graphics, int [] points, String threadName) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + ArrayList data = utils.getHeapDataFromAllCycles(threadName, parsedData); + + boolean handleDeleted = false; + + List> ListOfSolidLinePoints = new ArrayList>(); + ArrayList solidLinePoints = new ArrayList(); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "thread: " + threadName); + + for (int i = 0, j = 0; i < parsedData.getNumberOfCycles(); i++, j++){ + + int x_point = points[j]; + int y_point = points[++j]; + + if(y_point == NOT_DRAWN_DATA_POINT){ + continue; // There is no valid data for this cycle + } + + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Plotting data of threads"); + if(!handleDeleted){ + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point); + } + + ThreadData threadData = data.get(i); + + if(threadData.isKernelHandleDeleted() && !handleDeleted){ + handleDeleted = true; + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + solidLinePoints = new ArrayList(); + } + + if(handleDeleted && threadData.getStatus() == CycleData.New) + { + handleDeleted = false; + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + } + + } + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + for(int i=0; i < ListOfSolidLinePoints.size(); i++) + { + int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i)); + + if(solidPts != null) + { + if(ListOfSolidLinePoints.size() > 1) + { + int instance_id = i+1; + graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15); + } + graphics.setLineStyle(SWT.LINE_SOLID); + graphics.drawPolyline(solidPts); + } + } + + } + + private void paintChunkEvents(Graphics graphics, int [] points, String item_name, String event) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + ArrayList data = utils.getHeapDataFromAllCycles(item_name, parsedData); + + boolean handleDeleted = false; + + List> ListOfSolidLinePoints = new ArrayList>(); + ArrayList solidLinePoints = new ArrayList(); + + for (int i = 0, j = 0; i < parsedData.getNumberOfCycles(); i++, j++) + { + int x_point = points[j]; + int y_point = points[++j]; + + if (y_point <= 0){ + // Not showing zero values to a user, not meaningful data + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "continued because value <= 0"); + continue; + } + + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Plotting data of threads"); + if(!handleDeleted){ + if(y_point > 0){ + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + getHandleStatus(i+1, item_name, event); + if(data.get(i).isKernelHandleDeleted() && !handleDeleted){ + handleDeleted = true; + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + solidLinePoints = new ArrayList(); + } + + if(handleDeleted && data.get(i).getStatus() == CycleData.New) + { + handleDeleted = false; + + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + } + + } + + if(solidLinePoints.size() > 0) + ListOfSolidLinePoints.add(solidLinePoints); + + for(int i=0; i < ListOfSolidLinePoints.size(); i++) + { + int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i)); + + if(solidPts != null) + { + if(ListOfSolidLinePoints.size() > 1) + { + int instance_id = i+1; + graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15); + } + graphics.setLineStyle(SWT.LINE_SOLID); + graphics.drawPolyline(solidPts); + } + } + + } + + private boolean getHandleStatus(int cycleNo, String chunkName, String event) + { + boolean status = false; + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + if(event.equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList glod_data = utils.getGLOBDataFromAllCycles(chunkName, parsedData); + + status = glod_data.get(cycleNo -1).isKernelHandleDeleted(); + } + else if(event.equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList chunks_data = utils.getChunkDataFromAllCycles(chunkName, parsedData); + + status = chunks_data.get(cycleNo -1).isKernelHandleDeleted(); + } + + return status; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage() + */ + public Image getImage() { + return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable() + */ + public Drawable getDrawable() { + return parentComposite; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GraphsUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GraphsUtils.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html". + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: + * + */ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; + +import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Graph utilities common to all graph types. + */ +public class GraphsUtils { + + // + // Constants + // + + /** + * Constant for no marker possibility. + */ + private static final int NO_MARKER = -1; + + /** + * Possible marker sizes from smallest to biggest value. + */ + private static final int[] MARKER_SIZES = { 4, 6, 8 }; + + /** + * Default marker size. + */ + private static final int DEFAULT_MARKER = MARKER_SIZES[2]; + + /** + * Array of event names used to map the event names into corresponding event + * enumerators. + * + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes + */ + private static final String[] EVENT_NAMES_ARR = { "Global data size", + "Non heap chunk size", "Disk used", "Disk total", "No of Files", + "Max size", "Heap size", "Heap allocated space", "Heap free space", + "Heap allocated cell count", "Heap free cell count", "Free slack", + "No of PS Handles", "RAM used", "RAM total", "System Data" }; + + /** + * Percentage of byte count to be graphed that is added extra reserve in + * order to show markers appropriately. + */ + private static final int MARKER_MARGIN_PERCENTAGE = 5; + + // + // Symbolic name constants for different byte units use in setting Y-axis + // value level according given maximum byte value + // + private static final int KILOBYTE = 1024; + private static final int MEGABYTE = 1024 * 1024; + + // + // Members + // + private static String imageFilename; + private static Composite parentComposite; + + /** + * Maps event names into corresponding enumerator type + * + * @param event + * event name + * @return enumerator constant corresponding to the given event + */ + public static EventTypes getMappedEvent(String eventName) { + int index = Arrays.asList(EVENT_NAMES_ARR).indexOf(eventName); + GenericGraph.EventTypes eventType = null; + + switch (index) { + case 0: + eventType = GenericGraph.EventTypes.GLOBAL_DATA_SIZE; + break; + case 1: + eventType = GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE; + break; + case 2: + eventType = GenericGraph.EventTypes.DISK_USED_SIZE; + break; + case 3: + eventType = GenericGraph.EventTypes.DISK_TOTAL_SIZE; + break; + case 4: + eventType = GenericGraph.EventTypes.NO_OF_FILES; + break; + case 5: + eventType = GenericGraph.EventTypes.MAX_HEAP_SIZE; + break; + case 6: + eventType = GenericGraph.EventTypes.HEAP_SIZE; + break; + case 7: + eventType = GenericGraph.EventTypes.HEAP_ALLOC_SPACE; + break; + case 8: + eventType = GenericGraph.EventTypes.HEAP_FREE_SPACE; + break; + case 9: + eventType = GenericGraph.EventTypes.HEAP_ALLOC_CELL_COUNT; + break; + case 10: + eventType = GenericGraph.EventTypes.HEAP_FREE_CELL_COUNT; + break; + case 11: + eventType = GenericGraph.EventTypes.HEAP_FREE_SLACK; + break; + case 12: + eventType = GenericGraph.EventTypes.NO_OF_PSHANDLES; + break; + case 13: + eventType = GenericGraph.EventTypes.RAM_USED; + break; + case 14: + eventType = GenericGraph.EventTypes.RAM_TOTAL; + break; + case 15: + eventType = GenericGraph.EventTypes.SYSTEM_DATA; + break; + } + + return eventType; + } + + /** + * Get next scale when zooming in or out + * @param scale + * @param bigger give true when zooming out and false when zooming in. + * @return next scale + */ + public static double nextScale(double scale, boolean bigger) { + double logScale = Math.log10(scale); + double floorLogScale = Math.floor(Math.log10(scale)); + double mostSignificantDigit = Math.rint(Math.pow(10, + (logScale - floorLogScale))); + double powerOfTen = Math.pow(10, floorLogScale); + + if (bigger) { + if (mostSignificantDigit < 2) { + mostSignificantDigit = 2; + } else if (mostSignificantDigit < 5) { + mostSignificantDigit = 5; + } else { + mostSignificantDigit = 10; + } + } else { + if (mostSignificantDigit > 5) { + mostSignificantDigit = 5; + } else if (mostSignificantDigit > 2) { + mostSignificantDigit = 2; + } else if (mostSignificantDigit > 1) { + mostSignificantDigit = 1; + } else { + mostSignificantDigit = 0.5; + } + } + + double result = mostSignificantDigit * powerOfTen; + + if (result < 0.1) + result = 0.1; + + return result; + } + + /** + * Save the given composite as an image to local file system. + * + * @param parent + */ + public static void saveGraph(Composite parent) { + parentComposite = parent; + FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), + SWT.SAVE); + dlg.setFilterExtensions(new String[] { "*.bmp", "*.png", "*.jpeg" }); + imageFilename = dlg.open(); + if (imageFilename == null) + return; + + Runnable p = new Runnable() { + public void run() { + GC gc = new GC(parentComposite); + Image image = new Image(Display.getCurrent(), parentComposite + .getClientArea().width, + parentComposite.getClientArea().height); + parentComposite.setFocus(); + gc.copyArea(image, 0, 0); + gc.dispose(); + ImageData data = image.getImageData(); + ImageLoader loader = new ImageLoader(); + loader.data = new ImageData[] { data }; + if (imageFilename != null) + loader.save(imageFilename, SWT.IMAGE_BMP); + image.dispose(); + } + }; + Display.getDefault().timerExec(500, p); + } + + /** + * Generate random color. + * + * @return a random color + */ + public static Color getRandomColor() { + Random rand = new Random(); + int r = rand.nextInt(255); + int g = rand.nextInt(255); + int b = rand.nextInt(255); + return new Color(Display.getCurrent(), r, g, b); + } + + /** + * Creates an image and writes the given text vertically on the image. This + * is used to represent the Y-axis names in the Analysis tab and Graphed + * events -graphs. Those graphs show double Y-axis and therefore layout + * differs from single Y-axis situation. + * + * @param axisLabelName + * name of the label + * @return vertical axis label image + */ + public static Image getDoubleYAxisVerticalLabel(String axisLabelName) { + return getVerticalLabel(axisLabelName, 90, 18, 10); + } + + /** + * Creates an image and writes the given text vertically on the image with + * given coordinates and font size. + * + * @param axisLabelName + * name of the label + * @param x + * x-coordinate + * @param y + * y-coordinate + * @param fontSize + * font size + * @return vertical axis label image + */ + public static Image getVerticalLabel(String axisLabelName, int x, int y, + int fontSize) { + final Image image = new Image(Display.getDefault(), x, y); + GC gc = new GC(image); + Font font = new Font(Display.getDefault(), Display.getDefault() + .getSystemFont().getFontData()[0].getName(), fontSize, SWT.BOLD); + gc.setFont(font); + gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(0, 0, 90, 15); + gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + gc.drawText(axisLabelName + " ->", 0, 0, true); + font.dispose(); + gc.dispose(); + return image; + } + + /** + * Draws markers to data points with current foreground color and marker + * size. + * + * @param graphics + * Graphics context + * @param points + * Data point array in format [ X0, Y0, X1, Y1, ... ] + */ + private static void drawMarkers(Graphics graphics, int[] points, + int markerSize) { + Color backgroundColor = graphics.getBackgroundColor(); + graphics.setBackgroundColor(graphics.getForegroundColor()); + for (int j = 0; j < points.length; j += 2) { + int width = markerSize; + int height = width; + int x = points[j] - (width / 2); + int y = points[j + 1] - (width / 2); + graphics.fillRectangle(x, y, width, height); + } + graphics.setBackgroundColor(backgroundColor); + } + + /** + * Resolving minimum space between subsequent X-coordinate data points. This + * method expects that there are at least 2 x,y pairs in the array + * + * @param points + * Data point array in format [ X0, Y0, X1, Y1, ... ] + * @return minimum space between subsequent X-coordinate data points + */ + private static int resolveMinumumXDelta(int[] points) { + int minDelta = points[2] - points[0]; + for (int i = 4; i < points.length; i += 2) { + int delta = points[i] - points[i - 2]; + if (delta < minDelta) { + minDelta = delta; + } + } + return minDelta; + } + + /** + * Draws markers to data points with current foreground color. Markers drawn + * only if there is enough room in X-axis to draw them between all + * individual data points. + * + * @param graphics + * Graphics context + * @param points + * Data point array in format [ X0, Y0, X1, Y1, ... ] + */ + public static void drawMarkers(Graphics graphics, int[] points) { + int markerSize = NO_MARKER; // By default not drawing markers if there + // is no room for them + // Checking deltas only if there is more than single point to draw + if (points.length > 2) { + // Resolving minimum space between subsequent X-coordinate data + // points + int minDelta = resolveMinumumXDelta(points); + // Resolving if there is at all need to draw markers + for (int i = MARKER_SIZES.length - 1; i >= 0; i--) { + int size = MARKER_SIZES[i]; + if (size < minDelta) { + markerSize = size; // Using this size in drawing + break; + } + } + // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "minDelta: " + minDelta); //$NON-NLS-1$ + } else { + // Using default marker in case there + markerSize = DEFAULT_MARKER; + } + // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "markerSize: " + markerSize); //$NON-NLS-1$ + // Drawing markers + if (markerSize != NO_MARKER) { + drawMarkers(graphics, points, markerSize); + } + } + + /** + * Gets nearest Y-legend bytes label from the given bytes + * + * @param bytes + * bytes number + * @return nearest Y-legend bytes label from the given bytes + */ + static public int prettyMaxBytes(int bytes) { + + // Adding some margin that makes possible to show also markers + int byteMarginForMarkers = (int) Math + .ceil((MARKER_MARGIN_PERCENTAGE / 100.0) * bytes); + bytes = bytes + byteMarginForMarkers; + + // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "prettyMaxBytes/bytes: " + bytes); //$NON-NLS-1$ + // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "byteMarginForMarkers: " + byteMarginForMarkers); //$NON-NLS-1$ + + // Before 10 KB limit using byte units are used Y-axis legend and + // therefore thousand is used as checkpoint limit instead if KILOBYTE + final int thousand = 1000; + + if (bytes < thousand) + bytes = thousand; + else if (bytes < 10 * thousand) + bytes = 10 * thousand; + else if (bytes < 20 * KILOBYTE) + bytes = 20 * KILOBYTE; + else if (bytes < 30 * KILOBYTE) + bytes = 30 * KILOBYTE; + else if (bytes < 50 * KILOBYTE) + bytes = 50 * KILOBYTE; + else if (bytes < 100 * KILOBYTE) + bytes = 100 * KILOBYTE; + else if (bytes < 150 * KILOBYTE) + bytes = 150 * KILOBYTE; + else if (bytes < 200 * KILOBYTE) + bytes = 200 * KILOBYTE; + else if (bytes < 300 * KILOBYTE) + bytes = 300 * KILOBYTE; + else if (bytes < 400 * KILOBYTE) + bytes = 400 * KILOBYTE; + else if (bytes < 500 * KILOBYTE) + bytes = 500 * KILOBYTE; + else if (bytes < 600 * KILOBYTE) + bytes = 600 * KILOBYTE; + else if (bytes < 700 * KILOBYTE) + bytes = 700 * KILOBYTE; + else if (bytes < 800 * KILOBYTE) + bytes = 800 * KILOBYTE; + else if (bytes < 900 * KILOBYTE) + bytes = 900 * KILOBYTE; + else if (bytes < 1000 * KILOBYTE) + bytes = 1000 * KILOBYTE; + else if (bytes < 1 * MEGABYTE) + bytes = 1 * MEGABYTE; + else if (bytes < 2 * MEGABYTE) + bytes = 2 * MEGABYTE; + else if (bytes < 3 * MEGABYTE) + bytes = 3 * MEGABYTE; + else if (bytes < 5 * MEGABYTE) + bytes = 5 * MEGABYTE; + else if (bytes < 10 * MEGABYTE) + bytes = 10 * MEGABYTE; + else if (bytes < 20 * MEGABYTE) + bytes = 20 * MEGABYTE; + else if (bytes < 30 * MEGABYTE) + bytes = 30 * MEGABYTE; + else if (bytes < 50 * MEGABYTE) + bytes = 50 * MEGABYTE; + else if (bytes < 100 * MEGABYTE) + bytes = 100 * MEGABYTE; + else if (bytes < 200 * MEGABYTE) + bytes = 200 * MEGABYTE; + else if (bytes < 300 * MEGABYTE) + bytes = 300 * MEGABYTE; + else if (bytes < 500 * MEGABYTE) + bytes = 500 * MEGABYTE; + else + bytes = ((bytes + 1024 * MEGABYTE - 1) / (1024 * MEGABYTE)) + * (1024 * MEGABYTE); + + return bytes; + } + + /** + * Converts list of Point objects into integer array. + * + * @param pointsList + * list of point objects + * @return points converted in 1-dimensional integer array. + */ + public static int[] convertPointListToIntArray(List pointsList) { + int[] integerArray = new int[pointsList.size() * 2]; + for (int i = 0, j = 0; i < pointsList.size(); i++, j += 2) { + Point pnt = pointsList.get(i); + integerArray[j] = pnt.x; + integerArray[(j + 1)] = pnt.y; + } + return integerArray; + } + + /** + * Gets nearest Y-legend count value label from the given input count value. + * Maximum count value handled is 999*100 i.e. 99900 counts. + * + * @param inputCountValue + * bytes input count value + * @return nearest Y-legend count value label from the given input count + * value. + * @return + */ + static public int roundToNearestNumber(int inputCountValue) { + int tempCount = inputCountValue; + + // Adding some safe margin for making sure that all data points with + // markers are drawn appropriately + int countMarginForMarkers = (int) Math + .ceil((MARKER_MARGIN_PERCENTAGE / 100.0) * tempCount); + tempCount = tempCount + countMarginForMarkers; + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, + "roundToNearestNumber/count: " + tempCount); //$NON-NLS-1$ + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, + "countMarginForMarkers: " + countMarginForMarkers); //$NON-NLS-1$ + + if (tempCount < 10) + tempCount = 10; + else if (tempCount < 50) + tempCount = 50; + else if (tempCount < 100) + tempCount = 100; + else { + for (int i = 2; i < 1000; i++) { + if (tempCount < (i * 100)) { + tempCount = i * 100; + break; + } + } + } + + return tempCount; + } + + /** + * Builds int array from Integer List object + * + * @param solidsList + * Integer list + * @return int array + */ + public static int[] CreateIntArrayFromIntegerList(List solidsList) { + int[] solidPts = new int[solidsList.size()]; + for (int j = 0; j < solidsList.size(); j++) { + solidPts[j] = solidsList.get(j); + } + return solidPts; + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/IGraphTypeSelectionListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/IGraphTypeSelectionListener.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +/** + * Implementors of this interface can be notified when selected graph type changes + * and implementor can do necessary actions based on the changed selection. + */ +public interface IGraphTypeSelectionListener { + + /** + * Listeners are notified when user changes the selection of threads, + */ + public void notifyThreadsSelection(); + /** + * Listeners are notified when user changes the selection of chunks. + */ + public void notifyChunksSelection(); + /** + * Listeners are notified when user changes the selection of disks. + */ + public void notifyDisksSelection(); + /** + * Listeners are notified when user changes the selection of elements to be shown. + */ + public void notifySysElementsSelection(); + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/LinearIssuesGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/LinearIssuesGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,812 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Panel; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Drawable; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.ScrollBar; + +import com.nokia.s60tools.swmtanalyser.analysers.ResultElements; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes; +import com.nokia.s60tools.ui.IImageProvider; +import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * Graph to be shown in Analysis tab. + */ +public class LinearIssuesGraph extends ZoomableGraph implements MouseMoveListener, IImageProvider { + + private static DecimalFormat MBformat = new DecimalFormat("#####.0"); + private static DecimalFormat Bytes_Format = new DecimalFormat("#####.##"); + + private HashMap pointsData = new HashMap(); + + private Composite parentComposite; + private FigureCanvas yAxis; + private FigureCanvas numberAxis; + private FigureCanvas figureCanvas; + private int[] timeSamples; + private ArrayList selectedIssues; + private boolean scalingNeeded; + + private double visY; + private int maxBytes = 10; + private int maxCount = 10; + private double scale = 1.0; + private int timeOffset = 0; + + /** + * Construction + * @param composite + */ + public LinearIssuesGraph(Composite composite) + { + this.parentComposite = composite; + } + + /** + * Draw the area + */ + public void constructGraphArea() + { + if(parentComposite == null) + return; + + Control [] children = parentComposite.getChildren(); + + if(children != null) + { + for(Control child:children) + child.dispose(); + } + + calculateMultiplier(); + scalingNeeded = true; + + Composite parent = new Composite(parentComposite, SWT.NONE); + parent.setLayout(new FormLayout()); + + yAxis = new FigureCanvas(parent); + + numberAxis = new FigureCanvas(parent); + figureCanvas = new FigureCanvas(parent); + FormData formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.width = 50; + numberAxis.setLayoutData(formData); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(numberAxis); + formData.width = 60; + yAxis.setLayoutData(formData); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT); + formData.right = new FormAttachment(100); + + figureCanvas.setLayoutData(formData); + + yAxis.setBackground(ColorConstants.white); + numberAxis.setBackground(ColorConstants.white); + + yAxis.addPaintListener(new PaintListener() + { + public void paintControl(PaintEvent event) { + GC localGC = event.gc; + + org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea(); + + visY = rect.height - CommonGraphConstants.XLEGENDSPACE; + + double yIncrement = visY / 10; + int previousBottom = 0; + + double multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + String legend = ""; + + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + Point extent = localGC.stringExtent(legend); + + localGC.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, 60, (int)y + 1); + + if (y >= previousBottom) + { + localGC.drawString(legend, 60 - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + localGC.setLineWidth(2); + localGC.drawLine(CommonGraphConstants.YLEGENDSPACE, 0, 60, rect.height); + + final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Bytes"); + + localGC.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + localGC.setTransform(transform); + localGC.drawImage(image, -(int)visY/3, 1); + + transform.dispose(); + localGC.dispose(); + } + }); + + numberAxis.addPaintListener(new PaintListener() + { + public void paintControl(PaintEvent event) { + + GC localGC = event.gc; + org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea(); + visY = rect.height - CommonGraphConstants.XLEGENDSPACE; + double yIncrement = visY / 10; + int previousBottom = 0; + double multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + int yValue = (int)(yIncrement * multiplier) * k; + String legend = yValue + ""; + Point extent = localGC.stringExtent(legend); + localGC.drawLine(50 - 3, (int)y + 1, 50, (int)y + 1); + if (y >= previousBottom) + { + localGC.drawString(legend, 50 - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + localGC.setLineWidth(2); + localGC.drawLine(50, 0, 50, rect.height); + + final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Count"); + localGC.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + localGC.setTransform(transform); + localGC.drawImage(image, -(int)visY/3, 10); + + transform.dispose(); + localGC.dispose(); + + } + }); + + + figureCanvas.setBackground(ColorConstants.white); + Panel panel = new Panel() + { + public void paint(Graphics graphics) + { +// DbgUtility.println(DbgUtility.PRIORITY_LOOP, "LinearIssuesGraph/Panel/paint START"); + + drawBackGroundLines(figureCanvas,graphics); + paintData(graphics); + +// DbgUtility.println(DbgUtility.PRIORITY_LOOP, "LinearIssuesGraph/Panel/paint END"); + } + }; + + panel.setLayoutManager(new FlowLayout()); + figureCanvas.setContents(panel); + figureCanvas.addMouseMoveListener(this); + + final ScrollBar horizontalBar = figureCanvas.getHorizontalBar(); + horizontalBar.addSelectionListener(new SelectionListener() + { + + public void widgetDefaultSelected(SelectionEvent arg0) { + + } + + public void widgetSelected(SelectionEvent event) { + timeOffset = figureCanvas.getViewport().getViewLocation().x; + figureCanvas.redraw(); + } + + }); + + figureCanvas.addControlListener(new ControlAdapter() + { + public void controlResized(ControlEvent e) { + horizontalBar.setPageIncrement(figureCanvas.getBounds().width); + + if(scalingNeeded) + { + zoomGraph(); + scalingNeeded = false; + } + //setNewSize(); + yAxis.redraw(); + numberAxis.redraw(); + figureCanvas.redraw(); + + } + }); + + zoomGraph(); + figureCanvas.redraw(); + hookContextMenu(); + parentComposite.layout(true); + } + + /** + * Draw background lines on the canvas + * @param canvas + * @param graphics + */ + public void drawBackGroundLines(FigureCanvas canvas, Graphics graphics) + { + Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle()); + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200))); + graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170))); + + int height = canvas.getClientArea().height; + int width = canvas.getClientArea().width; + + graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50)); + + double visY = height - CommonGraphConstants.XLEGENDSPACE; + + int k = 0; + + for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++) + { + for(int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5) + { + if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1); + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + // horizontal lines + if (width > 0) + { + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + if (x % 100 == 0) + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + else + graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200))); + + for (int y = 0; y < height; y += 5) + { + if ((y / 5) % 2 == 0) + graphics.drawLine(x, y, x, y + 5); + } + + } + } + + graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100))); + graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255))); + + for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50) + { + double time = (double) x; + TimeObject timeObj = new TimeObject(time, scale); + graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13); + if(timeObj.hasDays()){ + graphics.drawString(timeObj.getDays(), x + 5, height - 26); + } + } + Image img = GraphsUtils.getDoubleYAxisVerticalLabel(GenericGraph.TIME_X_AXIS_LABEL); + graphics.drawImage(img, width/2, height-30); + + } + + private void paintData(Graphics graphics) + { + DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData START"); + + try + { + Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle()); + + if(this.selectedIssues == null || selectedIssues.size() == 0) + return; + + int [] listX = timeSamples; + int k = 0; + + calculateMultiplier(); + + // Storing original graphics settings + Color origColor = graphics.getForegroundColor(); + int origLineWidth = graphics.getLineWidth(); + // Setting line width for drawing the graph + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + + for(ResultElements item:selectedIssues) + { + long [] valuesToBePlotted = item.getEventValues(); + + if(valuesToBePlotted == null) + continue; + + double visY = canvasRect.height - CommonGraphConstants.XLEGENDSPACE; + double multiplier = 1; + + EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent()); + + switch (eventType) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case SYSTEM_DATA: + multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + break; + default: + multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + break; + } + + List pointsList = new ArrayList(); + + for (int i = 0; i < valuesToBePlotted.length; i++) + { + // Showing only positive values + if(valuesToBePlotted[i] > 0){ + int scaledXPoint = (int)(listX[i]/scale); + int scaledYPoint = (int) (visY - valuesToBePlotted[i] /multiplier);; + Point p = new Point(scaledXPoint, scaledYPoint); + pointsList.add(p); + } + } + + // Converting point list into integer array for drawing + int[] points = GraphsUtils.convertPointListToIntArray(pointsList); + + graphics.setForegroundColor(item.getColor()); + + // Drawing graph + graphics.drawPolyline(points); + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, points); + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + pointsData.put(item, line); + + k++; + } + + // Restoring original settings + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + + }catch(Exception e){ + e.printStackTrace(); + } + } + + private void calculateMultiplier() + { + maxCount = 10; + maxBytes = 10; + + if(selectedIssues == null) + return; + + for(ResultElements item:selectedIssues) + { + long [] valuesToBePlotted = item.getEventValues(); + + if(valuesToBePlotted == null) + return; + + int maxValue = (int)calculateMaxValue(valuesToBePlotted); + + EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent()); + + switch (eventType) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case SYSTEM_DATA: + if(maxValue > maxCount) + maxCount = maxValue; + break; + default: + if(maxValue > maxBytes) + maxBytes = maxValue; + break; + } + } + + } + /** + * Adds Pop-Up menu items on th graph area. + * + */ + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(figureCanvas); + figureCanvas.setMenu(menu); + } + + protected void fillContextMenu(IMenuManager manager) { + zoomIn = new Action() + { + public void run() + { + zoomIn(); + } + { + this.setText(ZOOM_IN_CONTEXT_MENU_TITLE); + } + }; + + zoomOut = new Action() + { + public void run() + { + zoomOut(); + } + { + this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE); + } + }; + IAction showEntireGraph = new Action() + { + public void run() + { + zoomGraph(); + } + { + this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + IAction saveGraph = new Action() + { + public void run() + { + GraphsUtils.saveGraph(parentComposite); + } + { + this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + copy = new CopyImageToClipboardAction(this); + + manager.add(zoomIn); + manager.add(new Separator()); + manager.add(zoomOut); + manager.add(new Separator()); + manager.add(showEntireGraph); + manager.add(saveGraph); + manager.add(copy); + + // Finally updating action states + updateViewActionEnabledStates(); + + } + + /** + * Sets enabled/disabled states for actions commands + * on this view, based on the current application state. + * This method should be called whenever an operation is + * started or stopped that might have effect on action + * button states. + */ + private void updateViewActionEnabledStates() { + // Zoom In + setEnableState(zoomIn, !(this.scale == GraphsUtils.nextScale(scale, false))); + + // Zoom Out + boolean zoomOutEnableCondition1 = !(this.scale == GraphsUtils.nextScale(scale, true)); + int width = figureCanvas.getClientArea().width; + int lastTimeSample = timeSamples[timeSamples.length - 1]; + boolean zoomOutEnableCondition2 = !(lastTimeSample / this.scale <= width); + setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2); + } + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn() + */ + protected void zoomIn() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "LinearIssuesGraph - Zoom In"); + //Preconditions checked already in updateViewActionEnabledStates + this.scale = GraphsUtils.nextScale(scale, false); + figureCanvas.redraw(); + setNewSize(); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut() + */ + protected void zoomOut() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "LinearIssuesGraph - Zoom Out"); + //Preconditions checked already in updateViewActionEnabledStates + this.scale = GraphsUtils.nextScale(this.scale, true); + setNewSize(); + + } + /** + * This method zoom in the graph area to the maximum possible scale + * and then zooms out, so that it fits in the canvas area + */ + public void zoomGraph() + { + int width = figureCanvas.getClientArea().width; + + if(width <=0) + return; + + double new_scale = this.scale; + + double prevNew = new_scale; + + int lastSampleTime = timeSamples[timeSamples.length - 1]; + //first zoom in until it is too big to fit + while (lastSampleTime / new_scale <= width){ + new_scale = GraphsUtils.nextScale(new_scale, false); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + + } + // now zoom out until it just fits + while (lastSampleTime / new_scale > width){ + new_scale = GraphsUtils.nextScale(new_scale, true); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + } + + if (new_scale == this.scale) + return; + + this.scale = new_scale; + + setNewSize(); + } + + + /** + * This method sets the size of the panel, when scale is changed. + * When graph extends beyond visible area, horizontal scroll bar appears automatically. + * + */ + private void setNewSize() + { + int lastSample = timeSamples[timeSamples.length - 1]; + + int prefSize = (int)(lastSample/scale); + + timeOffset = 0; + Panel panel = (Panel)(figureCanvas.getContents()); + panel.setPreferredSize(prefSize + 100, 0); + + if (prefSize >= figureCanvas.getClientArea().width) { + timeOffset = figureCanvas.getViewport().getViewLocation().x; + panel.setSize(prefSize + 100, 0); + } + + } + + /** + * Set issues that user has been selected + * @param selectedIssues + */ + public void setSelectedIssues(ArrayList selectedIssues) { + this.selectedIssues = selectedIssues; + } + + /** + * Set parsed data + * @param logsData + */ + public void setLogData(ParsedData logsData) + { + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + timeSamples = utils.getTimeIntervalsFromLogData(logsData); + } + + private long calculateMaxValue(long [] values) + { + long maxValue = 0; + + for(int i=0; i maxValue) + maxValue = values[i]; + } + + return maxValue; + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + int x = event.x; + int y = event.y; + + if(y > (int)visY) + figureCanvas.setToolTipText(null); + + String text = ""; + double xValue = x + timeOffset; + int scaledX = (int)(xValue * scale); + double valY = visY - y; + + double count_multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY; + double bytes_multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY; + + String scaledY_1 = getFormattedValues(valY * bytes_multiplier); + int scaledY_2 = (int)(Math.round((valY * count_multiplier))); + + text += scaledX + "s " + scaledY_1 + " , " + scaledY_2 ; + + if(selectedIssues != null) + { + for(ResultElements item:selectedIssues) + { + Polyline line = pointsData.get(item); + + if(line != null && line.containsPoint(x, y)) + { + text += "\n" + item.getItemName(); + text += " -- " + item.getEvent(); + } + } + } + + figureCanvas.setToolTipText(text); + figureCanvas.redraw(); + } + + /** + * + * @param bytes represents value to be formatted. + * @return formatted value + */ + private String getFormattedValues(double bytes) + { + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + return scaledY; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage() + */ + public Image getImage() { + return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable() + */ + public Drawable getDrawable() { + return parentComposite; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SwmtGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SwmtGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,537 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.util.ArrayList; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Panel; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Drawable; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.ScrollBar; + +import com.nokia.s60tools.swmtanalyser.data.ChunksData; +import com.nokia.s60tools.swmtanalyser.data.DiskOverview; +import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks; +import com.nokia.s60tools.swmtanalyser.data.KernelElements; +import com.nokia.s60tools.swmtanalyser.data.ParsedData; +import com.nokia.s60tools.swmtanalyser.data.SystemData; +import com.nokia.s60tools.swmtanalyser.data.ThreadData; +import com.nokia.s60tools.ui.IImageProvider; +import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction; +import com.nokia.s60tools.util.debug.DbgUtility; +/** + * Graph to be shown in Graphs tab. + * + */ +public class SwmtGraph extends ZoomableGraph implements MouseMoveListener, IImageProvider { + + private FigureCanvas figureCanvas; + private FigureCanvas yAxis; + private ParsedData logData; + private Composite parentComposite; + + private boolean scaleNeedsUpdation = true; + private GenericGraph graph; + /** + * Constructor + * @param parent + */ + public SwmtGraph(Composite parent) + { + this.parentComposite = parent; + } + + /** + * Set parsed data + * @param parsedData + */ + public void setInputCyclesData(ParsedData parsedData) + { + this.logData = parsedData; + } + + /** + * Draw graph area + */ + public void constructGraphArea() + { + if(this.logData == null || this.logData.getLogData() == null || parentComposite == null) + return; + + Control [] children = parentComposite.getChildren(); + + if(children != null) + { + for(Control child:children) + child.dispose(); + } + + Composite parent = new Composite(parentComposite, SWT.NONE); + parent.setLayout(new FormLayout()); + + yAxis = new FigureCanvas(parent); + figureCanvas = new FigureCanvas(parent); + //figureCanvas.setSize(500, 450); + + FormData formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(0); + formData.width = 60; + yAxis.setLayoutData(formData); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.bottom = new FormAttachment(100); + formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT); + formData.right = new FormAttachment(100); + figureCanvas.setLayoutData(formData); + + yAxis.setBackground(ColorConstants.white); + yAxis.addPaintListener(new PaintListener() + { + + public void paintControl(PaintEvent event) { + + if(graph != null) + graph.paintYAxis(event.gc); + else + event.gc.dispose(); + + } + }); + + yAxis.addControlListener(new ControlAdapter(){ + public void controlResized(ControlEvent e) { + } + }); + + figureCanvas.setBackground(new Color(Display.getDefault(), new RGB(255,255,255))); + + Panel panel = new Panel() + { + public void paint(Graphics graphics) + { + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint START"); + + if(graph != null){ + graph.drawBackGroundLines(figureCanvas, graphics); + graph.paint(graphics); + } + else{ + erase(); + } + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint END"); + } + + + }; + + panel.setLayoutManager(new FlowLayout()); + + figureCanvas.setContents(panel); + + figureCanvas.addMouseMoveListener(this); + hookContextMenu(); + + final ScrollBar horizontalBar = figureCanvas.getHorizontalBar(); + + horizontalBar.addSelectionListener(new SelectionListener() + { + + public void widgetDefaultSelected(SelectionEvent arg0) { + + } + + public void widgetSelected(SelectionEvent event) { + + if(graph != null){ + graph.setScrolledXOrigin((figureCanvas.getViewport().getViewLocation().x)); + } + + figureCanvas.redraw(); + } + + }); + + figureCanvas.addControlListener(new ControlAdapter() + { + public void controlResized(ControlEvent e) { + horizontalBar.setPageIncrement(figureCanvas.getBounds().width); + + if(graph != null) + graph.setVisualSize(figureCanvas.getClientArea().height); + if(scaleNeedsUpdation) + { + zoomGraph(); + scaleNeedsUpdation = false; + } + + yAxis.redraw(); + figureCanvas.redraw(); + + } + }); + parentComposite.layout(); + + } + + /** + * Add Pop-Up Menus on Graph area. + * + */ + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(figureCanvas); + figureCanvas.setMenu(menu); + } + + protected void fillContextMenu(IMenuManager manager) { + + zoomIn = new Action() + { + public void run() + { + zoomIn(); + } + { + this.setText(ZOOM_IN_CONTEXT_MENU_TITLE); + } + }; + + zoomOut = new Action() + { + public void run() + { + zoomOut(); + } + { + this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE); + } + }; + IAction showEntireGraph = new Action() + { + public void run() + { + zoomGraph(); + } + { + this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + IAction saveGraph = new Action() + { + public void run() + { + GraphsUtils.saveGraph(parentComposite); + } + { + this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE); + } + }; + + copy = new CopyImageToClipboardAction(this); + + manager.add(zoomIn); + manager.add(new Separator()); + manager.add(zoomOut); + manager.add(new Separator()); + manager.add(showEntireGraph); + manager.add(saveGraph); + manager.add(copy); + + // Finally updating action states + updateViewActionEnabledStates(); + } + + /** + * This method acts as an interface for redrawig graphs + * @param graph + */ + public void redraw(GenericGraph graph) + { + this.graph = graph; + + try{ + + graph.setVisualSize(figureCanvas.getClientArea().height); + graph.prepareData(); + int [] timeSamples = graph.calculateTimeIntervals(); + graph.lastSampleTime = timeSamples[timeSamples.length -1]; + + //Zooms Graph to fit last sample value + zoomGraph(); + yAxis.redraw(); + figureCanvas.redraw(); + }catch(Exception e){ + e.printStackTrace(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + + if(this.graph != null) + { + this.figureCanvas.setToolTipText(this.graph.getToolTipText(event.x, event.y)); + this.figureCanvas.redraw(); + } + } + + /** + * Clear graph + */ + public void clearGraph() + { + this.graph = null; + try{ + yAxis.redraw(); + figureCanvas.redraw(); + + }catch(NullPointerException e){ + + } + } + + /** + * This method stores data corresponding to given item, so that it can be + * used in Graphed items view. + * @param itemName + * @param allEventsGraph + */ + public void storeClearedEventValues(String itemName, GraphForAllEvents allEventsGraph) + { + if(this.graph != null) + { + if(graph instanceof ThreadsGraph){ + ArrayList values = ((ThreadsGraph)(graph)).getDataForThread(itemName); + + allEventsGraph.setHeapSizeForThread(itemName, values); + + } + else if(graph instanceof ChunksGraph) + { + if(graph.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE)) + { + ArrayList values = ((ChunksGraph)(graph)).getGlobalChunkData(itemName); + + allEventsGraph.setGlobalChunkSizeForChunk(itemName, values); + } + else if(graph.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE)) + { + ArrayList values = ((ChunksGraph)(graph)).getNonHeapChunkData(itemName); + + allEventsGraph.setNonHeapChunkSizeForChunk(itemName, values); + } + + } + else if(graph instanceof DisksGraph) + { + if(graph.getEvent().equals(GenericGraph.EventTypes.DISK_USED_SIZE) || + graph.getEvent().equals(GenericGraph.EventTypes.DISK_TOTAL_SIZE)) + { + ArrayList values = ((DisksGraph)(graph)).getDiskData(itemName); + + allEventsGraph.setDiskData(itemName, values); + } + + else if(graph.getEvent().equals(GenericGraph.EventTypes.RAM_USED)|| + graph.getEvent().equals(GenericGraph.EventTypes.RAM_TOTAL)) + { + ArrayList sysData = ((DisksGraph)(graph)).getSystemData(); + + allEventsGraph.setSystemData(sysData); + } + } + else if(graph instanceof SystemDataGraph) + { + ArrayList kernelData = ((SystemDataGraph)(graph)).getKernelData(); + + allEventsGraph.setKernelData(kernelData); + } + } + } + + /** + * Sets enabled/disabled states for actions commands + * on this view, based on the current application state. + * This method should be called whenever an operation is + * started or stopped that might have effect on action + * button states. + */ + private void updateViewActionEnabledStates() { + //Zoom In + setEnableState(zoomIn, !(this.graph != null && graph.getScale() == GraphsUtils.nextScale(graph.getScale(), false))); + + //Zoom Out + if(this.graph != null) + { + boolean zoomOutEnableCondition1 = !(graph.getScale() == GraphsUtils.nextScale(graph.getScale(), true)); + int width = figureCanvas.getClientArea().width; + boolean zoomOutEnableCondition2 = !(graph.lastSampleTime / graph.getScale() <= width); + setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2); + } + else{ + setEnableState(zoomOut, false); + } + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn() + */ + protected void zoomIn() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom In"); + //Preconditions checked already in updateViewActionEnabledStates + graph.setScale(GraphsUtils.nextScale(graph.getScale(), false)); + setNewSize(); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut() + */ + protected void zoomOut() + { + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom Out"); + //Preconditions checked already in updateViewActionEnabledStates + graph.setScale(GraphsUtils.nextScale(graph.getScale(), true)); + setNewSize(); + } + + /** + * This method first zooms in graph to the maximum possible scale + * and zooms out so that it fits in the canvas area. + * + */ + public void zoomGraph() + { + int width = figureCanvas.getClientArea().width; + + if(width <=0 || this.graph == null) + return; + + double new_scale = graph.getScale(); + + double prevNew = new_scale; + + //first zoom in until it is too big to fit + while (graph.lastSampleTime / new_scale <= width){ + new_scale = GraphsUtils.nextScale(new_scale, false); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + + } + // now zoom out until it just fits + while (graph.lastSampleTime / new_scale > width){ + new_scale = GraphsUtils.nextScale(new_scale, true); + + if(prevNew == new_scale) + break; + + prevNew = new_scale; + } + + if (new_scale == graph.getScale()) + return; + + graph.setScale(new_scale); + setNewSize(); + } + + /** + * This method sets the size of the panel, when scale is changed. + * When graph extends beyond visible area, horizontal scroll bar appears automatically. + * + */ + private void setNewSize() + { + if(graph == null) + return; + + graph.setScrolledXOrigin(0); + double scale = graph.getScale(); + int lastSample = graph.lastSampleTime; + + int prefSize = (int)(lastSample/scale); + + Panel panel = (Panel)(figureCanvas.getContents()); + panel.setPreferredSize(prefSize + 100, 0); + + if (prefSize >= figureCanvas.getClientArea().width) { + graph.setScrolledXOrigin(figureCanvas.getViewport().getViewLocation().x); + panel.setSize(prefSize + 100, 0); + } + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage() + */ + public Image getImage() { + return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable() + */ + public Drawable getDrawable() { + return parentComposite; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SystemDataGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SystemDataGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.KernelElements; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * This class contains all needed logic to paint data related to System data. + */ +public class SystemDataGraph extends GenericGraph +{ + private ArrayList kernelElements; + private HashMap pointsData = new HashMap(); + + private double visY; + private double multiplier; + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics) + */ + public void paint(Graphics graphics) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START"); + + ArrayList selectedItems = this.getUserSelectedItems(); + + if(selectedItems == null) + return; + + int [] listX = this.calculateTimeIntervals(); + this.lastSampleTime = listX[listX.length-1]; + + int k=0; + + // Storing drawing settings + Color origColor = graphics.getForegroundColor(); + int origLineWidth = graphics.getLineWidth(); + // Setting drawing settings + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + + for(String item: selectedItems) + { + int [] valuesToBePlotted = getValuesForGivenKerenelElement(item, kernelElements); + + if(valuesToBePlotted == null) + return; + + int [] points = new int[valuesToBePlotted.length *2]; + + double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + + for (int i = 0, j = 0; i < valuesToBePlotted.length; i++) + { + points[j++] = (int)(listX[i]/getScale()); + + points[j] =(int) (visY - valuesToBePlotted[i] /multiplier); + + if (points[j] < 0) + points[j] = 0; + + j++; + } + + graphics.setForegroundColor(this.getColors().get(k)); + // Drawing graph + graphics.drawPolyline(points); + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, points); + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + pointsData.put(item, line); + + k++; + } + + // Restoring drawing settings + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END"); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC) + */ + public void paintYAxis( GC gc) { + + visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + multiplier = GraphsUtils.roundToNearestNumber(maxBytes) / visY; + + double yIncrement = visY / 10; + int previousBottom = 0; + + for (int k = 10; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier)* k; + + String legend = ""; + legend += bytes ; + + Point extent = gc.stringExtent(legend); + + gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1); + + if (y >= previousBottom) + { + gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + + final Image image = this.getVerticalLabel("Count"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -(int)visY/3, 0); + + transform.dispose(); + gc.dispose(); + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData() + */ + public void prepareData() { + + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + kernelElements = utils.getKerenelElemsFromAllCycles(this.getCyclesData()); + + for(String item:getUserSelectedItems()) + { + int [] values = getValuesForGivenKerenelElement(item, kernelElements); + + int maxValue = calculateMaxValue(values); + + if(maxValue > maxBytes){ + maxBytes = maxValue; + } + } + } + + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int) + */ + public String getToolTipText(int x, int y) + { + if(y > (int)visY) + return null; + + String text = ""; + + double xValue = x + timeOffset; + int scaledX = (int)(xValue * getScale()); + int valY = (int)visY - y; + int scaledY = (int)(valY * multiplier); + + text += scaledX + " s, " + scaledY; + + for(String elem: getUserSelectedItems()) + { + Polyline line = pointsData.get(elem); + + if(line != null && line.containsPoint(x, y)) + text += "\n" + elem; + } + + return text; + } + + /** + * Get kernel data + * @return kernel data + */ + public ArrayList getKernelData() + { + return this.kernelElements; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ThreadsGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ThreadsGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,477 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.widgets.Display; + +import com.nokia.s60tools.swmtanalyser.data.CycleData; +import com.nokia.s60tools.swmtanalyser.data.ThreadData; +import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils; +import com.nokia.s60tools.util.debug.DbgUtility; + +/** + * This class contains all needed logic to paint data related to Threads. + */ +public class ThreadsGraph extends GenericGraph { + + // + // Members + // + private HashMap> threadData = new HashMap>(); + private HashMap samplesData = new HashMap(); + private double visY; + private double multiplier; + private boolean yAxisNeedsToBeChanged = false; + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics) + */ + public void paint(Graphics graphics) { + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START"); + + // Getting threads that user has been selected + ArrayList threadsList = this.getUserSelectedItems(); + + if(threadsList == null){ + // No thread data selected for drawing + return; + } + + // Storing original settings before graphs are painted with case-specific settings + int origLineWidth = graphics.getLineWidth(); + Color origColor = graphics.getForegroundColor(); + int origLineStyle = graphics.getLineStyle(); + + // Setting graph drawing specific settings + graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH); + graphics.setLineStyle(SWT.LINE_SOLID); + + // Getting cycle time stamps + int [] listX = this.calculateTimeIntervals(); + this.lastSampleTime = listX[listX.length-1]; + + // Each thread is drawn by different color stored in external array + int colorIndex=0; + visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + + // Looping through all the threads + for(String th: threadsList) + { + ArrayList data = threadData.get(th); + + boolean handleDeleted = false; + + int[] valuesToBePlotted = new int[data.size()]; + int [] points = new int[valuesToBePlotted.length *2]; + + List> ListOfSolidLinePoints = new ArrayList>(); + ArrayList solidLinePoints = new ArrayList(); + + for(int i =0, j=0; i 0){ + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because non-positive Y-axis value"); + } + } + + if(data.get(i).isKernelHandleDeleted() && !handleDeleted){ + handleDeleted = true; + } + + if(handleDeleted && data.get(i).getStatus() == CycleData.New) + { + handleDeleted = false; + + if(y_point > 0){ + // Graphing only positive values + solidLinePoints.add(x_point); + solidLinePoints.add(y_point); + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point); + } + else{ + DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value"); + } + } + + points[j] = x_point; + points[++j] = y_point; + } + + if(solidLinePoints.size() > 0){ + // Adding point for this thread graph, possible to have more instances for same thread name + ListOfSolidLinePoints.add(solidLinePoints); + } + + visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + + // Each thread have a separate color + graphics.setForegroundColor(this.getColors().get(colorIndex)); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "No of solid lists are " + ListOfSolidLinePoints.size()); + + for(int i=0; i < ListOfSolidLinePoints.size(); i++) + { + int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i)); + + if(solidPts != null) + { + if(ListOfSolidLinePoints.size() > 1) + { + int instance_id = i+1; + graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15); + } + + // Drawing graph based on the stored data points + graphics.drawPolyline(solidPts); + + // Drawing markers to the data points + GraphsUtils.drawMarkers(graphics, solidPts); + } + } + + Polyline line = new Polyline(); + line.setPoints(new PointList(points)); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Putting the points list in a map for '" + th + "'."); + samplesData.put(th, line); + + colorIndex++; + } + + // Restoring original settings before paint call + graphics.setLineStyle(origLineStyle); + graphics.setForegroundColor(origColor); + graphics.setLineWidth(origLineWidth); + + DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END"); + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC) + */ + public void paintYAxis(GC gc) + { + double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; + + switch(this.getEvent()) + { + case NO_OF_FILES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case NO_OF_PSHANDLES: + multiplier = GraphsUtils.roundToNearestNumber(maxBytes) / visY; + yAxisNeedsToBeChanged = true; + break; + default: + multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY; + break; + } + int countOfYAxisLabels = 10; + double yIncrement = visY / countOfYAxisLabels; + int previousBottom = 0; + + for (int k = countOfYAxisLabels; k >= 0; k--) + { + // location for the value indicator is k * 1/10 the height of the display + int y = (int) (visY - (yIncrement * k)); + + int bytes = (int)(yIncrement * multiplier) * k; + + String legend = ""; + + switch(this.getEvent()) + { + case NO_OF_FILES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + case NO_OF_PSHANDLES: + legend += bytes; + break; + default: + //legend += bytes + "B"; + if (maxBytes < 10000) + { + legend += bytes + " B"; //$NON-NLS-1$ + } + else if (maxBytes <= 500 * 1024) + { + legend += (bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + break; + } + + Point extent = gc.stringExtent(legend); + + gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1); + + if (y >= previousBottom) + { + gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y); + previousBottom = (int)y + extent.y; + } + } + + if(yAxisNeedsToBeChanged) + drawCountLabel(gc, (int)(visY/3)); + else + drawBytesLabel(gc, (int)(visY/3)); + } + + private void fetchEntireDataForSelectedThreads() + { + ArrayList selectedThreads = this.getUserSelectedItems(); + SWMTLogReaderUtils utils = new SWMTLogReaderUtils(); + + for(String th:selectedThreads) + { + ArrayList thData = utils.getHeapDataFromAllCycles(th, this.getCyclesData()); + threadData.put(th, thData); + } + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData() + */ + public void prepareData() + { + fetchEntireDataForSelectedThreads(); + + for(String th:getUserSelectedItems()) + { + ArrayList data = threadData.get(th); + + valuesToBePlotted = new int[data.size()]; + for(int i =0; i maxBytes) + maxBytes = maxValue; + } + + } + + } + + private int getEventValueFromThreadData(ThreadData thData, EventTypes event) + { + int value = 0; + + if(thData.getStatus() == CycleData.Deleted) + return 0; + + switch(event) + { + case NO_OF_FILES: + value = (int)thData.getOpenFiles(); + break; + case MAX_HEAP_SIZE: + value = (int)thData.getMaxHeapSize(); + break; + case HEAP_SIZE: + value = (int)thData.getHeapChunkSize(); + break; + case HEAP_ALLOC_SPACE: + value = (int)thData.getHeapAllocatedSpace(); + break; + case HEAP_FREE_SPACE: + value = (int)thData.getHeapFreeSpace(); + break; + case HEAP_ALLOC_CELL_COUNT: + value = (int)thData.getAllocatedCells(); + break; + case HEAP_FREE_CELL_COUNT: + value = (int)thData.getFreeCells(); + break; + case HEAP_FREE_SLACK: + value = (int)thData.getFreeSlackSize(); + break; + case NO_OF_PSHANDLES: + value = (int)thData.getPsHandles(); + break; + default: + value = 0; + break; + } + + return value; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int) + */ + public String getToolTipText(int x, int y) + { + if(y > (int)visY) + return null; + + String text = ""; + + double xValue = x + timeOffset; + int scaledX = (int)(xValue * getScale()); + + double valY = visY - y; + double scaledY = valY * multiplier; + + String yValue = ""; + + yValue+= (int)(scaledY); + + switch(this.getEvent()) + { + case NO_OF_FILES: + case NO_OF_PSHANDLES: + case HEAP_ALLOC_CELL_COUNT: + case HEAP_FREE_CELL_COUNT: + text += scaledX + " s, " + yValue; + break; + default: + yValue = getFormattedValues(scaledY); + text += scaledX + " s, " + yValue; + break; + } + + for(String th: getUserSelectedItems()) + { + Polyline line = samplesData.get(th); + if(line != null && line.containsPoint(x, y)) + text += "\n" + th; + + } + + return text; + } + + /** + * Get thread data for thread + * @param thread + * @return thread data + */ + public ArrayList getDataForThread(String thread) + { + return this.threadData.get(thread); + } + + /** + * Draws Bytes label on given gc at given position + * @param gc + * @param position + */ + private void drawBytesLabel(GC gc, int position) + { + final Image image = this.getVerticalLabel("Bytes"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -position, 0); + + transform.dispose(); + gc.dispose(); + + } + + /** + * Draws Count label on given gc at given position + * @param gc + * @param position + */ + private void drawCountLabel(GC gc, int position) + { + final Image image = this.getVerticalLabel("Count"); + gc.setAdvanced(true); + final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds(); + Transform transform = new Transform(Display.getDefault()); + + transform.translate(rect2.height / 2f, rect2.width / 2f); + transform.rotate(-90); + transform.translate(-rect2.width / 2f, -rect2.height / 2f); + + gc.setTransform(transform); + gc.drawImage(image, -position, 0); + + transform.dispose(); + gc.dispose(); + + } + + private String getFormattedValues(double bytes) + { + String scaledY = ""; + + if (bytes < 10000) + { + scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$ + } + else if (bytes <= 500 * 1024) + { + scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$ + } + else + { + scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$ + } + + return scaledY; + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/TimeObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/TimeObject.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +/** + * Object for storing time to show in X-axis in UI. Handles time formatting. + */ +public class TimeObject { + + private String days = null; + + private String hourMinutesAndSeconds = null; + + + /** + * Create a time object + * @param time + * @param scale + */ + public TimeObject(double time, double scale){ + init(time, scale); + } + + /** + * Get the days with units, e.g. "1d" or "12d" + * @return the days null if not defined or less than 1 + */ + public String getDays() { + return days; + } + + /** + * Set day String with units, e.g. "1d" + * @param days the days to set + */ + public void setDays(String days) { + this.days = days; + } + + /** + * Get Hours, minutes and seconds as "h:m:s" -format + * @return the hourMinutesAndSeconds + */ + public String getHourMinutesAndSeconds() { + return hourMinutesAndSeconds; + } + + /** + * Set Hours, minutes and seconds as "h:m:s" -format + * @param hourMinutesAndSeconds the hourMinutesAndSeconds to set + */ + public void setHourMinutesAndSeconds(String hourMinutesAndSeconds) { + this.hourMinutesAndSeconds = hourMinutesAndSeconds; + } + + /** + * Check if days has been set for this time object + * @return true if there are days set, false otherwise. + */ + public boolean hasDays() { + return getDays() != null; + } + + /** + * Scaling the time and decides how to show the time in UI. + * E.g. + *
"30s" + *
"1m 30s" + *
"40m" + *
"1h 30m" + * @param time + * @param scale + * @return time with units to add in graph + */ + private void init(double time, double scale) { + + time = time * scale; + long timeAsLong = (long)time * 1000;//Ms to s + String hoursMinsAndSecs ; + + //To avoid TimeZone adding e.g. 2hours to time, using GMT + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));//$NON-NLS-1$ + SimpleDateFormat hmsDf;//Date format for hours, minutes and seconds + hmsDf = new SimpleDateFormat("H:m:s");//$NON-NLS-1$ + hmsDf.setCalendar(cal); + + //If it has been taken more than one day, also days must be calculated + if(time > (60*60*24)){ + //Decrease one day for time, because SimpeDateFormat will show "0" days as day "1" + timeAsLong = timeAsLong - (60*60*24*1000); + SimpleDateFormat dDf = new SimpleDateFormat("D'd'");//$NON-NLS-1$ + dDf.setCalendar(cal); + Date date = new Date (timeAsLong); + hoursMinsAndSecs = hmsDf.format(date ); + String days = dDf.format(date); + setDays(days); + setHourMinutesAndSeconds(hoursMinsAndSecs); + } + //If it has been taken less than day, we need only hours minutes and seconds + else{ + Date date = new Date (timeAsLong); + hoursMinsAndSecs = hmsDf.format(date ); + setHourMinutesAndSeconds(hoursMinsAndSecs); + } + + + } + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ZoomableGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ZoomableGraph.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +package com.nokia.s60tools.swmtanalyser.ui.graphs; + +import org.eclipse.jface.action.IAction; + +/** + * Common abstract base class for graphs that support zoom operations. + */ +public abstract class ZoomableGraph { + + + /** + * Context menu title for action: Zoom In + */ + protected static final String ZOOM_IN_CONTEXT_MENU_TITLE = "Zoom In"; + + /** + * Context menu title for action: Zoom Out + */ + protected static final String ZOOM_OUT_CONTEXT_MENU_TITLE = "Zoom Out"; + + /** + * Copy -action + */ + protected IAction copy; + + + /** + * Zoom In -action + */ + protected IAction zoomIn; + + /** + * Zoom Out -action + */ + protected IAction zoomOut; + + /** + * This method zooms in the graph area. + */ + protected abstract void zoomIn(); + + /** + * This method zooms out the graph area. + */ + protected abstract void zoomOut(); + + /** + * Sets given enable state for an action if it is non null. + * @param action Action to set enable status for. + * @param enableStatus true if enabled, otherwise false. + */ + protected void setEnableState(IAction action, boolean enableStatus) { + if(action != null){ + action.setEnabled(enableStatus); + } + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/CommentsPage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/CommentsPage.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,289 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.wizards; + +import java.io.File; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.PlatformUI; + +import com.nokia.s60tools.swmtanalyser.resources.HelpContextIds; +import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; +/** + * First page in the Report Generation wizard. i.e. Comments page. + * + */ +public class CommentsPage extends S60ToolsWizardPage implements SelectionListener, ModifyListener { + + //Radio button for creating type1 report + private Button type1_radio; + //Radio button for creating overview type report + private Button type2_radio; + //Save as button to select the pdf file path/name + private Button browse_btn; + //Text box to show the selected path + private Text path_txt; + //Text box to enetr comments + private Text commentsText; + //Label to explain about the selected radio option + private Label info; + + //Temporary variables used + private Tree all_tree_items; + private boolean checked = false; + + /** + * Create a comments page + * @param pageName + * @param all_tree_items + */ + protected CommentsPage(String pageName, Tree all_tree_items) { + super(pageName); + setTitle("Report Options"); + setDescription("Select your options"); + this.all_tree_items = all_tree_items; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates() + */ + public void recalculateButtonStates() { + + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus() + */ + public void setInitialFocus() { + + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + if(e.widget == browse_btn) + { + FileDialog dlg = new FileDialog(this.getShell(), SWT.SAVE); + dlg.setFilterExtensions(new String[]{"*.pdf"}); + String path = dlg.open(); + if(path != null) + path_txt.setText(path); + } + else if(e.widget == type1_radio) + { + //If option 1 is selected, explain about that option. + info.setText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues."); + } + else if(e.widget == type2_radio) + { + //If option 2 is selected, explain about that option. + info.setText("This case the report contains the overview information of all the type of issues."); + } + + checkForCompletion(); + this.getContainer().updateButtons(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + public void modifyText(ModifyEvent arg0) { + checkForCompletion(); + this.getContainer().updateButtons(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite parentComposite = new Composite(parent, SWT.NONE); + parentComposite.setLayout(new GridLayout(2, false)); + + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + + Label title = new Label(parentComposite, SWT.WRAP); + title.setText("Select type of report to be created:"); + title.setLayoutData(gd); + + type1_radio = new Button(parentComposite, SWT.RADIO); + type1_radio.setText("Create report for the selected issues"); + type1_radio.setLayoutData(gd); + type1_radio.setToolTipText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues."); + type1_radio.addSelectionListener(this); + + type2_radio = new Button(parentComposite, SWT.RADIO); + type2_radio.setText("Create overview report"); + type2_radio.setLayoutData(gd); + type2_radio.setToolTipText("This case the report contains the overview information of all the type of issues"); + type2_radio.addSelectionListener(this); + + info=new Label(parentComposite,SWT.WRAP); + info.setText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues."); + GridData lblGD=new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); + lblGD.horizontalSpan = 2; + lblGD.verticalIndent=8; + info.setLayoutData(lblGD); + + Label comments_label = new Label(parentComposite, SWT.WRAP); + comments_label.setText("Enter your comments here:"); + GridData lbl_gd = new GridData(GridData.FILL_HORIZONTAL); + lbl_gd.horizontalSpan = 2; + comments_label.setLayoutData(lbl_gd); + + commentsText = new Text(parentComposite, SWT.BORDER|SWT.MULTI|SWT.V_SCROLL|SWT.H_SCROLL); + GridData txt_gd = new GridData(GridData.FILL_HORIZONTAL); + txt_gd.heightHint = 100; + txt_gd.horizontalSpan = 2; + commentsText.setLayoutData(txt_gd); + commentsText.addModifyListener(this); + + Label browse_label = new Label(parentComposite, SWT.WRAP); + browse_label.setText("Provide report file path here:"); + browse_label.setLayoutData(lbl_gd); + + path_txt = new Text(parentComposite, SWT.BORDER); + path_txt.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + path_txt.addModifyListener(this); + + browse_btn = new Button(parentComposite, SWT.PUSH); + browse_btn.setText("Save as..."); + browse_btn.addSelectionListener(this); + + setHelp(parentComposite); + setControl(parentComposite); + } + + /** + * Check if overview report was selected or not. + * @return true if overview report was selected, false otherwise. + */ + public boolean isOverviewReportSelected() + { + return type2_radio.getSelection(); + } + + /** + * Returns filename with path provided in the text box + * @return file name + */ + public String getFileName() + { + return path_txt.getText(); + } + + /** + * Returns comments provided. + * @return comment text + */ + public String getComments() + { + return commentsText.getText(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage() + */ + public boolean canFlipToNextPage() { + checkForCompletion(); + return super.canFlipToNextPage(); + } + + /** + * Checks wizard completion. + * @return true if completed. + */ + public boolean checkForCompletion(){ + setErrorMessage(null); + if(type1_radio.getSelection() && !areItemsChecked()) + { + setErrorMessage("No issues are selected. Please select some issues in the analysis view."); + return false; + } + else if(commentsText.getText()==null || commentsText.getText() == "") + { + setErrorMessage("Enter your comments"); + return false; + } + else if(!(new File(path_txt.getText()).isAbsolute())|| !(new File(path_txt.getText())).getParentFile().exists()) + { + setErrorMessage("Invalid file name"); + return false; + } + return true; + } + + /** + * Checks whether any issues are selected or not. + * @return true if any issue(child) is selected. + */ + private boolean areItemsChecked() { + checked = false; + //To avoid invalid thread access, running in new thread. + Display.getDefault().syncExec(new Runnable() { + public void run() { + for(TreeItem i:all_tree_items.getItems()) + { + if(i.getItemCount() > 0) + { + for(TreeItem child : i.getItems()) + { + if(child.getChecked()) + { + checked = true; + return; + } + } + } + } + }}); + return checked; + } + + /** + * Set context sensitive helps + * @param parentComposite + */ + private void setHelp(Composite parentComposite) + { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parentComposite, + HelpContextIds.SWMT_REPORT_WIZARD_HELP); + + } +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportCreationJob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportCreationJob.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,615 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.wizards; + +import java.awt.Color; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Chapter; +import com.lowagie.text.Chunk; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.FontFactory; +import com.lowagie.text.PageSize; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.GrayColor; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfWriter; +import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin; +import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants; +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.util.console.AbstractProductSpecificConsole; +import com.nokia.s60tools.util.console.IConsolePrintUtility; + +/** + * Job to create PDF report. + * + */ +public class ReportCreationJob extends Job { + + + /** + * Spacing after a header text, to avoid texts to be too close each other + */ + private static final int SPACING_AFTER_HEADER_TEXT = 5; + //Paddings in cells + private float cellPaddingSmall; + private float cellPaddingTableHeader; + + //Colors used in document + private Color colorHeading; + private Color colorTableHeaderBackGrd; + private Color colorTable2ndHeaderBackGrd; + private Color colorSeverityNormal; + private Color colorSeverityHigh; + private Color colorSeverityCritical; + + //Fonts used in document + private Font fontTable2ndHeaderText; + private Font fontHeader; + private Font fontNormalSmallTables; + private Font fontNormal; + private Font fontHeading2; + private Font fontHeading1; + + //PDF filename + private String fileName = null; + //Use given comments + private String comment = null; + //Oveview info to write in pdf + private OverviewData ov; + //ROM Checksum to write in pdf + private String rom_checkSum_string; + //ROM Version to write in pdf + private String rom_version_string; + //Tree object to get the issues info + private Tree all_tree_items; + //To save the report type option + boolean isOverviewReport; + //temporary variable + private PdfPTable table; + + /** + * Job constructor. + * @param name Job name + * @param fileName PDF filename + * @param comment User given comments + * @param ov Overview object + * @param checksum ROM Checksum + * @param version ROM Version + * @param issues_tree Tree object from Analysis view. + * @param isOverviewReport report type + */ + public ReportCreationJob(String name, String fileName, String comment, OverviewData ov, String checksum, String version, Tree issues_tree, boolean isOverviewReport) { + super(name); + this.fileName = fileName; + this.comment = comment; + this.ov = ov; + this.rom_checkSum_string = checksum; + this.rom_version_string = version; + this.all_tree_items = issues_tree; + this.isOverviewReport = isOverviewReport; + + //Initialize Colors and Fonts + initStyles(); + } + + /** + * Initializing Colors and fonts to be used in PDF Document. + * Color scheme is taken from Carbide logo. + */ + private void initStyles() { + + // + // Colors used are picked up from Carbide.c++ -logo, from dark blue to white + // #003399 = 0, 51, 153 -Dark blue + // #0088ff = 0, 136, 255 -mid blue + // #33aaff = 51, 170, 255 -mid blue 2 + // #88ccff = 136, 204, 255 -thin blue + // #ffffff = -white + // + + // + //Using Carbide.c++ logo colors to decorate report + // + colorHeading = new Color(0, 51, 153); + colorTableHeaderBackGrd = new Color (136, 204, 255); + colorTable2ndHeaderBackGrd = new Color (0, 136, 255); + + + // + // Setting Severity Colors for PDF report from Analyser view colors. + // + org.eclipse.swt.graphics.Color color = AnalyserConstants.COLOR_SEVERITY_CRITICAL; + colorSeverityCritical = new Color (color.getRed(),color.getGreen(),color.getBlue()); + + color = AnalyserConstants.COLOR_SEVERITY_HIGH; + colorSeverityHigh = new Color (color.getRed(),color.getGreen(),color.getBlue()); + + color = AnalyserConstants.COLOR_SEVERITY_NORMAL; + colorSeverityNormal = new Color (color.getRed(),color.getGreen(),color.getBlue()); + + // + // Font used in report + // + String font = FontFactory.HELVETICA; + + // + // Creating fonts + // + fontTable2ndHeaderText = FontFactory.getFont(font,10f,Font.NORMAL, Color.WHITE); + fontHeader = FontFactory.getFont(font, 16, Font.BOLD, Color.BLACK); + fontNormalSmallTables = FontFactory.getFont(font,9f,Font.NORMAL); + fontNormal = FontFactory.getFont(font,10f,Font.NORMAL); + fontHeading2 = FontFactory.getFont(font,10f,Font.BOLD); + fontHeading1 = FontFactory.getFont(font,12f,Font.BOLD, colorHeading); + + cellPaddingSmall = 1.0f; + cellPaddingTableHeader = 3.0f; + + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + + monitor.beginTask("Creating report...", 10); + + try { + //Instantiation of document object + Document document = new Document(PageSize.A4, 50, 50, 50, 50); + PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(this.fileName)); + document.open(); + + addGeneralDetails(document); + + if(!this.isOverviewReport) //If the report type is 1. i.e., report for selected issues only. + { + addSelectedIssuesReport(document); + } + else // If the report type is 2. i.e., Overview report + { + addOverviewReport(document); + } + + addComments(document); + + //Close document + document.close(); + //Close the writer + writer.close(); + + + } catch (DocumentException e) { + e.printStackTrace(); + SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR); + } + catch (Exception e) { + e.printStackTrace(); + AbstractProductSpecificConsole absConsole = (AbstractProductSpecificConsole)SwmtAnalyserPlugin.getConsole(); + absConsole.printStackTrace(e); + SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR); + } + return Status.OK_STATUS; + } + + private void addComments(Document document) throws DocumentException { + //Create new line + document.add(Chunk.NEWLINE); + //Comments heading + Paragraph comments_title = new Paragraph("User given comments", fontHeading1); + document.add(comments_title); + + Paragraph comments = new Paragraph(this.comment, fontNormal); + document.add(comments); + } + + private void addGeneralDetails(Document document) throws DocumentException { + //Report Title + Paragraph title = new Paragraph("MemSpy - System Wide Memory Tracking - Analysis Report", fontHeader); + title.setAlignment(Element.ALIGN_CENTER); + document.add(title); + document.add(Chunk.NEWLINE); + + //Introduction title + Paragraph hdng = new Paragraph("Introduction of Memspy (S60) and SWMT Analyser", fontHeading1); + document.add(hdng); + + //About the MemSpy S60 Application + Paragraph intro_memspy = new Paragraph("The MemSpy S60 application tracks various subsystems that directly or indirectly contribute to overall system memory usage and provides information about the changes in these subsystems at specified time intervals.", fontNormal); + document.add(intro_memspy); + document.add(Chunk.NEWLINE); + //About the SWMT Analyser + Paragraph intro_swmt = new Paragraph("A System Wide Memory Tracker log file contains information about system wide memory status changes over time. SWMT Analyser is a Carbide.c++ Extension for analyzing System Wide Memory Tracking logs produced by the MemSpy S60 application and imported to PC with the MemSpy Carbide.c++ Extension.", fontNormal); + document.add(intro_swmt); + document.add(Chunk.NEWLINE); + + //Properties heading + Paragraph props_title = new Paragraph("Properties", fontHeading1); + document.add(props_title); + Chunk no_of_cycles = new Chunk("No of cycles : ", fontHeading2); + document.add(no_of_cycles); + Chunk cycles = new Chunk(ov.noOfcycles+"", fontNormal); + document.add(cycles); + document.add(Chunk.NEWLINE); + + Chunk time_period = new Chunk("Time period : ", fontHeading2); + document.add(time_period); + Chunk period = new Chunk(ov.fromTime+" to "+ov.toTime, fontNormal); + document.add(period); + document.add(Chunk.NEWLINE); + + Chunk duration = new Chunk("Time duration : ", fontHeading2); + document.add(duration); + Chunk dur = new Chunk(ov.durationString, fontNormal); + document.add(dur); + document.add(Chunk.NEWLINE); + + + document.add(Chunk.NEWLINE); + Paragraph rom_title = new Paragraph("ROM Details", fontHeading1); + document.add(rom_title); + Chunk rom_checksum = new Chunk("ROM Checksum : ", fontHeading2); + document.add(rom_checksum); + Chunk checksum = new Chunk(this.rom_checkSum_string, fontNormal); + document.add(checksum); + document.add(Chunk.NEWLINE); + + Chunk rom_version = new Chunk("ROM Version : ", fontHeading2); + document.add(rom_version); + Chunk version = new Chunk(this.rom_version_string, fontNormal); + document.add(version); + document.add(Chunk.NEWLINE); + document.add(Chunk.NEWLINE); + } + + private void addSelectedIssuesReport(Document document) throws DocumentException, + BadElementException { + Paragraph selected_title = new Paragraph("Selected issues", fontHeading1); + selected_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT); + document.add(selected_title); + + Display.getDefault().syncExec(new Runnable() { + public void run() { + table = getTableForTheSelectedIssues(all_tree_items); + } + }); + document.add(table); + + document.add(Chunk.NEWLINE); + + + Paragraph graph_title = new Paragraph("Graph for the selected issues", fontHeading1); + //Using chapter, so title stays together with image + Chapter chapter = new Chapter(graph_title,0); + //Chapter with out number, when depth is 0 + chapter.setNumberDepth(0); + + + com.lowagie.text.Image img = null; + try { + img = com.lowagie.text.Image.getInstance(SwmtAnalyserPlugin.getPluginInstallPath()+"\\swmt_graph.bmp"); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + img.scalePercent(50f); + img.setBorder(Rectangle.BOX); + img.setBorderWidth(1f); + img.setBorderColor(new GrayColor(0.5f)); + //Adding image to chapter + chapter.add(img); + //Adding chapter to document + document.add(chapter); + + } + + private void addOverviewReport(Document document) throws DocumentException { + Paragraph res_title = new Paragraph("Overview Of Analysis Results", fontHeading1); + res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT); + document.add(res_title); + + Display.getDefault().syncExec(new Runnable() { + public void run() { + table = getTableForOverallIssues(all_tree_items); + } + }); + document.add(table); + document.add(Chunk.NEWLINE); + + res_title = new Paragraph("Details", fontHeading1); + document.add(res_title); + + res_title = new Paragraph("Critical Severity Issues", fontHeading2); + res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT); + + Display.getDefault().syncExec(new Runnable() { + public void run() { + table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.CRITICAL);; + } + }); + if(table!=null) + { + document.add(res_title); + document.add(table); + document.add(Chunk.NEWLINE); + } + + res_title = new Paragraph("High Severity Issues", fontHeading2); + res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT); + + Display.getDefault().syncExec(new Runnable() { + public void run() { + table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.HIGH); + } + }); + if(table!=null) + { + document.add(res_title); + document.add(table); + document.add(Chunk.NEWLINE); + } + + res_title = new Paragraph("Normal Severity Issues", fontHeading2); + res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT); + + Display.getDefault().syncExec(new Runnable() { + public void run() { + table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.NORMAL); + } + }); + if(table!=null) + { + document.add(res_title); + document.add(table); + } + } + + /** + * Returns a table for issues of given priority type from the selected issues. + * @param allTreeItems tree + * @param p priority + * @return + */ + private PdfPTable getTableForIssues(Tree allTreeItems, AnalyserConstants.Priority p) { + + float[] relativeWidth = {60, 25, 15};//100% total + PdfPTable table = new PdfPTable(relativeWidth); + table.setWidthPercentage(100); + + PdfPCell cell = new PdfPCell (new Paragraph ("Item name")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Event")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Delta")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + + for(TreeItem parent : allTreeItems.getItems()) + { + for(TreeItem child : parent.getItems()) + { + if(child.getText(4).toLowerCase().equals(p.toString().toLowerCase())) + { + + cell = new PdfPCell (new Paragraph (child.getText(1),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph (child.getText(2),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph (child.getText(3),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + } + } + } + if(table.getRows().size() > 1) + return table; + + return table; + } + + /** + * Returns a table for the overview issues of all types. + * @param all + * @return + */ + private PdfPTable getTableForOverallIssues(Tree all) { + PdfPTable table = new PdfPTable(2); + table.setWidthPercentage(100); + + PdfPCell cell = new PdfPCell (new Paragraph ("Severity")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Count")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + int critical = 0; + int high = 0; + int normal = 0; + + for(TreeItem parent : all.getItems()) + { + for(TreeItem child : parent.getItems()) + { + if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.CRITICAL.toString().toLowerCase())) + critical++; + else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.HIGH.toString().toLowerCase())) + high++; + else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.NORMAL.toString().toLowerCase())) + normal++; + } + } + + table.addCell(new PdfPCell (new Paragraph ("CRITICAL",fontNormalSmallTables))); + table.addCell(new PdfPCell (new Paragraph (critical+"",fontNormalSmallTables))); + table.addCell(new PdfPCell (new Paragraph ("HIGH",fontNormalSmallTables))); + table.addCell(new PdfPCell (new Paragraph (high+"",fontNormalSmallTables))); + table.addCell(new PdfPCell (new Paragraph ("NORMAL",fontNormalSmallTables))); + table.addCell(new PdfPCell (new Paragraph (normal+"",fontNormalSmallTables))); + + return table; + } + + /** + * Returns a table for the selected issues. + * @param issuesTree + * @return + */ + private PdfPTable getTableForTheSelectedIssues(Tree issuesTree) { + + float[] relativeWidth = {50, 22, 14, 14};//100% total + PdfPTable table = new PdfPTable(relativeWidth); + table.setWidthPercentage(100); + + PdfPCell cell = new PdfPCell (new Paragraph ("Item name")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Event")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Delta")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph ("Severity")); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + cell.setVerticalAlignment (Element.ALIGN_MIDDLE); + cell.setBackgroundColor (colorTableHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + table.addCell (cell); + + for(TreeItem item : issuesTree.getItems()) + { + ArrayList selected = new ArrayList(); + for(TreeItem child: item.getItems()) + if(child.getChecked()) + selected.add(child); + + if(selected.size() > 0) + { + cell = new PdfPCell (new Paragraph (item.getText(1),fontTable2ndHeaderText)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setBackgroundColor (colorTable2ndHeaderBackGrd); + cell.setPadding (cellPaddingTableHeader); + cell.setColspan(4); + table.addCell (cell); + + for(TreeItem child: selected) + { + cell = new PdfPCell (new Paragraph (child.getText(1),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph (child.getText(2),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph (child.getText(3),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_LEFT); + cell.setPadding (cellPaddingSmall); + table.addCell (cell); + + cell = new PdfPCell (new Paragraph (child.getText(4),fontNormalSmallTables)); + cell.setHorizontalAlignment (Element.ALIGN_CENTER); + + if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.CRITICAL.toString().toLowerCase())){ + cell.setBackgroundColor (colorSeverityCritical); + } + else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.HIGH.toString().toLowerCase())){ + cell.setBackgroundColor (colorSeverityHigh); + } + else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.NORMAL.toString().toLowerCase())){ + cell.setBackgroundColor (colorSeverityNormal); + } + cell.setPadding(cellPaddingSmall); + table.addCell (cell); + } + } + } + return table; + } + + +} diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportGenerationWizard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportGenerationWizard.java Wed Apr 21 20:01:08 2010 +0300 @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +package com.nokia.s60tools.swmtanalyser.wizards; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Tree; + +import com.nokia.s60tools.swmtanalyser.data.OverviewData; +import com.nokia.s60tools.ui.wizards.S60ToolsWizard; + +/** + * Report Generation Wizard + * + */ +public class ReportGenerationWizard extends S60ToolsWizard { + + //Comments page + private CommentsPage comments_page; + //Overview object to write overview info to pdf + private OverviewData ov; + //ROM Checksum + private String rom_checkSum; + //ROM Version + private String rom_version; + //Tree object from Analysis view + private Tree issues_tree; + //PDF file name + private String fileName; + + /** + * Constructor + * @param ov Overview Data Object + * @param checksum ROM Checksum string + * @param version ROM Version string + * @param issues_tree Tree object from the Analysis view. + */ + public ReportGenerationWizard(OverviewData ov, String checksum, String version, Tree issues_tree) { + setWindowTitle("Create Report"); + this.ov = ov; + this.rom_checkSum = checksum; + this.rom_version = version; + this.issues_tree = issues_tree; + } + + /* (non-Javadoc) + * @see com.nokia.s60tools.ui.wizards.S60ToolsWizard#addPages() + */ + public void addPages() { + comments_page = new CommentsPage("Comments", issues_tree); + addPage(comments_page); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performFinish() + */ + public boolean performFinish() { + + fileName = comments_page.getFileName(); + String comment = comments_page.getComments(); + boolean isOverviewReport = comments_page.isOverviewReportSelected(); + ReportCreationJob engine = new ReportCreationJob("Creating report", fileName, comment, ov, this.rom_checkSum, this.rom_version, issues_tree, isOverviewReport); + engine.setUser(true); + engine.schedule(); + + //Ask user whether to open the created pdf file or not + Runnable p = new Runnable(){ + public void run() { + if(MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),"Confirmation","Would you like to open the saved report?")) //$NON-NLS-2$ + { + Program p=Program.findProgram(".pdf"); + if(p!=null) + p.execute(fileName); + } + } + }; + Display.getDefault().asyncExec(p); + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#canFinish() + */ + public boolean canFinish() { + return comments_page.checkForCompletion(); + } + +}