• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.ide.eclipse.ddms.systrace;
18 
19 import org.eclipse.jface.dialogs.TitleAreaDialog;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.ModifyEvent;
22 import org.eclipse.swt.events.ModifyListener;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.FileDialog;
31 import org.eclipse.swt.widgets.Group;
32 import org.eclipse.swt.widgets.Label;
33 import org.eclipse.swt.widgets.Shell;
34 import org.eclipse.swt.widgets.Text;
35 
36 import java.io.File;
37 
38 public class SystraceOptionsDialogV1 extends TitleAreaDialog implements ISystraceOptionsDialog {
39     private static final String TITLE = "Android System Trace";
40     private static final String DEFAULT_MESSAGE =
41             "Settings to use while capturing system level trace";
42     private static final String DEFAULT_TRACE_FNAME = "trace.html"; //$NON-NLS-1$
43 
44     private Text mDestinationText;
45     private String mDestinationPath;
46     private Text mTraceDurationText;
47     private Text mTraceBufferSizeText;
48 
49     private static String sSaveToFolder = System.getProperty("user.home"); //$NON-NLS-1$
50     private static String sTraceDuration = "";
51     private static String sTraceBufferSize = "";
52 
53     private Button mTraceCpuFreqBtn;
54     private Button mTraceCpuIdleBtn;
55     private Button mTraceCpuLoadBtn;
56     private Button mTraceDiskIoBtn;
57     private Button mTraceKernelWorkqueuesBtn;
58     private Button mTraceCpuSchedulerBtn;
59 
60     private static boolean sTraceCpuFreq;
61     private static boolean sTraceCpuIdle;
62     private static boolean sTraceCpuLoad;
63     private static boolean sTraceDiskIo;
64     private static boolean sTraceKernelWorkqueues;
65     private static boolean sTraceCpuScheduler;
66 
67     private Button mGfxTagBtn;
68     private Button mInputTagBtn;
69     private Button mViewTagBtn;
70     private Button mWebViewTagBtn;
71     private Button mWmTagBtn;
72     private Button mAmTagBtn;
73     private Button mSyncTagBtn;
74     private Button mAudioTagBtn;
75     private Button mVideoTagBtn;
76     private Button mCameraTagBtn;
77 
78     private static boolean sGfxTag;
79     private static boolean sInputTag;
80     private static boolean sViewTag;
81     private static boolean sWebViewTag;
82     private static boolean sWmTag;
83     private static boolean sAmTag;
84     private static boolean sSyncTag;
85     private static boolean sAudioTag;
86     private static boolean sVideoTag;
87     private static boolean sCameraTag;
88 
89     private final SystraceOptions mOptions = new SystraceOptions();
90 
SystraceOptionsDialogV1(Shell parentShell)91     public SystraceOptionsDialogV1(Shell parentShell) {
92         super(parentShell);
93     }
94 
95     @Override
createDialogArea(Composite parent)96     protected Control createDialogArea(Composite parent) {
97         setTitle(TITLE);
98         setMessage(DEFAULT_MESSAGE);
99 
100         Composite c = new Composite(parent, SWT.BORDER);
101         c.setLayout(new GridLayout(3, false));
102         c.setLayoutData(new GridData(GridData.FILL_BOTH));
103 
104         Label l = new Label(c, SWT.NONE);
105         l.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
106         l.setText("Destination File: ");
107 
108         mDestinationText = new Text(c, SWT.BORDER);
109         mDestinationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
110         mDestinationText.setText(sSaveToFolder + File.separator + DEFAULT_TRACE_FNAME);
111 
112         final Button browse = new Button(c, SWT.NONE);
113         browse.setText("Browse...");
114         browse.addSelectionListener(new SelectionAdapter() {
115             @Override
116             public void widgetSelected(SelectionEvent e) {
117                 String path = openBrowseDialog(browse.getShell());
118                 if (path != null) mDestinationText.setText(path);
119             }
120         });
121 
122         Label lblTraceDurationseconds = new Label(c, SWT.NONE);
123         lblTraceDurationseconds.setLayoutData(
124                 new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
125         lblTraceDurationseconds.setText("Trace duration (seconds): ");
126 
127         mTraceDurationText = new Text(c, SWT.BORDER);
128         mTraceDurationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
129         mTraceDurationText.setText(sTraceDuration);
130 
131         Label lblTraceBufferSize = new Label(c, SWT.NONE);
132         lblTraceBufferSize.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
133         lblTraceBufferSize.setText("Trace Buffer Size (kb): ");
134 
135         mTraceBufferSizeText = new Text(c, SWT.BORDER);
136         mTraceBufferSizeText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
137         mTraceBufferSizeText.setText(sTraceBufferSize);
138 
139         Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL);
140         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
141         gd.horizontalSpan = 3;
142         separator.setLayoutData(gd);
143 
144         Group grpTraceEvents = new Group(c, SWT.BORDER);
145         grpTraceEvents.setLayout(new GridLayout(3, false));
146         grpTraceEvents.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
147         grpTraceEvents.setText("Trace Events");
148 
149         mTraceCpuFreqBtn = new Button(grpTraceEvents, SWT.CHECK);
150         mTraceCpuFreqBtn.setText("CPU Frequency Changes");
151         mTraceCpuFreqBtn.setSelection(sTraceCpuFreq);
152 
153         mTraceCpuIdleBtn = new Button(grpTraceEvents, SWT.CHECK);
154         mTraceCpuIdleBtn.setText("CPU Idle Events");
155         mTraceCpuIdleBtn.setSelection(sTraceCpuIdle);
156 
157         mTraceCpuLoadBtn = new Button(grpTraceEvents, SWT.CHECK);
158         mTraceCpuLoadBtn.setText("CPU Load");
159         mTraceCpuLoadBtn.setSelection(sTraceCpuLoad);
160 
161         mTraceCpuSchedulerBtn = new Button(grpTraceEvents, SWT.CHECK);
162         mTraceCpuSchedulerBtn.setText("CPU Scheduler");
163         mTraceCpuSchedulerBtn.setSelection(sTraceCpuScheduler);
164 
165         Group grpTraceRootEvents = new Group(c, SWT.BORDER);
166         grpTraceRootEvents.setLayout(new GridLayout(2, false));
167         grpTraceRootEvents.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
168         grpTraceRootEvents.setText("Trace Events that require root privileges on device");
169 
170         mTraceDiskIoBtn = new Button(grpTraceRootEvents, SWT.CHECK);
171         mTraceDiskIoBtn.setText("Disk I/O");
172         mTraceDiskIoBtn.setSelection(sTraceDiskIo);
173 
174         mTraceKernelWorkqueuesBtn = new Button(grpTraceRootEvents, SWT.CHECK);
175         mTraceKernelWorkqueuesBtn.setText("Kernel Workqueues (requires root)");
176         mTraceKernelWorkqueuesBtn.setSelection(sTraceKernelWorkqueues);
177 
178         Group grpTraceTags = new Group(c, SWT.BORDER);
179         grpTraceTags.setLayout(new GridLayout(5, false));
180         grpTraceTags.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1));
181         grpTraceTags.setText("Trace Tags");
182 
183         mGfxTagBtn = new Button(grpTraceTags, SWT.CHECK);
184         mGfxTagBtn.setText("gfx");
185         mGfxTagBtn.setSelection(sGfxTag);
186 
187         mInputTagBtn = new Button(grpTraceTags, SWT.CHECK);
188         mInputTagBtn.setText("input");
189         mInputTagBtn.setSelection(sInputTag);
190 
191         mViewTagBtn = new Button(grpTraceTags, SWT.CHECK);
192         mViewTagBtn.setText("view");
193         mViewTagBtn.setSelection(sViewTag);
194 
195         mWebViewTagBtn = new Button(grpTraceTags, SWT.CHECK);
196         mWebViewTagBtn.setText("webview");
197         mWebViewTagBtn.setSelection(sWebViewTag);
198 
199         mWmTagBtn = new Button(grpTraceTags, SWT.CHECK);
200         mWmTagBtn.setText("wm");
201         mWmTagBtn.setSelection(sWmTag);
202 
203         mAmTagBtn = new Button(grpTraceTags, SWT.CHECK);
204         mAmTagBtn.setText("am");
205         mAmTagBtn.setSelection(sAmTag);
206 
207         mSyncTagBtn = new Button(grpTraceTags, SWT.CHECK);
208         mSyncTagBtn.setText("sync");
209         mSyncTagBtn.setSelection(sSyncTag);
210 
211         mAudioTagBtn = new Button(grpTraceTags, SWT.CHECK);
212         mAudioTagBtn.setText("audio");
213         mAudioTagBtn.setSelection(sAudioTag);
214 
215         mVideoTagBtn = new Button(grpTraceTags, SWT.CHECK);
216         mVideoTagBtn.setText("video");
217         mVideoTagBtn.setSelection(sVideoTag);
218 
219         mCameraTagBtn = new Button(grpTraceTags, SWT.CHECK);
220         mCameraTagBtn.setText("camera");
221         mCameraTagBtn.setSelection(sCameraTag);
222 
223         Label lblTraceTagsWarning = new Label(grpTraceTags, SWT.NONE);
224         lblTraceTagsWarning.setText(
225                 "Changes to trace tags will likely need a restart of the Android framework to take effect:\n"
226                 + "    $ adb shell stop\n"
227                 + "    $ adb shell start");
228         lblTraceTagsWarning.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 5, 1));
229 
230         ModifyListener m = new ModifyListener() {
231             @Override
232             public void modifyText(ModifyEvent e) {
233                 validateFields();
234             }
235         };
236 
237         mDestinationText.addModifyListener(m);
238         mTraceBufferSizeText.addModifyListener(m);
239         mTraceDurationText.addModifyListener(m);
240 
241         return c;
242     }
243 
validateFields()244     private void validateFields() {
245         // validate trace destination path
246         String msg = validatePath(mDestinationText.getText());
247         if (msg != null) {
248             setErrorMessage(msg);
249             getButton(OK).setEnabled(false);
250             return;
251         }
252 
253         // validate the trace duration
254         if (!validateInteger(mTraceDurationText.getText())) {
255             setErrorMessage("Trace Duration should be a valid integer (seconds)");
256             getButton(OK).setEnabled(false);
257             return;
258         }
259 
260         // validate the trace buffer size
261         if (!validateInteger(mTraceBufferSizeText.getText())) {
262             setErrorMessage("Trace Buffer Size should be a valid integer (kilobytes)");
263             getButton(OK).setEnabled(false);
264             return;
265         }
266 
267         getButton(OK).setEnabled(true);
268         setErrorMessage(null);
269     }
270 
validateInteger(String text)271     private boolean validateInteger(String text) {
272         if (text == null || text.isEmpty()) {
273             return true;
274         }
275 
276         try {
277             Integer.parseInt(text);
278             return true;
279         } catch (NumberFormatException e) {
280             return false;
281         }
282     }
283 
validatePath(String path)284     private String validatePath(String path) {
285         if (path == null || path.isEmpty()) {
286             return null;
287         }
288 
289         File f = new File(path);
290         if (f.isDirectory()) {
291             return String.format("The path '%s' points to a folder", path);
292         }
293 
294         if (!f.exists()) { // if such a file doesn't exist, make sure the parent folder is valid
295             if (!f.getParentFile().isDirectory()) {
296                 return String.format("That path '%s' is not a valid folder.", f.getParent());
297             }
298         }
299 
300         return null;
301     }
302 
openBrowseDialog(Shell parentShell)303     private String openBrowseDialog(Shell parentShell) {
304         FileDialog fd = new FileDialog(parentShell, SWT.SAVE);
305 
306         fd.setText("Save To");
307         fd.setFileName(DEFAULT_TRACE_FNAME);
308 
309         fd.setFilterPath(sSaveToFolder);
310         fd.setFilterExtensions(new String[] { "*.html" }); //$NON-NLS-1$
311 
312         String fname = fd.open();
313         if (fname == null || fname.trim().length() == 0) {
314             return null;
315         }
316 
317         sSaveToFolder = fd.getFilterPath();
318         return fname;
319     }
320 
321     @Override
okPressed()322     protected void okPressed() {
323         mDestinationPath = mDestinationText.getText().trim();
324 
325         sTraceDuration = mTraceDurationText.getText();
326         if (!sTraceDuration.isEmpty()) {
327             mOptions.mTraceDuration = Integer.parseInt(sTraceDuration);
328         }
329 
330         sTraceBufferSize = mTraceBufferSizeText.getText();
331         if (!sTraceBufferSize.isEmpty()) {
332             mOptions.mTraceBufferSize = Integer.parseInt(sTraceBufferSize);
333         }
334 
335         mOptions.mTraceCpuFreq = mTraceCpuFreqBtn.getSelection();
336         mOptions.mTraceCpuIdle = mTraceCpuIdleBtn.getSelection();
337         mOptions.mTraceCpuLoad = mTraceCpuLoadBtn.getSelection();
338         mOptions.mTraceDiskIo = mTraceDiskIoBtn.getSelection();
339         mOptions.mTraceKernelWorkqueues = mTraceKernelWorkqueuesBtn.getSelection();
340         mOptions.mTraceCpuScheduler = mTraceCpuSchedulerBtn.getSelection();
341 
342         if (mGfxTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_GFX);
343         if (mInputTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_INPUT);
344         if (mViewTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_VIEW);
345         if (mWebViewTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_WEBVIEW);
346         if (mWmTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_WM);
347         if (mAmTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_AM);
348         if (mSyncTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_SYNC);
349         if (mAudioTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_AUDIO);
350         if (mVideoTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_VIDEO);
351         if (mCameraTagBtn.getSelection()) mOptions.enableTag(SystraceOptions.TAG_CAMERA);
352 
353         // save current selections to be restored if the dialog is invoked again
354         sTraceCpuFreq = mTraceCpuFreqBtn.getSelection();
355         sTraceCpuIdle = mTraceCpuIdleBtn.getSelection();
356         sTraceCpuLoad = mTraceCpuLoadBtn.getSelection();
357         sTraceDiskIo = mTraceDiskIoBtn.getSelection();
358         sTraceKernelWorkqueues = mTraceKernelWorkqueuesBtn.getSelection();
359         sTraceCpuScheduler = mTraceCpuSchedulerBtn.getSelection();
360 
361         sGfxTag = mGfxTagBtn.getSelection();
362         sInputTag = mInputTagBtn.getSelection();
363         sViewTag = mViewTagBtn.getSelection();
364         sWebViewTag = mWebViewTagBtn.getSelection();
365         sWmTag = mWmTagBtn.getSelection();
366         sAmTag = mAmTagBtn.getSelection();
367         sSyncTag = mSyncTagBtn.getSelection();
368         sAudioTag = mAudioTagBtn.getSelection();
369         sVideoTag = mVideoTagBtn.getSelection();
370         sCameraTag = mCameraTagBtn.getSelection();
371 
372         super.okPressed();
373     }
374 
375     @Override
getSystraceOptions()376     public SystraceOptions getSystraceOptions() {
377         return mOptions;
378     }
379 
380     @Override
getTraceFilePath()381     public String getTraceFilePath() {
382         return mDestinationPath;
383     }
384 
385     private class SystraceOptions implements ISystraceOptions {
386         // This list is based on the tags in frameworks/native/include/utils/Trace.h
387         private static final int TAG_GFX = 1 << 1;
388         private static final int TAG_INPUT = 1 << 2;
389         private static final int TAG_VIEW = 1 << 3;
390         private static final int TAG_WEBVIEW = 1 << 4;
391         private static final int TAG_WM = 1 << 5;
392         private static final int TAG_AM = 1 << 6;
393         private static final int TAG_SYNC = 1 << 7;
394         private static final int TAG_AUDIO = 1 << 8;
395         private static final int TAG_VIDEO = 1 << 9;
396         private static final int TAG_CAMERA = 1 << 10;
397 
398         private int mTraceBufferSize;
399         private int mTraceDuration;
400 
401         private boolean mTraceCpuFreq;
402         private boolean mTraceCpuIdle;
403         private boolean mTraceCpuLoad;
404         private boolean mTraceDiskIo;
405         private boolean mTraceKernelWorkqueues;
406         private boolean mTraceCpuScheduler;
407 
408         private int mTag;
409 
enableTag(int tag)410         private void enableTag(int tag) {
411             mTag |= tag;
412         }
413 
414         @Override
getTags()415         public String getTags() {
416             return mTag == 0 ? null : "0x" + Integer.toHexString(mTag);
417         }
418 
419         @Override
getOptions()420         public String getOptions() {
421             StringBuilder sb = new StringBuilder(20);
422 
423             if (mTraceCpuFreq) sb.append("-f "); //$NON-NLS-1$
424             if (mTraceCpuIdle) sb.append("-i "); //$NON-NLS-1$
425             if (mTraceCpuLoad) sb.append("-l "); //$NON-NLS-1$
426             if (mTraceDiskIo) sb.append("-d ");  //$NON-NLS-1$
427             if (mTraceKernelWorkqueues) sb.append("-w "); //$NON-NLS-1$
428             if (mTraceCpuScheduler) sb.append("-s "); //$NON-NLS-1$
429 
430             if (mTraceDuration > 0) {
431                 sb.append("-t");    //$NON-NLS-1$
432                 sb.append(mTraceDuration);
433                 sb.append(' ');
434             }
435 
436             if (mTraceBufferSize > 0) {
437                 sb.append("-b ");	//$NON-NLS-1$
438                 sb.append(mTraceBufferSize);
439                 sb.append(' ');
440             }
441 
442             return sb.toString().trim();
443         }
444     }
445 }
446