diff options
6 files changed, 364 insertions, 26 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java index 7a3f5ec..45d0185 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java @@ -16,16 +16,34 @@ package com.android.ide.eclipse.monitor; +import com.android.ide.eclipse.monitor.SdkToolsLocator.SdkInstallStatus; + +import org.eclipse.core.runtime.Platform; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.jface.window.Window; +import org.eclipse.osgi.service.datalocation.Location; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; +import java.io.File; + public class MonitorApplication implements IApplication { + private static final String SDK_PATH_ENVVAR = "com.android.sdk.path"; + @Override public Object start(IApplicationContext context) throws Exception { Display display = PlatformUI.createDisplay(); + + String sdkPath = findSdkPath(display); + if (!isValidSdkLocation(sdkPath)) { + // exit with return code -1 + return Integer.valueOf(-1); + } + MonitorPlugin.getDefault().setSdkPath(sdkPath); + try { int returnCode = PlatformUI.createAndRunWorkbench(display, new MonitorWorkbenchAdvisor()); @@ -52,4 +70,68 @@ public class MonitorApplication implements IApplication { } }); } + + private String findSdkPath(Display display) { + // see if there is a system property set (passed in via a command line arg) + String sdkLocation = System.getProperty(SDK_PATH_ENVVAR); + if (isValidSdkLocation(sdkLocation)) { + return sdkLocation; + } + + // see if there is an environment variable set + sdkLocation = System.getenv(SDK_PATH_ENVVAR); + if (isValidSdkLocation(sdkLocation)) { + return sdkLocation; + } + + // check for the last used SDK + sdkLocation = MonitorPlugin.getDdmsPreferenceStore().getLastSdkPath(); + if (isValidSdkLocation(sdkLocation)) { + return sdkLocation; + } + + // The monitor app should be located in "<sdk>/tools/monitor/" + // So see if the folder one level up from the install location is a valid SDK. + Location install = Platform.getInstallLocation(); + if (install != null && install.getURL() != null) { + String toolsFolder = new File(install.getURL().getFile()).getParent(); + if (toolsFolder != null) { + sdkLocation = new File(toolsFolder).getParent(); + if (isValidSdkLocation(sdkLocation)) { + MonitorPlugin.getDdmsPreferenceStore().setLastSdkPath(sdkLocation); + return sdkLocation; + } + } + } + + // if nothing else works, prompt the user + sdkLocation = getSdkLocationFromUser(new Shell(display)); + if (isValidSdkLocation(sdkLocation)) { + MonitorPlugin.getDdmsPreferenceStore().setLastSdkPath(sdkLocation); + } + + return sdkLocation; + } + + private boolean isValidSdkLocation(String sdkLocation) { + if (sdkLocation == null) { + return false; + } + + if (sdkLocation.trim().length() == 0) { + return false; + } + + SdkToolsLocator locator = new SdkToolsLocator(sdkLocation); + return locator.isValidInstallation() == SdkInstallStatus.VALID; + } + + private String getSdkLocationFromUser(Shell shell) { + SdkLocationChooserDialog dlg = new SdkLocationChooserDialog(shell); + if (dlg.open() == Window.OK) { + return dlg.getPath(); + } else { + return null; + } + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java index 9449d6f..ca2c292 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java @@ -26,10 +26,12 @@ public class MonitorPlugin extends AbstractUIPlugin { public static final String PLUGIN_ID = "com.android.ide.eclipse.monitor"; //$NON-NLS-1$ private static MonitorPlugin sPlugin; private static final DdmsPreferenceStore sDdmsPreferenceStore = new DdmsPreferenceStore(); + private String mSdkPath; @Override public void start(BundleContext context) throws Exception { super.start(context); + sPlugin = this; } @@ -50,4 +52,12 @@ public class MonitorPlugin extends AbstractUIPlugin { public static DdmsPreferenceStore getDdmsPreferenceStore() { return sDdmsPreferenceStore; } + + public void setSdkPath(String sdkPath) { + mSdkPath = sdkPath; + } + + public String getSdkPath() { + return mSdkPath; + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkLocationChooserDialog.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkLocationChooserDialog.java new file mode 100644 index 0000000..76e2350 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkLocationChooserDialog.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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. + */ + +package com.android.ide.eclipse.monitor; + +import com.android.ide.eclipse.monitor.SdkToolsLocator.SdkInstallStatus; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.DirectoryDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class SdkLocationChooserDialog extends Dialog { + private static final String TITLE = "Android Device Monitor"; + private static final String DEFAULT_MESSAGE = "Provide the path to the Android SDK"; + + private Label mStatusLabel; + private Text mTextBox; + private String mPath; + + public SdkLocationChooserDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected Control createDialogArea(Composite parent) { + getShell().setText(TITLE); + + Composite c = new Composite((Composite) super.createDialogArea(parent), SWT.NONE); + c.setLayout(new GridLayout(2, false)); + c.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Label l = new Label(c, SWT.NONE); + l.setText(DEFAULT_MESSAGE); + GridDataFactory.fillDefaults().span(2, 1).applyTo(l); + + mTextBox = new Text(c, SWT.BORDER); + mTextBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridDataFactory.fillDefaults() + .hint(SwtUtils.getFontWidth(mTextBox) * 80, SWT.DEFAULT) + .applyTo(mTextBox); + mTextBox.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + validateInstall(); + } + }); + + Button browse = new Button(c, SWT.PUSH); + browse.setText("Browse"); + browse.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + DirectoryDialog dlg = new DirectoryDialog(getShell(), SWT.OPEN); + dlg.setText("Android SDK location"); + String dir = dlg.open(); + if (dir != null) { + mTextBox.setText(dir); + validateInstall(); + } + } + }); + + mStatusLabel = new Label(c, SWT.WRAP); + mStatusLabel.setText(""); + mStatusLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_RED)); + GridDataFactory.fillDefaults().span(2, 1).applyTo(mStatusLabel); + + return super.createDialogArea(parent); + } + + private void validateInstall() { + SdkToolsLocator locator = new SdkToolsLocator(mTextBox.getText()); + SdkInstallStatus status = locator.isValidInstallation(); + if (status.isValid()) { + mStatusLabel.setText(""); + getButton(IDialogConstants.OK_ID).setEnabled(true); + } else { + mStatusLabel.setText(status.getErrorMessage()); + mStatusLabel.pack(); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + } + + @Override + public boolean close() { + mPath = mTextBox.getText(); + return super.close(); + } + + public String getPath() { + return mPath; + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java new file mode 100644 index 0000000..ba87c7b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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. + */ + +package com.android.ide.eclipse.monitor; + +import com.android.ide.eclipse.ddms.IToolsLocator; +import com.android.sdklib.SdkConstants; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +/** + * {@link SdkToolsLocator} has two functions: <ul> + * <li> It implements all the methods of {@link IToolsLocator} interface, and + * so can be used as such. </li> + * <li> It provides the {@link #isValidInstallation()} method to check the validity + * of an installation. </li> + * The only reason this class does not explicitly implement the {@link IToolsLocator} interface + * is that it is used very early during the startup to check the validity of the installation. + * Actually implementing that interface causes other bundles to be activated before the + * Eclipse Platform is fully initialized, resulting in startup error. + */ +public class SdkToolsLocator { + public static final String PLATFORM_EXECUTABLE_EXTENSION = + (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ? + ".exe" : ""; //$NON-NLS-1$ + + public static final String PLATFORM_SCRIPT_EXTENSION = + (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ? + ".bat" : ""; //$NON-NLS-1$ + + public static final String FN_HPROF_CONV = "hprof-conv" + PLATFORM_EXECUTABLE_EXTENSION; //$NON-NLS-1$ + public static final String FN_TRACEVIEW = "traceview" + PLATFORM_SCRIPT_EXTENSION; //$NON-NLS-1$ + + private final String mSdkPath; + + public SdkToolsLocator(String sdkPath) { + mSdkPath = sdkPath; + } + + public String getAdbLocation() { + return getSdkPlatformToolsFolder() + SdkConstants.FN_ADB; + } + + public String getTraceViewLocation() { + return getSdkToolsFolder() + FN_TRACEVIEW; + } + + public String getHprofConvLocation() { + return getSdkToolsFolder() + FN_HPROF_CONV; + } + + private String getSdkToolsFolder() { + return mSdkPath + "/tools/"; //$NON-NLS-1$ + } + + private String getSdkPlatformToolsFolder() { + return mSdkPath + "/platform-tools/"; //$NON-NLS-1$ + } + + public SdkInstallStatus isValidInstallation() { + List<String> executables = Arrays.asList(getAdbLocation(), + getTraceViewLocation(), + getHprofConvLocation()); + + for (String exe : executables) { + File f = new File(exe); + if (!f.exists()) { + return SdkInstallStatus.invalidInstallation(exe + " not present."); + } + if (!f.canExecute()) { + return SdkInstallStatus.invalidInstallation(exe + " is not executable."); + } + } + + return SdkInstallStatus.VALID; + } + + public static class SdkInstallStatus { + private boolean mValid; + private String mCause; + + private SdkInstallStatus(boolean valid, String errorMessage) { + mValid = valid; + mCause = errorMessage; + } + + public boolean isValid() { + return mValid; + } + + public String getErrorMessage() { + return mCause; + } + + public static final SdkInstallStatus VALID = new SdkInstallStatus(true, ""); + + public static SdkInstallStatus invalidInstallation(String errorMessage) { + return new SdkInstallStatus(false, errorMessage); + } + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SwtUtils.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SwtUtils.java new file mode 100644 index 0000000..bae7f0b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SwtUtils.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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. + */ + +package com.android.ide.eclipse.monitor; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Control; + +public class SwtUtils { + public static int getFontWidth(Control c) { + GC gc = new GC(c); + int avgCharWidth = gc.getFontMetrics().getAverageCharWidth(); + gc.dispose(); + return avgCharWidth; + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java index b0cd8a5..ebee3c6 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java @@ -17,45 +17,26 @@ package com.android.ide.eclipse.monitor; import com.android.ide.eclipse.ddms.IToolsLocator; -import com.android.sdklib.SdkConstants; public class ToolsLocator implements IToolsLocator { - public static final String PLATFORM_EXECUTABLE_EXTENSION = - (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ? - ".exe" : ""; //$NON-NLS-1$ + private SdkToolsLocator mLocator; - public static final String PLATFORM_SCRIPT_EXTENSION = - (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ? - ".bat" : ""; //$NON-NLS-1$ - - public static final String FN_HPROF_CONV = "hprof-conv" + PLATFORM_EXECUTABLE_EXTENSION; //$NON-NLS-1$ - public static final String FN_TRACEVIEW = "traceview" + PLATFORM_SCRIPT_EXTENSION; //$NON-NLS-1$ + public ToolsLocator() { + mLocator = new SdkToolsLocator(MonitorPlugin.getDefault().getSdkPath()); + } @Override public String getAdbLocation() { - return getSdkPlatformToolsFolder() + SdkConstants.FN_ADB; + return mLocator.getAdbLocation(); } @Override public String getTraceViewLocation() { - return getSdkToolsFolder() + FN_TRACEVIEW; + return mLocator.getTraceViewLocation(); } @Override public String getHprofConvLocation() { - return getSdkToolsFolder() + FN_HPROF_CONV; - } - - private String getSdkToolsFolder() { - return getSdkFolder() + "/tools/"; //$NON-NLS-1$ - } - - private String getSdkPlatformToolsFolder() { - return getSdkFolder() + "/platform-tools/"; //$NON-NLS-1$ - } - - private String getSdkFolder() { - // FIXME! - return MonitorPlugin.getDdmsPreferenceStore().getLastSdkPath(); + return mLocator.getHprofConvLocation(); } } |