OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / sdk / ddms / app / src / com / android / ddms / PrefsDialog.java
1 /* //device/tools/ddms/src/com/android/ddms/PrefsDialog.java
2 **
3 ** Copyright 2007, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 package com.android.ddms;
19
20 import com.android.ddmlib.DdmConstants;
21 import com.android.ddmlib.DdmPreferences;
22 import com.android.ddmlib.Log;
23 import com.android.ddmlib.Log.LogLevel;
24 import com.android.ddmuilib.DdmUiPreferences;
25 import com.android.ddmuilib.PortFieldEditor;
26 import com.android.sdkstats.SdkStatsService;
27
28 import org.eclipse.jface.preference.BooleanFieldEditor;
29 import org.eclipse.jface.preference.DirectoryFieldEditor;
30 import org.eclipse.jface.preference.FieldEditorPreferencePage;
31 import org.eclipse.jface.preference.FontFieldEditor;
32 import org.eclipse.jface.preference.IntegerFieldEditor;
33 import org.eclipse.jface.preference.PreferenceDialog;
34 import org.eclipse.jface.preference.PreferenceManager;
35 import org.eclipse.jface.preference.PreferenceNode;
36 import org.eclipse.jface.preference.PreferencePage;
37 import org.eclipse.jface.preference.PreferenceStore;
38 import org.eclipse.jface.preference.RadioGroupFieldEditor;
39 import org.eclipse.jface.util.IPropertyChangeListener;
40 import org.eclipse.jface.util.PropertyChangeEvent;
41 import org.eclipse.swt.SWT;
42 import org.eclipse.swt.events.SelectionAdapter;
43 import org.eclipse.swt.events.SelectionEvent;
44 import org.eclipse.swt.graphics.FontData;
45 import org.eclipse.swt.graphics.Point;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Composite;
49 import org.eclipse.swt.widgets.Control;
50 import org.eclipse.swt.widgets.Link;
51 import org.eclipse.swt.widgets.Shell;
52
53 import java.io.File;
54 import java.io.IOException;
55
56 /**
57  * Preferences dialog.
58  */
59 public final class PrefsDialog {
60
61     // Preference store.
62     private static PreferenceStore mPrefStore;
63
64     // public const values for storage
65     public final static String SHELL_X = "shellX"; //$NON-NLS-1$
66     public final static String SHELL_Y = "shellY"; //$NON-NLS-1$
67     public final static String SHELL_WIDTH = "shellWidth"; //$NON-NLS-1$
68     public final static String SHELL_HEIGHT = "shellHeight"; //$NON-NLS-1$
69     public final static String EXPLORER_SHELL_X = "explorerShellX"; //$NON-NLS-1$
70     public final static String EXPLORER_SHELL_Y = "explorerShellY"; //$NON-NLS-1$
71     public final static String EXPLORER_SHELL_WIDTH = "explorerShellWidth"; //$NON-NLS-1$
72     public final static String EXPLORER_SHELL_HEIGHT = "explorerShellHeight"; //$NON-NLS-1$
73     public final static String SHOW_NATIVE_HEAP = "native"; //$NON-NLS-1$
74
75     public final static String LOGCAT_COLUMN_MODE = "ddmsLogColumnMode"; //$NON-NLS-1$
76     public final static String LOGCAT_FONT = "ddmsLogFont"; //$NON-NLS-1$
77
78     public final static String LOGCAT_COLUMN_MODE_AUTO = "auto"; //$NON-NLS-1$
79     public final static String LOGCAT_COLUMN_MODE_MANUAL = "manual"; //$NON-NLS-1$
80
81     private final static String PREFS_DEBUG_PORT_BASE = "adbDebugBasePort"; //$NON-NLS-1$
82     private final static String PREFS_SELECTED_DEBUG_PORT = "debugSelectedPort"; //$NON-NLS-1$
83     private final static String PREFS_DEFAULT_THREAD_UPDATE = "defaultThreadUpdateEnabled"; //$NON-NLS-1$
84     private final static String PREFS_DEFAULT_HEAP_UPDATE = "defaultHeapUpdateEnabled"; //$NON-NLS-1$
85     private final static String PREFS_THREAD_REFRESH_INTERVAL = "threadStatusInterval"; //$NON-NLS-1$
86     private final static String PREFS_LOG_LEVEL = "ddmsLogLevel"; //$NON-NLS-1$
87     private final static String PREFS_TIMEOUT = "timeOut"; //$NON-NLS-1$
88
89
90     /**
91      * Private constructor -- do not instantiate.
92      */
93     private PrefsDialog() {}
94
95     /**
96      * Return the PreferenceStore that holds our values.
97      */
98     public static PreferenceStore getStore() {
99         return mPrefStore;
100     }
101
102     /**
103      * Save the prefs to the config file.
104      */
105     public static void save() {
106         try {
107             mPrefStore.save();
108         }
109         catch (IOException ioe) {
110             Log.w("ddms", "Failed saving prefs file: " + ioe.getMessage());
111         }
112     }
113
114     /**
115      * Do some one-time prep.
116      *
117      * The original plan was to let the individual classes define their
118      * own defaults, which we would get and then override with the config
119      * file.  However, PreferencesStore.load() doesn't trigger the "changed"
120      * events, which means we have to pull the loaded config values out by
121      * hand.
122      *
123      * So, we set the defaults, load the values from the config file, and
124      * then run through and manually export the values.  Then we duplicate
125      * the second part later on for the "changed" events.
126      */
127     public static void init() {
128         assert mPrefStore == null;
129
130         mPrefStore = SdkStatsService.getPreferenceStore();
131
132         if (mPrefStore == null) {
133             // we have a serious issue here...
134             Log.e("ddms",
135                     "failed to access both the user HOME directory and the system wide temp folder. Quitting.");
136             System.exit(1);
137         }
138
139         // configure default values
140         setDefaults(System.getProperty("user.home")); //$NON-NLS-1$
141
142         // listen for changes
143         mPrefStore.addPropertyChangeListener(new ChangeListener());
144
145         // Now we initialize the value of the preference, from the values in the store.
146
147         // First the ddm lib.
148         DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
149         DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
150         DdmPreferences.setLogLevel(mPrefStore.getString(PREFS_LOG_LEVEL));
151         DdmPreferences.setInitialThreadUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_THREAD_UPDATE));
152         DdmPreferences.setInitialHeapUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_HEAP_UPDATE));
153         DdmPreferences.setTimeOut(mPrefStore.getInt(PREFS_TIMEOUT));
154
155         // some static values
156         String out = System.getenv("ANDROID_PRODUCT_OUT"); //$NON-NLS-1$
157         DdmUiPreferences.setSymbolsLocation(out + File.separator + "symbols"); //$NON-NLS-1$
158         DdmUiPreferences.setAddr2LineLocation("arm-eabi-addr2line"); //$NON-NLS-1$
159
160         String traceview = System.getProperty("com.android.ddms.bindir");  //$NON-NLS-1$
161         if (traceview != null && traceview.length() != 0) {
162             traceview += File.separator + DdmConstants.FN_TRACEVIEW;
163         } else {
164             traceview = DdmConstants.FN_TRACEVIEW;
165         }
166         DdmUiPreferences.setTraceviewLocation(traceview);
167
168         // Now the ddmui lib
169         DdmUiPreferences.setStore(mPrefStore);
170         DdmUiPreferences.setThreadRefreshInterval(mPrefStore.getInt(PREFS_THREAD_REFRESH_INTERVAL));
171     }
172
173     /*
174      * Set default values for all preferences.  These are either defined
175      * statically or are based on the values set by the class initializers
176      * in other classes.
177      *
178      * The other threads (e.g. VMWatcherThread) haven't been created yet,
179      * so we want to use static values rather than reading fields from
180      * class.getInstance().
181      */
182     private static void setDefaults(String homeDir) {
183         mPrefStore.setDefault(PREFS_DEBUG_PORT_BASE, DdmPreferences.DEFAULT_DEBUG_PORT_BASE);
184
185         mPrefStore.setDefault(PREFS_SELECTED_DEBUG_PORT,
186                 DdmPreferences.DEFAULT_SELECTED_DEBUG_PORT);
187
188         mPrefStore.setDefault(PREFS_DEFAULT_THREAD_UPDATE, true);
189         mPrefStore.setDefault(PREFS_DEFAULT_HEAP_UPDATE, false);
190         mPrefStore.setDefault(PREFS_THREAD_REFRESH_INTERVAL,
191             DdmUiPreferences.DEFAULT_THREAD_REFRESH_INTERVAL);
192
193         mPrefStore.setDefault("textSaveDir", homeDir); //$NON-NLS-1$
194         mPrefStore.setDefault("imageSaveDir", homeDir); //$NON-NLS-1$
195
196         mPrefStore.setDefault(PREFS_LOG_LEVEL, "info"); //$NON-NLS-1$
197
198         mPrefStore.setDefault(PREFS_TIMEOUT, DdmPreferences.DEFAULT_TIMEOUT);
199
200         // choose a default font for the text output
201         FontData fdat = new FontData("Courier", 10, SWT.NORMAL); //$NON-NLS-1$
202         mPrefStore.setDefault("textOutputFont", fdat.toString()); //$NON-NLS-1$
203
204         // layout information.
205         mPrefStore.setDefault(SHELL_X, 100);
206         mPrefStore.setDefault(SHELL_Y, 100);
207         mPrefStore.setDefault(SHELL_WIDTH, 800);
208         mPrefStore.setDefault(SHELL_HEIGHT, 600);
209
210         mPrefStore.setDefault(EXPLORER_SHELL_X, 50);
211         mPrefStore.setDefault(EXPLORER_SHELL_Y, 50);
212
213         mPrefStore.setDefault(SHOW_NATIVE_HEAP, false);
214     }
215
216
217     /*
218      * Create a "listener" to take action when preferences change.  These are
219      * required for ongoing activities that don't check prefs on each use.
220      *
221      * This is only invoked when something explicitly changes the value of
222      * a preference (e.g. not when the prefs file is loaded).
223      */
224     private static class ChangeListener implements IPropertyChangeListener {
225         public void propertyChange(PropertyChangeEvent event) {
226             String changed = event.getProperty();
227
228             if (changed.equals(PREFS_DEBUG_PORT_BASE)) {
229                 DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
230             } else if (changed.equals(PREFS_SELECTED_DEBUG_PORT)) {
231                 DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
232             } else if (changed.equals(PREFS_LOG_LEVEL)) {
233                 DdmPreferences.setLogLevel((String)event.getNewValue());
234             } else if (changed.equals("textSaveDir")) {
235                 mPrefStore.setValue("lastTextSaveDir",
236                     (String) event.getNewValue());
237             } else if (changed.equals("imageSaveDir")) {
238                 mPrefStore.setValue("lastImageSaveDir",
239                     (String) event.getNewValue());
240             } else if (changed.equals(PREFS_TIMEOUT)) {
241                 DdmPreferences.setTimeOut(mPrefStore.getInt(PREFS_TIMEOUT));
242             } else {
243                 Log.v("ddms", "Preference change: " + event.getProperty()
244                     + ": '" + event.getOldValue()
245                     + "' --> '" + event.getNewValue() + "'");
246             }
247         }
248     }
249
250
251     /**
252      * Create and display the dialog.
253      */
254     public static void run(Shell shell) {
255         assert mPrefStore != null;
256
257         PreferenceManager prefMgr = new PreferenceManager();
258
259         PreferenceNode node, subNode;
260
261         // this didn't work -- got NPE, possibly from class lookup:
262         //PreferenceNode app = new PreferenceNode("app", "Application", null,
263         //    AppPrefs.class.getName());
264
265         node = new PreferenceNode("debugger", new DebuggerPrefs());
266         prefMgr.addToRoot(node);
267
268         subNode = new PreferenceNode("panel", new PanelPrefs());
269         //prefMgr.addTo(node.getId(), subNode);
270         prefMgr.addToRoot(subNode);
271
272         node = new PreferenceNode("LogCat", new LogCatPrefs());
273         prefMgr.addToRoot(node);
274
275         node = new PreferenceNode("misc", new MiscPrefs());
276         prefMgr.addToRoot(node);
277
278         node = new PreferenceNode("stats", new UsageStatsPrefs());
279         prefMgr.addToRoot(node);
280
281         PreferenceDialog dlg = new PreferenceDialog(shell, prefMgr);
282         dlg.setPreferenceStore(mPrefStore);
283
284         // run it
285         dlg.open();
286
287         // save prefs
288         try {
289             mPrefStore.save();
290         }
291         catch (IOException ioe) {
292         }
293
294         // discard the stuff we created
295         //prefMgr.dispose();
296         //dlg.dispose();
297     }
298
299     /**
300      * "Debugger" prefs page.
301      */
302     private static class DebuggerPrefs extends FieldEditorPreferencePage {
303
304         /**
305          * Basic constructor.
306          */
307         public DebuggerPrefs() {
308             super(GRID);        // use "grid" layout so edit boxes line up
309             setTitle("Debugger");
310         }
311
312          /**
313          * Create field editors.
314          */
315         @Override
316         protected void createFieldEditors() {
317             IntegerFieldEditor ife;
318
319             ife = new PortFieldEditor(PREFS_DEBUG_PORT_BASE,
320                 "Starting value for local port:", getFieldEditorParent());
321             addField(ife);
322
323             ife = new PortFieldEditor(PREFS_SELECTED_DEBUG_PORT,
324                 "Port of Selected VM:", getFieldEditorParent());
325             addField(ife);
326         }
327     }
328
329     /**
330      * "Panel" prefs page.
331      */
332     private static class PanelPrefs extends FieldEditorPreferencePage {
333
334         /**
335          * Basic constructor.
336          */
337         public PanelPrefs() {
338             super(FLAT);        // use "flat" layout
339             setTitle("Info Panels");
340         }
341
342         /**
343          * Create field editors.
344          */
345         @Override
346         protected void createFieldEditors() {
347             BooleanFieldEditor bfe;
348             IntegerFieldEditor ife;
349
350             bfe = new BooleanFieldEditor(PREFS_DEFAULT_THREAD_UPDATE,
351                 "Thread updates enabled by default", getFieldEditorParent());
352             addField(bfe);
353
354             bfe = new BooleanFieldEditor(PREFS_DEFAULT_HEAP_UPDATE,
355                 "Heap updates enabled by default", getFieldEditorParent());
356             addField(bfe);
357
358             ife = new IntegerFieldEditor(PREFS_THREAD_REFRESH_INTERVAL,
359                 "Thread status interval (seconds):", getFieldEditorParent());
360             ife.setValidRange(1, 60);
361             addField(ife);
362         }
363     }
364
365     /**
366      * "logcat" prefs page.
367      */
368     private static class LogCatPrefs extends FieldEditorPreferencePage {
369
370         /**
371          * Basic constructor.
372          */
373         public LogCatPrefs() {
374             super(FLAT);        // use "flat" layout
375             setTitle("Logcat");
376         }
377
378         /**
379          * Create field editors.
380          */
381         @Override
382         protected void createFieldEditors() {
383             RadioGroupFieldEditor rgfe;
384
385             rgfe = new RadioGroupFieldEditor(PrefsDialog.LOGCAT_COLUMN_MODE,
386                 "Message Column Resizing Mode", 1, new String[][] {
387                     { "Manual", PrefsDialog.LOGCAT_COLUMN_MODE_MANUAL },
388                     { "Automatic", PrefsDialog.LOGCAT_COLUMN_MODE_AUTO },
389                     },
390                 getFieldEditorParent(), true);
391             addField(rgfe);
392
393             FontFieldEditor ffe = new FontFieldEditor(PrefsDialog.LOGCAT_FONT, "Text output font:",
394                     getFieldEditorParent());
395             addField(ffe);
396         }
397     }
398
399     /**
400      * "misc" prefs page.
401      */
402     private static class MiscPrefs extends FieldEditorPreferencePage {
403
404         /**
405          * Basic constructor.
406          */
407         public MiscPrefs() {
408             super(FLAT);        // use "flat" layout
409             setTitle("Misc");
410         }
411
412         /**
413          * Create field editors.
414          */
415         @Override
416         protected void createFieldEditors() {
417             DirectoryFieldEditor dfe;
418             FontFieldEditor ffe;
419
420             IntegerFieldEditor ife = new IntegerFieldEditor(PREFS_TIMEOUT,
421                     "ADB connection time out (ms):", getFieldEditorParent());
422             addField(ife);
423
424             dfe = new DirectoryFieldEditor("textSaveDir",
425                 "Default text save dir:", getFieldEditorParent());
426             addField(dfe);
427
428             dfe = new DirectoryFieldEditor("imageSaveDir",
429                 "Default image save dir:", getFieldEditorParent());
430             addField(dfe);
431
432             ffe = new FontFieldEditor("textOutputFont", "Text output font:",
433                 getFieldEditorParent());
434             addField(ffe);
435
436             RadioGroupFieldEditor rgfe;
437
438             rgfe = new RadioGroupFieldEditor(PREFS_LOG_LEVEL,
439                 "Logging Level", 1, new String[][] {
440                     { "Verbose", LogLevel.VERBOSE.getStringValue() },
441                     { "Debug", LogLevel.DEBUG.getStringValue() },
442                     { "Info", LogLevel.INFO.getStringValue() },
443                     { "Warning", LogLevel.WARN.getStringValue() },
444                     { "Error", LogLevel.ERROR.getStringValue() },
445                     { "Assert", LogLevel.ASSERT.getStringValue() },
446                     },
447                 getFieldEditorParent(), true);
448             addField(rgfe);
449         }
450     }
451
452     /**
453      * "Device" prefs page.
454      */
455     private static class UsageStatsPrefs extends PreferencePage {
456
457         private BooleanFieldEditor mOptInCheckbox;
458         private Composite mTop;
459
460         /**
461          * Basic constructor.
462          */
463         public UsageStatsPrefs() {
464             setTitle("Usage Stats");
465         }
466
467         @Override
468         protected Control createContents(Composite parent) {
469             mTop = new Composite(parent, SWT.NONE);
470             mTop.setLayout(new GridLayout(1, false));
471             mTop.setLayoutData(new GridData(GridData.FILL_BOTH));
472
473             Link text = new Link(mTop, SWT.WRAP);
474             text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
475             text.setText(SdkStatsService.BODY_TEXT);
476
477             text.addSelectionListener(new SelectionAdapter() {
478                 @Override
479                 public void widgetSelected(SelectionEvent event) {
480                     SdkStatsService.openUrl(event.text);
481                 }
482             });
483
484             mOptInCheckbox = new BooleanFieldEditor(SdkStatsService.PING_OPT_IN,
485                     SdkStatsService.CHECKBOX_TEXT, mTop);
486             mOptInCheckbox.setPage(this);
487             mOptInCheckbox.setPreferenceStore(getPreferenceStore());
488             mOptInCheckbox.load();
489
490             return null;
491         }
492
493         @Override
494         protected Point doComputeSize() {
495             if (mTop != null) {
496                 return mTop.computeSize(450, SWT.DEFAULT, true);
497             }
498
499             return super.doComputeSize();
500         }
501
502         @Override
503         protected void performDefaults() {
504             if (mOptInCheckbox != null) {
505                 mOptInCheckbox.loadDefault();
506             }
507             super.performDefaults();
508         }
509
510         @Override
511         public void performApply() {
512             if (mOptInCheckbox != null) {
513                 mOptInCheckbox.store();
514             }
515             super.performApply();
516         }
517
518         @Override
519         public boolean performOk() {
520             if (mOptInCheckbox != null) {
521                 mOptInCheckbox.store();
522             }
523             return super.performOk();
524         }
525     }
526
527 }
528
529