• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.traceview;
18 
19 import com.android.sdkstats.SdkStatsService;
20 
21 import org.eclipse.jface.action.Action;
22 import org.eclipse.jface.action.MenuManager;
23 import org.eclipse.jface.window.ApplicationWindow;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.custom.SashForm;
26 import org.eclipse.swt.graphics.Color;
27 import org.eclipse.swt.graphics.Image;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Display;
33 import org.eclipse.swt.widgets.Shell;
34 
35 import java.io.File;
36 import java.io.FileInputStream;
37 import java.io.FileNotFoundException;
38 import java.io.FileOutputStream;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.nio.channels.FileChannel;
42 import java.util.HashMap;
43 import java.util.Properties;
44 
45 public class MainWindow extends ApplicationWindow {
46 
47     private final static String PING_NAME = "Traceview";
48 
49     private TraceReader mReader;
50     private String mTraceName;
51 
52     // A global cache of string names.
53     public static HashMap<String, String> sStringCache = new HashMap<String, String>();
54 
MainWindow(String traceName, TraceReader reader)55     public MainWindow(String traceName, TraceReader reader) {
56         super(null);
57         mReader = reader;
58         mTraceName = traceName;
59 
60         addMenuBar();
61     }
62 
run()63     public void run() {
64         setBlockOnOpen(true);
65         open();
66     }
67 
68     @Override
configureShell(Shell shell)69     protected void configureShell(Shell shell) {
70         super.configureShell(shell);
71         shell.setText("Traceview: " + mTraceName);
72 
73         InputStream in = getClass().getClassLoader().getResourceAsStream(
74                 "icons/traceview-128.png");
75         if (in != null) {
76             shell.setImage(new Image(shell.getDisplay(), in));
77         }
78 
79         shell.setBounds(100, 10, 1282, 900);
80     }
81 
82     @Override
createContents(Composite parent)83     protected Control createContents(Composite parent) {
84         ColorController.assignMethodColors(parent.getDisplay(), mReader.getMethods());
85         SelectionController selectionController = new SelectionController();
86 
87         GridLayout gridLayout = new GridLayout(1, false);
88         gridLayout.marginWidth = 0;
89         gridLayout.marginHeight = 0;
90         gridLayout.horizontalSpacing = 0;
91         gridLayout.verticalSpacing = 0;
92         parent.setLayout(gridLayout);
93 
94         Display display = parent.getDisplay();
95         Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
96 
97         // Create a sash form to separate the timeline view (on top)
98         // and the profile view (on bottom)
99         SashForm sashForm1 = new SashForm(parent, SWT.VERTICAL);
100         sashForm1.setBackground(darkGray);
101         sashForm1.SASH_WIDTH = 3;
102         GridData data = new GridData(GridData.FILL_BOTH);
103         sashForm1.setLayoutData(data);
104 
105         // Create the timeline view
106         new TimeLineView(sashForm1, mReader, selectionController);
107 
108         // Create the profile view
109         new ProfileView(sashForm1, mReader, selectionController);
110         return sashForm1;
111     }
112 
113     @Override
createMenuManager()114     protected MenuManager createMenuManager() {
115         MenuManager manager = super.createMenuManager();
116 
117         MenuManager viewMenu = new MenuManager("View");
118         manager.add(viewMenu);
119 
120         Action showPropertiesAction = new Action("Show Properties...") {
121             @Override
122             public void run() {
123                 showProperties();
124             }
125         };
126         viewMenu.add(showPropertiesAction);
127 
128         return manager;
129     }
130 
showProperties()131     private void showProperties() {
132         PropertiesDialog dialog = new PropertiesDialog(getShell());
133         dialog.setProperties(mReader.getProperties());
134         dialog.open();
135     }
136 
137     /**
138      * Convert the old two-file format into the current concatenated one.
139      *
140      * @param base Base path of the two files, i.e. base.key and base.data
141      * @return Path to a temporary file that will be deleted on exit.
142      * @throws IOException
143      */
makeTempTraceFile(String base)144     private static String makeTempTraceFile(String base) throws IOException {
145         // Make a temporary file that will go away on exit and prepare to
146         // write into it.
147         File temp = File.createTempFile(base, ".trace");
148         temp.deleteOnExit();
149         FileChannel dstChannel = new FileOutputStream(temp).getChannel();
150 
151         // First copy the contents of the key file into our temp file.
152         FileChannel srcChannel = new FileInputStream(base + ".key").getChannel();
153         long size = dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
154         srcChannel.close();
155 
156         // Then concatenate the data file.
157         srcChannel = new FileInputStream(base + ".data").getChannel();
158         dstChannel.transferFrom(srcChannel, size, srcChannel.size());
159 
160         // Clean up.
161         srcChannel.close();
162         dstChannel.close();
163 
164         // Return the path of the temp file.
165         return temp.getPath();
166     }
167 
168     /**
169      * Returns the tools revision number.
170      */
getRevision()171     private static String getRevision() {
172         Properties p = new Properties();
173         try{
174             String toolsdir = System.getProperty("com.android.traceview.toolsdir"); //$NON-NLS-1$
175             File sourceProp;
176             if (toolsdir == null || toolsdir.length() == 0) {
177                 sourceProp = new File("source.properties"); //$NON-NLS-1$
178             } else {
179                 sourceProp = new File(toolsdir, "source.properties"); //$NON-NLS-1$
180             }
181 
182             FileInputStream fis = null;
183             try {
184                 fis = new FileInputStream(sourceProp);
185                 p.load(fis);
186             } finally {
187                 if (fis != null) {
188                     try {
189                         fis.close();
190                     } catch (IOException ignore) {
191                     }
192                 }
193             }
194 
195             String revision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
196             if (revision != null && revision.length() > 0) {
197                 return revision;
198             }
199         } catch (FileNotFoundException e) {
200             // couldn't find the file? don't ping.
201         } catch (IOException e) {
202             // couldn't find the file? don't ping.
203         }
204 
205         return null;
206     }
207 
208 
main(String[] args)209     public static void main(String[] args) {
210         TraceReader reader = null;
211         boolean regression = false;
212 
213         // ping the usage server
214 
215         String revision = getRevision();
216         if (revision != null) {
217             new SdkStatsService().ping(PING_NAME, revision);
218         }
219 
220         // Process command line arguments
221         int argc = 0;
222         int len = args.length;
223         while (argc < len) {
224             String arg = args[argc];
225             if (arg.charAt(0) != '-') {
226                 break;
227             }
228             if (arg.equals("-r")) {
229                 regression = true;
230             } else {
231                 break;
232             }
233             argc++;
234         }
235         if (argc != len - 1) {
236             System.out.printf("Usage: java %s [-r] trace%n", MainWindow.class.getName());
237             System.out.printf("  -r   regression only%n");
238             return;
239         }
240 
241         String traceName = args[len - 1];
242         File file = new File(traceName);
243         if (file.exists() && file.isDirectory()) {
244             System.out.printf("Qemu trace files not supported yet.\n");
245             System.exit(1);
246             // reader = new QtraceReader(traceName);
247         } else {
248             // If the filename as given doesn't exist...
249             if (!file.exists()) {
250                 // Try appending .trace.
251                 if (new File(traceName + ".trace").exists()) {
252                     traceName = traceName + ".trace";
253                 // Next, see if it is the old two-file trace.
254                 } else if (new File(traceName + ".data").exists()
255                     && new File(traceName + ".key").exists()) {
256                     try {
257                         traceName = makeTempTraceFile(traceName);
258                     } catch (IOException e) {
259                         System.err.printf("cannot convert old trace file '%s'\n", traceName);
260                         System.exit(1);
261                     }
262                 // Otherwise, give up.
263                 } else {
264                     System.err.printf("trace file '%s' not found\n", traceName);
265                     System.exit(1);
266                 }
267             }
268 
269             try {
270                 reader = new DmTraceReader(traceName, regression);
271             } catch (IOException e) {
272                 System.err.printf("Failed to read the trace file");
273                 e.printStackTrace();
274                 System.exit(1);
275                 return;
276             }
277         }
278 
279         reader.getTraceUnits().setTimeScale(TraceUnits.TimeScale.MilliSeconds);
280 
281         Display.setAppName("Traceview");
282         new MainWindow(traceName, reader).run();
283     }
284 }
285