aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.monitor
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.monitor')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/.classpath10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/.project28
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/.settings/org.eclipse.jdt.core.prefs98
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/build.properties10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/avd_manager.pngbin0 -> 269 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-128.pngbin0 -> 17692 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-16.pngbin0 -> 854 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-32.pngbin0 -> 2402 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms.icnsbin0 -> 99171 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/images/sdk_manager.pngbin0 -> 219 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/monitor.launch32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/plugin.properties8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/plugin.xml132
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/plugin_customization.ini6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/pom.xml17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/splash.bmpbin0 -> 90998 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/AndroidPreferencePage.java43
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorActionBarAdvisor.java105
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java179
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java65
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorStartup.java87
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchAdvisor.java43
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchWindowAdvisor.java41
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkLocationChooserDialog.java122
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java116
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SwtUtils.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java42
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/AvdManagerAction.java24
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/SdkManagerAction.java79
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/DebugPortProvider.java165
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortConfigDialog.java396
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortEditDialog.java334
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/handlers/StaticPortConfigHandler.java33
34 files changed, 2261 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath b/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath
new file mode 100644
index 000000000..fa341c0e1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry exported="true" kind="lib" path="libs/sdkuilib.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/ddmuilib"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/.project b/eclipse/plugins/com.android.ide.eclipse.monitor/.project
new file mode 100644
index 000000000..e7ca0c942
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>plugin-monitor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/.settings/org.eclipse.jdt.core.prefs b/eclipse/plugins/com.android.ide.eclipse.monitor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..ea661960a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,98 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
+org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..48a3aa366
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: com.android.ide.eclipse.monitor;singleton:=true
+Bundle-Version: 24.3.3.qualifier
+Bundle-Activator: com.android.ide.eclipse.monitor.MonitorPlugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.android.ide.eclipse.ddms,
+ com.android.ide.eclipse.traceview,
+ com.android.ide.eclipse.base
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %Bundle-Vendor
+Bundle-ClassPath: .,
+ libs/sdkuilib.jar
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties b/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties
new file mode 100644
index 000000000..643fe5ef0
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin_customization.ini,\
+ plugin.properties,\
+ images/,\
+ libs/,\
+ splash.bmp
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/avd_manager.png b/eclipse/plugins/com.android.ide.eclipse.monitor/images/avd_manager.png
new file mode 100644
index 000000000..f8a173ca3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/avd_manager.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-128.png b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-128.png
new file mode 100644
index 000000000..392a8f3ab
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-128.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-16.png b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-16.png
new file mode 100644
index 000000000..f77bee200
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-16.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-32.png b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-32.png
new file mode 100644
index 000000000..4fe68167d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms-32.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms.icns b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms.icns
new file mode 100644
index 000000000..eeacbde8d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/ddms.icns
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/images/sdk_manager.png b/eclipse/plugins/com.android.ide.eclipse.monitor/images/sdk_manager.png
new file mode 100644
index 000000000..08ffda85b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/images/sdk_manager.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/monitor.launch b/eclipse/plugins/com.android.ide.eclipse.monitor/monitor.launch
new file mode 100644
index 000000000..f56a37de1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/monitor.launch
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
+<booleanAttribute key="append.args" value="true"/>
+<booleanAttribute key="askclear" value="true"/>
+<booleanAttribute key="automaticAdd" value="true"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="false"/>
+<booleanAttribute key="clearws" value="false"/>
+<booleanAttribute key="clearwslog" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/monitor"/>
+<booleanAttribute key="default" value="false"/>
+<stringAttribute key="deselected_workspace_plugins" value="com.android.ide.eclipse.adt,com.android.ide.eclipse.adt.package,com.android.ide.eclipse.gldebugger.tests,overlay.com.android.ide.eclipse.adt.overlay"/>
+<booleanAttribute key="includeOptional" value="true"/>
+<stringAttribute key="location" value="${workspace_loc}/../runtime-monitor-idea133-ksr2"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -data @noDefault"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="com.android.ide.eclipse.monitor.product"/>
+<stringAttribute key="selected_target_plugins" value="com.android.tools.common@default:default,com.android.tools.ddms.ddmlib@default:default,com.android.tools.ddms.ddmuilib@default:default,com.android.tools.dvlib@default:default,com.android.tools.external.liblzf@default:default,com.android.tools.external.libprotobuf-java-lite@default:default,com.android.tools.hierarchyviewer2lib@default:default,com.android.tools.layoutlib.api@default:default,com.android.tools.sdklib@default:default,com.android.tools.sdkstats@default:default,com.android.tools.sdkuilib@default:default,com.android.tools.swtmenubar@default:default,com.android.tools.traceview@default:default,com.android.tools.uiautomatorviewer@default:default,com.google.guava@default:default,com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,javax.xml@default:default,jfree.chart-swt@default:default,jfree.chart@default:default,jfree.jcommon@default:default,net.sf.kxml.2@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.codec*1.4.0.v201209201156@default:default,org.apache.commons.compress@default:default,org.apache.commons.logging*1.1.1.v201101211721@default:default,org.apache.httpcomponents.httpclient*4.1.3.v201209201135@default:default,org.apache.httpcomponents.httpcore*4.1.4.v201203221030@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.linux.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security@default:default,org.eclipse.equinox.util@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.gtk.linux.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.text@default:default,org.eclipse.ui.console@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.w3c.css.sac@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
+<stringAttribute key="selected_workspace_plugins" value="com.android.ide.eclipse.base@default:default,com.android.ide.eclipse.ddms@default:default,com.android.ide.eclipse.gldebugger@default:default,com.android.ide.eclipse.hierarchyviewer@default:default,com.android.ide.eclipse.monitor@default:default,com.android.ide.eclipse.ndk@default:default,com.android.ide.eclipse.pdt@default:default,com.android.ide.eclipse.tests@default:false,com.android.ide.eclipse.traceview@default:default"/>
+<booleanAttribute key="show_selected_only" value="false"/>
+<stringAttribute key="templateConfig" value="${target_home}/configuration/config.ini"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<booleanAttribute key="useDefaultConfigArea" value="true"/>
+<booleanAttribute key="useProduct" value="true"/>
+</launchConfiguration>
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.properties b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.properties
new file mode 100644
index 000000000..f25aa6e31
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.properties
@@ -0,0 +1,8 @@
+#Properties file for com.android.ide.eclipse.monitor
+#TODO: update with new year date (search this to find other occurrences to update)
+Bundle-Vendor = The Android Open Source Project
+Bundle-Name = Monitor
+aboutText = \n\
+Android Device Monitor\n\
+Version: 24.3.3 \n\
+Copyright 2012, The Android Open Source Project \n\
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.xml
new file mode 100644
index 000000000..32c44d058
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="com.android.ide.eclipse.monitor.Application"
+ point="org.eclipse.core.runtime.applications">
+ <application
+ cardinality="singleton-global"
+ thread="main"
+ visible="true">
+ <run
+ class="com.android.ide.eclipse.monitor.MonitorApplication">
+ </run>
+ </application>
+ </extension>
+ <extension
+ id="com.android.ide.eclipse.monitor.product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="com.android.ide.eclipse.monitor.Application"
+ name="Android Device Monitor">
+ <property
+ name="appName"
+ value="Monitor">
+ </property>
+ <property
+ name="preferenceCustomization"
+ value="plugin_customization.ini">
+ </property>
+ <property
+ name="windowImages"
+ value="images/ddms-16.png,images/ddms-32.png,images/ddms-128.png">
+ </property>
+ <property
+ name="aboutImage"
+ value="images/ddms-128.png">
+ </property>
+ <property
+ name="aboutText"
+ value="%aboutText">
+ </property>
+
+ </product>
+ </extension>
+ <extension
+ point="com.android.ide.eclipse.ddms.toolsLocator">
+ <locator
+ class="com.android.ide.eclipse.monitor.ToolsLocator">
+ </locator>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ defaultHandler="com.android.ide.eclipse.monitor.handlers.StaticPortConfigHandler"
+ id="com.android.monitor.commands.StaticPortConfiguration"
+ name="Static Port Configuration">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="false"
+ locationURI="menu:file?after=additions">
+ <command
+ commandId="com.android.monitor.commands.StaticPortConfiguration"
+ label="Static Port Configuration"
+ style="push"
+ tooltip="Configure static debug ports">
+ </command>
+ </menuContribution>
+ <menuContribution
+ allPopups="false"
+ locationURI="menu:window?after=additions">
+ <command
+ commandId="org.eclipse.ui.views.showView"
+ style="push">
+ </command>
+ </menuContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ class="com.android.ide.eclipse.monitor.AndroidPreferencePage"
+ id="com.android.ide.eclipse.preferences.main"
+ name="Android">
+ </page>
+ </extension>
+ <extension
+ point="org.eclipse.ui.startup">
+ <startup
+ class="com.android.ide.eclipse.monitor.MonitorStartup">
+ </startup>
+ </extension>
+ <extension
+ point="org.eclipse.ui.actionSets">
+ <actionSet
+ id="monitor.actionSet.AvdSdkManager"
+ label="Android SDK and AVD Manager"
+ visible="true">
+ <action
+ class="com.android.ide.eclipse.monitor.actions.AvdManagerAction"
+ icon="images/avd_manager.png"
+ id="com.android.ide.eclipse.monitor.avdmanager"
+ label="Android Virtual Device Manager"
+ menubarPath="Window/additions"
+ style="push"
+ toolbarPath="android_project">
+ </action>
+ <action
+ class="com.android.ide.eclipse.monitor.actions.SdkManagerAction"
+ icon="images/sdk_manager.png"
+ id="com.android.ide.eclipse.monitor.sdkmanager"
+ label="Android SDK Manager"
+ menubarPath="Window/additions"
+ style="push"
+ toolbarPath="android_project">
+ </action>
+ </actionSet>
+ </extension>
+ <extension
+ id="product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="com.android.ide.eclipse.monitor.Application"
+ name="monitor">
+ <property
+ name="appName"
+ value="monitor">
+ </property>
+ </product>
+ </extension>
+</plugin>
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/plugin_customization.ini b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin_customization.ini
new file mode 100644
index 000000000..fa9d8a2b3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/plugin_customization.ini
@@ -0,0 +1,6 @@
+org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight
+org.eclipse.ui/SHOW_TEXT_ON_PERSPECTIVE_BAR=true
+org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=com.android.ide.eclipse.ddms.Perspective,com.android.ide.eclipse.hierarchyviewer.TreeViewPerspective
+org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=true
+org.eclipse.ui/SHOW_MEMORY_MONITOR=true
+org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = false
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/pom.xml b/eclipse/plugins/com.android.ide.eclipse.monitor/pom.xml
new file mode 100644
index 000000000..425057feb
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <version>24.3.3-SNAPSHOT</version>
+ <artifactId>com.android.ide.eclipse.monitor</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <name>monitor</name>
+
+ <parent>
+ <relativePath>../../pom.xml</relativePath>
+ <groupId>adt.group</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+</project>
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/splash.bmp b/eclipse/plugins/com.android.ide.eclipse.monitor/splash.bmp
new file mode 100644
index 000000000..54880bf35
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/splash.bmp
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/AndroidPreferencePage.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/AndroidPreferencePage.java
new file mode 100644
index 000000000..b85f0163d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/AndroidPreferencePage.java
@@ -0,0 +1,43 @@
+/*
+ * 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.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class AndroidPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+ public AndroidPreferencePage() {
+ super(""); //$NON-NLS-1$
+ setPreferenceStore(MonitorPlugin.getDefault().getPreferenceStore());
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ // TODO: This page is empty currently. It is only used as the top level
+ // to which DDMS & logcat attach their preference pages.
+ // ADT's root page contains the path to the Android SDK, and we should recreate
+ // that here once we figure out how to share this across plugins.
+ return null;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorActionBarAdvisor.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorActionBarAdvisor.java
new file mode 100644
index 000000000..e31e45ebe
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorActionBarAdvisor.java
@@ -0,0 +1,105 @@
+/*
+ * 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.jface.action.GroupMarker;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
+import org.eclipse.ui.internal.WorkbenchImages;
+
+public class MonitorActionBarAdvisor extends ActionBarAdvisor {
+ private IWorkbenchAction mQuitAction;
+ private IWorkbenchAction mCopyAction;
+ private IWorkbenchAction mSelectAllAction;
+ private IWorkbenchAction mFindAction;
+ private IWorkbenchAction mOpenPerspectiveAction;
+ private IWorkbenchAction mResetPerspectiveAction;
+ private IWorkbenchAction mPreferencesAction;
+ private IWorkbenchAction mAboutAction;
+
+ public MonitorActionBarAdvisor(IActionBarConfigurer configurer) {
+ super(configurer);
+ }
+
+ @Override
+ protected void makeActions(IWorkbenchWindow window) {
+ mQuitAction = ActionFactory.QUIT.create(window);
+ register(mQuitAction);
+
+ mCopyAction = ActionFactory.COPY.create(window);
+ register(mCopyAction);
+
+ mSelectAllAction = ActionFactory.SELECT_ALL.create(window);
+ register(mSelectAllAction);
+
+ mFindAction = ActionFactory.FIND.create(window);
+ mFindAction.setText("Find..."); // replace the default "Find and Replace..."
+ register(mFindAction);
+
+ mOpenPerspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create(window);
+ register(mOpenPerspectiveAction);
+
+ mResetPerspectiveAction = ActionFactory.RESET_PERSPECTIVE.create(window);
+ register(mResetPerspectiveAction);
+
+ mPreferencesAction = ActionFactory.PREFERENCES.create(window);
+ register(mPreferencesAction);
+
+ mAboutAction = ActionFactory.ABOUT.create(window);
+ register(mAboutAction);
+ }
+
+ @Override
+ protected void fillMenuBar(IMenuManager menuBar) {
+ MenuManager fileMenu = new MenuManager("&File", IWorkbenchActionConstants.M_FILE);
+ MenuManager editMenu = new MenuManager("&Edit", IWorkbenchActionConstants.M_EDIT);
+ MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP);
+ MenuManager windowMenu = new MenuManager("&Window", IWorkbenchActionConstants.M_WINDOW);
+
+ menuBar.add(fileMenu);
+ menuBar.add(editMenu);
+ menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ menuBar.add(windowMenu);
+ menuBar.add(helpMenu);
+
+ // contents of File menu
+ fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ fileMenu.add(mQuitAction);
+
+ // contents of Edit menu
+ editMenu.add(mCopyAction);
+ editMenu.add(mSelectAllAction);
+ editMenu.add(mFindAction);
+
+ // contents of Window menu
+ windowMenu.add(mOpenPerspectiveAction);
+ windowMenu.add(mResetPerspectiveAction);
+ windowMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ windowMenu.add(mPreferencesAction);
+
+ // contents of Help menu
+ helpMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ helpMenu.add(mAboutAction);
+ };
+}
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
new file mode 100644
index 000000000..425786f6f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2011 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 com.android.prefs.AndroidLocation;
+import com.android.sdklib.SdkManager;
+import com.android.sdkstats.SdkStatsService;
+import com.android.sdkuilib.internal.repository.ui.AdtUpdateDialog;
+import com.android.utils.ILogger;
+import com.android.utils.NullLogger;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.jface.dialogs.MessageDialog;
+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";
+ private static final String MONITOR_WORKSPACE_PATH = "monitor-workspace";
+
+ @Override
+ public Object start(IApplicationContext context) throws Exception {
+ Display display = PlatformUI.createDisplay();
+
+ // set workspace location
+ Location instanceLoc = Platform.getInstanceLocation();
+ IPath workspacePath = new Path(AndroidLocation.getFolder()).append(MONITOR_WORKSPACE_PATH);
+ instanceLoc.set(workspacePath.toFile().toURI().toURL(), true);
+
+ // figure out path to SDK
+ String sdkPath = findSdkPath(display);
+ if (!isValidSdkLocation(sdkPath)) {
+ // exit with return code -1
+ return Integer.valueOf(-1);
+ }
+ MonitorPlugin.getDefault().setSdkFolder(new File(sdkPath));
+
+ // install platform tools if necessary
+ ILogger sdkLog = NullLogger.getLogger();
+ SdkManager manager = SdkManager.createManager(sdkPath, sdkLog);
+ if (manager.getPlatformToolsVersion() == null) {
+ boolean install = MessageDialog.openQuestion(new Shell(display),
+ "Monitor",
+ "The platform tools package that provides adb is missing from your SDK installation. "
+ + "Monitor requires this package to work properly. Would you like to install that package now?");
+ if (!install) {
+ return Integer.valueOf(-1);
+ }
+ AdtUpdateDialog window = new AdtUpdateDialog(new Shell(display), sdkLog, sdkPath);
+ window.installPlatformTools();
+ }
+
+ // If this is the first time using ddms or adt, open up the stats service
+ // opt out dialog, and request user for permissions.
+ // Note that the actual ping is performed in MonitorStartup
+ SdkStatsService stats = new SdkStatsService();
+ stats.checkUserPermissionForPing(new Shell(display));
+
+ // open up RCP
+ try {
+ int returnCode = PlatformUI.createAndRunWorkbench(display,
+ new MonitorWorkbenchAdvisor());
+ if (returnCode == PlatformUI.RETURN_RESTART) {
+ return IApplication.EXIT_RESTART;
+ }
+ return IApplication.EXIT_OK;
+ } finally {
+ display.dispose();
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (!PlatformUI.isWorkbenchRunning())
+ return;
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ final Display display = workbench.getDisplay();
+ display.syncExec(new Runnable() {
+ @Override
+ public void run() {
+ if (!display.isDisposed())
+ workbench.close();
+ }
+ });
+ }
+
+ 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;
+ }
+
+ // The monitor app should be located in "<sdk>/tools/lib/monitor-platform/"
+ // 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) {
+ File libFolder = new File(install.getURL().getFile()).getParentFile();
+ if (libFolder != null) {
+ String toolsFolder = libFolder.getParent();
+ if (toolsFolder != null) {
+ sdkLocation = new File(toolsFolder).getParent();
+ if (isValidSdkLocation(sdkLocation)) {
+ MonitorPlugin.getDdmsPreferenceStore().setLastSdkPath(sdkLocation);
+ return sdkLocation;
+ }
+ }
+
+ }
+ }
+
+ // check for the last used SDK
+ sdkLocation = MonitorPlugin.getDdmsPreferenceStore().getLastSdkPath();
+ if (isValidSdkLocation(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(new File(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
new file mode 100644
index 000000000..a61eb4ab8
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorPlugin.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 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.sdkstats.DdmsPreferenceStore;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import java.io.File;
+
+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 File mSdkFolder;
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+
+ sPlugin = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ sPlugin = null;
+ super.stop(context);
+ }
+
+ public static MonitorPlugin getDefault() {
+ return sPlugin;
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+ public static DdmsPreferenceStore getDdmsPreferenceStore() {
+ return sDdmsPreferenceStore;
+ }
+
+ public void setSdkFolder(File sdkFolder) {
+ mSdkFolder = sdkFolder;
+ }
+
+ public File getSdkFolder() {
+ return mSdkFolder;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorStartup.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorStartup.java
new file mode 100644
index 000000000..2de260ee6
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorStartup.java
@@ -0,0 +1,87 @@
+/*
+ * 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.SdkConstants;
+import com.android.sdkstats.SdkStatsService;
+
+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.ui.IStartup;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Properties;
+
+public class MonitorStartup implements IStartup {
+ @Override
+ public void earlyStartup() {
+ Job pingJob = new Job("Android SDK Ping") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ SdkStatsService stats = new SdkStatsService();
+ File sdkFolder = MonitorPlugin.getDefault().getSdkFolder();
+ if (sdkFolder == null) {
+ return Status.OK_STATUS;
+ }
+
+ String toolsPath = new File(sdkFolder, SdkConstants.FD_TOOLS).getAbsolutePath();
+ ping(stats, toolsPath);
+ return Status.OK_STATUS;
+ }
+ };
+ pingJob.setPriority(Job.DECORATE); // lowest priority
+ pingJob.schedule();
+ }
+
+ private static void ping(SdkStatsService stats, String toolsLocation) {
+ Properties p = new Properties();
+ try{
+ File sourceProp;
+ if (toolsLocation != null && toolsLocation.length() > 0) {
+ sourceProp = new File(toolsLocation, "source.properties"); //$NON-NLS-1$
+ } else {
+ sourceProp = new File("source.properties"); //$NON-NLS-1$
+ }
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(sourceProp);
+ p.load(fis);
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
+ String revision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
+ if (revision != null && revision.length() > 0) {
+ stats.ping("ddms", revision); //$NON-NLS-1$
+ }
+ } catch (FileNotFoundException e) {
+ // couldn't find the file? don't ping.
+ } catch (IOException e) {
+ // couldn't find the file? don't ping.
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchAdvisor.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchAdvisor.java
new file mode 100644
index 000000000..c79803f4d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchAdvisor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.Perspective;
+
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class MonitorWorkbenchAdvisor extends WorkbenchAdvisor {
+ @Override
+ public String getInitialWindowPerspectiveId() {
+ return Perspective.ID;
+ }
+
+ @Override
+ public void initialize(IWorkbenchConfigurer configurer) {
+ super.initialize(configurer);
+ configurer.setSaveAndRestore(true);
+ }
+
+ @Override
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+ IWorkbenchWindowConfigurer configurer) {
+ return new MonitorWorkbenchWindowAdvisor(configurer);
+ };
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchWindowAdvisor.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchWindowAdvisor.java
new file mode 100644
index 000000000..137d3b184
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorWorkbenchWindowAdvisor.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class MonitorWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
+ public MonitorWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
+ super(configurer);
+ }
+
+ @Override
+ public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
+ return new MonitorActionBarAdvisor(configurer);
+ };
+
+ @Override
+ public void preWindowOpen() {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ configurer.setShowStatusLine(true);
+ configurer.setShowPerspectiveBar(true);
+ configurer.setTitle("Android Device Monitor");
+ }
+}
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 000000000..04f60c796
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkLocationChooserDialog.java
@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+import java.io.File;
+
+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(new File(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 000000000..bd8ef60cb
--- /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.SdkConstants;
+import com.android.ide.eclipse.ddms.IToolsLocator;
+
+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 File mSdkFolder;
+
+ public SdkToolsLocator(File sdkFolder) {
+ mSdkFolder = sdkFolder;
+ }
+
+ public String getAdbLocation() {
+ return new File(getSdkPlatformToolsFolder(), SdkConstants.FN_ADB).getAbsolutePath();
+ }
+
+ public String getTraceViewLocation() {
+ return new File(getSdkToolsFolder(), FN_TRACEVIEW).getAbsolutePath();
+ }
+
+ public String getHprofConvLocation() {
+ return new File(getSdkPlatformToolsFolder(), FN_HPROF_CONV).getAbsolutePath();
+ }
+
+ private String getSdkToolsFolder() {
+ return new File(mSdkFolder, SdkConstants.FD_TOOLS).getAbsolutePath();
+ }
+
+ private String getSdkPlatformToolsFolder() {
+ return new File(mSdkFolder, SdkConstants.FD_PLATFORM_TOOLS).getAbsolutePath();
+ }
+
+ public SdkInstallStatus isValidInstallation() {
+ List<String> executables = Arrays.asList(
+ 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 000000000..bae7f0b32
--- /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
new file mode 100644
index 000000000..75971817c
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ToolsLocator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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;
+
+public class ToolsLocator implements IToolsLocator {
+ private SdkToolsLocator mLocator;
+
+ public ToolsLocator() {
+ mLocator = new SdkToolsLocator(MonitorPlugin.getDefault().getSdkFolder());
+ }
+
+ @Override
+ public String getAdbLocation() {
+ return mLocator.getAdbLocation();
+ }
+
+ @Override
+ public String getTraceViewLocation() {
+ return mLocator.getTraceViewLocation();
+ }
+
+ @Override
+ public String getHprofConvLocation() {
+ return mLocator.getHprofConvLocation();
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/AvdManagerAction.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/AvdManagerAction.java
new file mode 100644
index 000000000..2510bd34a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/AvdManagerAction.java
@@ -0,0 +1,24 @@
+/*
+ * 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.actions;
+
+public class AvdManagerAction extends SdkManagerAction {
+ @Override
+ protected String getAndroidBatArgument() {
+ return "avd";
+ }
+} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/SdkManagerAction.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/SdkManagerAction.java
new file mode 100644
index 000000000..573ed7c07
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/actions/SdkManagerAction.java
@@ -0,0 +1,79 @@
+/*
+ * 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.actions;
+
+import com.android.SdkConstants;
+import com.android.ide.eclipse.monitor.MonitorPlugin;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.PlatformUI;
+
+import java.io.File;
+import java.io.IOException;
+
+public class SdkManagerAction implements IWorkbenchWindowActionDelegate {
+ @Override
+ public void run(IAction action) {
+ File sdk = MonitorPlugin.getDefault().getSdkFolder();
+ if (sdk != null) {
+ File tools = new File(sdk, SdkConstants.FD_TOOLS);
+ File androidBat = new File(tools, SdkConstants.androidCmdName());
+ if (androidBat.exists()) {
+ String[] cmd = new String[] {
+ androidBat.getAbsolutePath(),
+ getAndroidBatArgument(),
+ };
+ try {
+ Runtime.getRuntime().exec(cmd);
+ } catch (IOException e) {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ ErrorDialog.openError(
+ window.getShell(),
+ "Monitor",
+ "Error while launching SDK Manager",
+ new Status(Status.ERROR,
+ MonitorPlugin.PLUGIN_ID,
+ "Error while launching SDK Manager",
+ e));
+ }
+ }
+ }
+ }
+ }
+
+ protected String getAndroidBatArgument() {
+ return "sdk";
+ }
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void init(IWorkbenchWindow window) {
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/DebugPortProvider.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/DebugPortProvider.java
new file mode 100644
index 000000000..a2ffa042b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/DebugPortProvider.java
@@ -0,0 +1,165 @@
+/*
+ * 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.ddms;
+
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+import com.android.ddmlib.IDevice;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * DDMS implementation of the IDebugPortProvider interface.
+ * This class handles saving/loading the list of static debug port from
+ * the preference store and provides the port number to the Device Monitor.
+ */
+public class DebugPortProvider implements IDebugPortProvider {
+
+ private static DebugPortProvider sThis = new DebugPortProvider();
+
+ /** Preference name for the static port list. */
+ public static final String PREFS_STATIC_PORT_LIST = "android.staticPortList"; //$NON-NLS-1$
+
+ /**
+ * Mapping device serial numbers to maps. The embedded maps are mapping application names to
+ * debugger ports.
+ */
+ private Map<String, Map<String, Integer>> mMap;
+
+ public static DebugPortProvider getInstance() {
+ return sThis;
+ }
+
+ private DebugPortProvider() {
+ computePortList();
+ }
+
+ /**
+ * Returns a static debug port for the specified application running on the
+ * specified {@link IDevice}.
+ * @param device The device the application is running on.
+ * @param appName The application name, as defined in the
+ * AndroidManifest.xml package attribute.
+ * @return The static debug port or {@link #NO_STATIC_PORT} if there is none setup.
+ *
+ * @see IDebugPortProvider#getPort(IDevice, String)
+ */
+ @Override
+ public int getPort(IDevice device, String appName) {
+ if (mMap != null) {
+ Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber());
+ if (deviceMap != null) {
+ Integer i = deviceMap.get(appName);
+ if (i != null) {
+ return i.intValue();
+ }
+ }
+ }
+ return IDebugPortProvider.NO_STATIC_PORT;
+ }
+
+ /**
+ * Returns the map of Static debugger ports. The map links device serial numbers to
+ * a map linking application name to debugger ports.
+ */
+ public Map<String, Map<String, Integer>> getPortList() {
+ return mMap;
+ }
+
+ /**
+ * Create the map member from the values contained in the Preference Store.
+ */
+ private void computePortList() {
+ mMap = new HashMap<String, Map<String, Integer>>();
+
+ // get the prefs store
+ IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+ String value = store.getString(PREFS_STATIC_PORT_LIST);
+
+ if (value != null && value.length() > 0) {
+ // format is
+ // port1|port2|port3|...
+ // where port# is
+ // appPackageName:appPortNumber:device-serial-number
+ String[] portSegments = value.split("\\|"); //$NON-NLS-1$
+ for (String seg : portSegments) {
+ String[] entry = seg.split(":"); //$NON-NLS-1$
+
+ // backward compatibility support. if we have only 2 entry, we default
+ // to the first emulator.
+ String deviceName = null;
+ if (entry.length == 3) {
+ deviceName = entry[2];
+ } else {
+ deviceName = IDevice.FIRST_EMULATOR_SN;
+ }
+
+ // get the device map
+ Map<String, Integer> deviceMap = mMap.get(deviceName);
+ if (deviceMap == null) {
+ deviceMap = new HashMap<String, Integer>();
+ mMap.put(deviceName, deviceMap);
+ }
+
+ deviceMap.put(entry[0], Integer.valueOf(entry[1]));
+ }
+ }
+ }
+
+ /**
+ * Sets new [device, app, port] values.
+ * The values are also sync'ed in the preference store.
+ * @param map The map containing the new values.
+ */
+ public void setPortList(Map<String, Map<String,Integer>> map) {
+ // update the member map.
+ mMap.clear();
+ mMap.putAll(map);
+
+ // create the value to store in the preference store.
+ // see format definition in getPortList
+ StringBuilder sb = new StringBuilder();
+
+ Set<String> deviceKeys = map.keySet();
+ for (String deviceKey : deviceKeys) {
+ Map<String, Integer> deviceMap = map.get(deviceKey);
+ if (deviceMap != null) {
+ Set<String> appKeys = deviceMap.keySet();
+
+ for (String appKey : appKeys) {
+ Integer port = deviceMap.get(appKey);
+ if (port != null) {
+ sb.append(appKey).append(':').append(port.intValue()).append(':').
+ append(deviceKey).append('|');
+ }
+ }
+ }
+ }
+
+ String value = sb.toString();
+
+ // get the prefs store.
+ IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+
+ // and give it the new value.
+ store.setValue(PREFS_STATIC_PORT_LIST, value);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortConfigDialog.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortConfigDialog.java
new file mode 100644
index 000000000..456cdcf51
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortConfigDialog.java
@@ -0,0 +1,396 @@
+/*
+ * 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.ddms;
+
+import com.android.ddmuilib.TableHelper;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+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.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Dialog to configure the static debug ports.
+ *
+ */
+public class StaticPortConfigDialog extends Dialog {
+
+ /** Preference name for the 0th column width */
+ private static final String PREFS_DEVICE_COL = "spcd.deviceColumn"; //$NON-NLS-1$
+
+ /** Preference name for the 1st column width */
+ private static final String PREFS_APP_COL = "spcd.AppColumn"; //$NON-NLS-1$
+
+ /** Preference name for the 2nd column width */
+ private static final String PREFS_PORT_COL = "spcd.PortColumn"; //$NON-NLS-1$
+
+ private static final int COL_DEVICE = 0;
+ private static final int COL_APPLICATION = 1;
+ private static final int COL_PORT = 2;
+
+
+ private static final int DLG_WIDTH = 500;
+ private static final int DLG_HEIGHT = 300;
+
+ private Shell mShell;
+ private Shell mParent;
+
+ private Table mPortTable;
+
+ /**
+ * Array containing the list of already used static port to avoid
+ * duplication.
+ */
+ private ArrayList<Integer> mPorts = new ArrayList<Integer>();
+
+ /**
+ * Basic constructor.
+ * @param parent
+ */
+ public StaticPortConfigDialog(Shell parent) {
+ super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+ }
+
+ /**
+ * Open and display the dialog. This method returns only when the
+ * user closes the dialog somehow.
+ *
+ */
+ public void open() {
+ createUI();
+
+ if (mParent == null || mShell == null) {
+ return;
+ }
+
+ updateFromStore();
+
+ // Set the dialog size.
+ mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+ Rectangle r = mParent.getBounds();
+ // get the center new top left.
+ int cx = r.x + r.width/2;
+ int x = cx - DLG_WIDTH / 2;
+ int cy = r.y + r.height/2;
+ int y = cy - DLG_HEIGHT / 2;
+ mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+ mShell.pack();
+
+ // actually open the dialog
+ mShell.open();
+
+ // event loop until the dialog is closed.
+ Display display = mParent.getDisplay();
+ while (!mShell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+ /**
+ * Creates the dialog ui.
+ */
+ private void createUI() {
+ mParent = getParent();
+ mShell = new Shell(mParent, getStyle());
+ mShell.setText("Static Port Configuration");
+
+ mShell.setLayout(new GridLayout(1, true));
+
+ mShell.addListener(SWT.Close, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ event.doit = true;
+ }
+ });
+
+ // center part with the list on the left and the buttons
+ // on the right.
+ Composite main = new Composite(mShell, SWT.NONE);
+ main.setLayoutData(new GridData(GridData.FILL_BOTH));
+ main.setLayout(new GridLayout(2, false));
+
+ // left part: list view
+ mPortTable = new Table(main, SWT.SINGLE | SWT.FULL_SELECTION);
+ mPortTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mPortTable.setHeaderVisible(true);
+ mPortTable.setLinesVisible(true);
+
+ TableHelper.createTableColumn(mPortTable, "Device Serial Number",
+ SWT.LEFT, "emulator-5554", //$NON-NLS-1$
+ PREFS_DEVICE_COL, DdmsPlugin.getDefault().getPreferenceStore());
+
+ TableHelper.createTableColumn(mPortTable, "Application Package",
+ SWT.LEFT, "com.android.samples.phone", //$NON-NLS-1$
+ PREFS_APP_COL, DdmsPlugin.getDefault().getPreferenceStore());
+
+ TableHelper.createTableColumn(mPortTable, "Debug Port",
+ SWT.RIGHT, "Debug Port", //$NON-NLS-1$
+ PREFS_PORT_COL, DdmsPlugin.getDefault().getPreferenceStore());
+
+ // right part: buttons
+ Composite buttons = new Composite(main, SWT.NONE);
+ buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ buttons.setLayout(new GridLayout(1, true));
+
+ Button newButton = new Button(buttons, SWT.NONE);
+ newButton.setText("New...");
+ newButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
+ mPorts);
+ if (dlg.open()) {
+ // get the text
+ String device = dlg.getDeviceSN();
+ String app = dlg.getAppName();
+ int port = dlg.getPortNumber();
+
+ // add it to the list
+ addEntry(device, app, port);
+ }
+ }
+ });
+
+ final Button editButton = new Button(buttons, SWT.NONE);
+ editButton.setText("Edit...");
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int index = mPortTable.getSelectionIndex();
+ String oldDeviceName = getDeviceName(index);
+ String oldAppName = getAppName(index);
+ String oldPortNumber = getPortNumber(index);
+ StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
+ mPorts, oldDeviceName, oldAppName, oldPortNumber);
+ if (dlg.open()) {
+ // get the text
+ String deviceName = dlg.getDeviceSN();
+ String app = dlg.getAppName();
+ int port = dlg.getPortNumber();
+
+ // add it to the list
+ replaceEntry(index, deviceName, app, port);
+ }
+ }
+ });
+
+ final Button deleteButton = new Button(buttons, SWT.NONE);
+ deleteButton.setText("Delete");
+ deleteButton.setEnabled(false);
+ deleteButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int index = mPortTable.getSelectionIndex();
+ removeEntry(index);
+ }
+ });
+
+ // bottom part with the ok/cancel
+ Composite bottomComp = new Composite(mShell, SWT.NONE);
+ bottomComp.setLayoutData(new GridData(
+ GridData.HORIZONTAL_ALIGN_CENTER));
+ bottomComp.setLayout(new GridLayout(2, true));
+
+ Button okButton = new Button(bottomComp, SWT.NONE);
+ okButton.setText("OK");
+ okButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateStore();
+ mShell.close();
+ }
+ });
+
+ Button cancelButton = new Button(bottomComp, SWT.NONE);
+ cancelButton.setText("Cancel");
+ cancelButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ mShell.close();
+ }
+ });
+
+ mPortTable.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // get the selection index
+ int index = mPortTable.getSelectionIndex();
+
+ boolean enabled = index != -1;
+ editButton.setEnabled(enabled);
+ deleteButton.setEnabled(enabled);
+ }
+ });
+
+ mShell.pack();
+
+ }
+
+ /**
+ * Add a new entry in the list.
+ * @param deviceName the serial number of the device
+ * @param appName java package for the application
+ * @param portNumber port number
+ */
+ private void addEntry(String deviceName, String appName, int portNumber) {
+ // create a new item for the table
+ TableItem item = new TableItem(mPortTable, SWT.NONE);
+
+ item.setText(COL_DEVICE, deviceName);
+ item.setText(COL_APPLICATION, appName);
+ item.setText(COL_PORT, Integer.toString(portNumber));
+
+ // add the port to the list of port number used.
+ mPorts.add(portNumber);
+ }
+
+ /**
+ * Remove an entry from the list.
+ * @param index The index of the entry to be removed
+ */
+ private void removeEntry(int index) {
+ // remove from the ui
+ mPortTable.remove(index);
+
+ // and from the port list.
+ mPorts.remove(index);
+ }
+
+ /**
+ * Replace an entry in the list with new values.
+ * @param index The index of the item to be replaced
+ * @param deviceName the serial number of the device
+ * @param appName The new java package for the application
+ * @param portNumber The new port number.
+ */
+ private void replaceEntry(int index, String deviceName, String appName, int portNumber) {
+ // get the table item by index
+ TableItem item = mPortTable.getItem(index);
+
+ // set its new value
+ item.setText(COL_DEVICE, deviceName);
+ item.setText(COL_APPLICATION, appName);
+ item.setText(COL_PORT, Integer.toString(portNumber));
+
+ // and replace the port number in the port list.
+ mPorts.set(index, portNumber);
+ }
+
+
+ /**
+ * Returns the device name for a specific index
+ * @param index The index
+ * @return the java package name of the application
+ */
+ private String getDeviceName(int index) {
+ TableItem item = mPortTable.getItem(index);
+ return item.getText(COL_DEVICE);
+ }
+
+ /**
+ * Returns the application name for a specific index
+ * @param index The index
+ * @return the java package name of the application
+ */
+ private String getAppName(int index) {
+ TableItem item = mPortTable.getItem(index);
+ return item.getText(COL_APPLICATION);
+ }
+
+ /**
+ * Returns the port number for a specific index
+ * @param index The index
+ * @return the port number
+ */
+ private String getPortNumber(int index) {
+ TableItem item = mPortTable.getItem(index);
+ return item.getText(COL_PORT);
+ }
+
+ /**
+ * Updates the ui from the value in the preference store.
+ */
+ private void updateFromStore() {
+ // get the map from the debug port manager
+ DebugPortProvider provider = DebugPortProvider.getInstance();
+ Map<String, Map<String, Integer>> map = provider.getPortList();
+
+ // we're going to loop on the keys and fill the table.
+ Set<String> deviceKeys = map.keySet();
+
+ for (String deviceKey : deviceKeys) {
+ Map<String, Integer> deviceMap = map.get(deviceKey);
+ if (deviceMap != null) {
+ Set<String> appKeys = deviceMap.keySet();
+
+ for (String appKey : appKeys) {
+ Integer port = deviceMap.get(appKey);
+ if (port != null) {
+ addEntry(deviceKey, appKey, port);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Update the store from the content of the ui.
+ */
+ private void updateStore() {
+ // create a new Map object and fill it.
+ HashMap<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
+
+ int count = mPortTable.getItemCount();
+
+ for (int i = 0 ; i < count ; i++) {
+ TableItem item = mPortTable.getItem(i);
+ String deviceName = item.getText(COL_DEVICE);
+
+ Map<String, Integer> deviceMap = map.get(deviceName);
+ if (deviceMap == null) {
+ deviceMap = new HashMap<String, Integer>();
+ map.put(deviceName, deviceMap);
+ }
+
+ deviceMap.put(item.getText(COL_APPLICATION), Integer.valueOf(item.getText(COL_PORT)));
+ }
+
+ // set it in the store through the debug port manager.
+ DebugPortProvider provider = DebugPortProvider.getInstance();
+ provider.setPortList(map);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortEditDialog.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortEditDialog.java
new file mode 100644
index 000000000..a9b0cd45e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/ddms/StaticPortEditDialog.java
@@ -0,0 +1,334 @@
+/*
+ * 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.ddms;
+
+import com.android.ddmlib.IDevice;
+
+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.graphics.Rectangle;
+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.Dialog;
+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.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.ArrayList;
+
+/**
+ * Small dialog box to edit a static port number.
+ */
+public class StaticPortEditDialog extends Dialog {
+
+ private static final int DLG_WIDTH = 400;
+ private static final int DLG_HEIGHT = 200;
+
+ private Shell mParent;
+
+ private Shell mShell;
+
+ private boolean mOk = false;
+
+ private String mAppName;
+
+ private String mPortNumber;
+
+ private Button mOkButton;
+
+ private Label mWarning;
+
+ /** List of ports already in use */
+ private ArrayList<Integer> mPorts;
+
+ /** This is the port being edited. */
+ private int mEditPort = -1;
+ private String mDeviceSn;
+
+ /**
+ * Creates a dialog with empty fields.
+ * @param parent The parent Shell
+ * @param ports The list of already used port numbers.
+ */
+ public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
+ super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+ mPorts = ports;
+ mDeviceSn = IDevice.FIRST_EMULATOR_SN;
+ }
+
+ /**
+ * Creates a dialog with predefined values.
+ * @param shell The parent shell
+ * @param ports The list of already used port numbers.
+ * @param oldDeviceSN the device serial number to display
+ * @param oldAppName The application name to display
+ * @param oldPortNumber The port number to display
+ */
+ public StaticPortEditDialog(Shell shell, ArrayList<Integer> ports,
+ String oldDeviceSN, String oldAppName, String oldPortNumber) {
+ this(shell, ports);
+
+ mDeviceSn = oldDeviceSN;
+ mAppName = oldAppName;
+ mPortNumber = oldPortNumber;
+ mEditPort = Integer.valueOf(mPortNumber);
+ }
+
+ /**
+ * Opens the dialog. The method will return when the user closes the dialog
+ * somehow.
+ *
+ * @return true if ok was pressed, false if cancelled.
+ */
+ public boolean open() {
+ createUI();
+
+ if (mParent == null || mShell == null) {
+ return false;
+ }
+
+ mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+ Rectangle r = mParent.getBounds();
+ // get the center new top left.
+ int cx = r.x + r.width/2;
+ int x = cx - DLG_WIDTH / 2;
+ int cy = r.y + r.height/2;
+ int y = cy - DLG_HEIGHT / 2;
+ mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+ mShell.open();
+
+ Display display = mParent.getDisplay();
+ while (!mShell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+
+ return mOk;
+ }
+
+ public String getDeviceSN() {
+ return mDeviceSn;
+ }
+
+ public String getAppName() {
+ return mAppName;
+ }
+
+ public int getPortNumber() {
+ return Integer.valueOf(mPortNumber);
+ }
+
+ private void createUI() {
+ mParent = getParent();
+ mShell = new Shell(mParent, getStyle());
+ mShell.setText("Static Port");
+
+ mShell.setLayout(new GridLayout(1, false));
+
+ mShell.addListener(SWT.Close, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ }
+ });
+
+ // center part with the edit field
+ Composite main = new Composite(mShell, SWT.NONE);
+ main.setLayoutData(new GridData(GridData.FILL_BOTH));
+ main.setLayout(new GridLayout(2, false));
+
+ Label l0 = new Label(main, SWT.NONE);
+ l0.setText("Device Name:");
+
+ final Text deviceSNText = new Text(main, SWT.SINGLE | SWT.BORDER);
+ deviceSNText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ if (mDeviceSn != null) {
+ deviceSNText.setText(mDeviceSn);
+ }
+ deviceSNText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ mDeviceSn = deviceSNText.getText().trim();
+ validate();
+ }
+ });
+
+ Label l = new Label(main, SWT.NONE);
+ l.setText("Application Name:");
+
+ final Text appNameText = new Text(main, SWT.SINGLE | SWT.BORDER);
+ if (mAppName != null) {
+ appNameText.setText(mAppName);
+ }
+ appNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ appNameText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ mAppName = appNameText.getText().trim();
+ validate();
+ }
+ });
+
+ Label l2 = new Label(main, SWT.NONE);
+ l2.setText("Debug Port:");
+
+ final Text debugPortText = new Text(main, SWT.SINGLE | SWT.BORDER);
+ if (mPortNumber != null) {
+ debugPortText.setText(mPortNumber);
+ }
+ debugPortText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ debugPortText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ mPortNumber = debugPortText.getText().trim();
+ validate();
+ }
+ });
+
+ // warning label
+ Composite warningComp = new Composite(mShell, SWT.NONE);
+ warningComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ warningComp.setLayout(new GridLayout(1, true));
+
+ mWarning = new Label(warningComp, SWT.NONE);
+ mWarning.setText("");
+ mWarning.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // bottom part with the ok/cancel
+ Composite bottomComp = new Composite(mShell, SWT.NONE);
+ bottomComp
+ .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+ bottomComp.setLayout(new GridLayout(2, true));
+
+ mOkButton = new Button(bottomComp, SWT.NONE);
+ mOkButton.setText("OK");
+ mOkButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ mOk = true;
+ mShell.close();
+ }
+ });
+ mOkButton.setEnabled(false);
+ mShell.setDefaultButton(mOkButton);
+
+ Button cancelButton = new Button(bottomComp, SWT.NONE);
+ cancelButton.setText("Cancel");
+ cancelButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ mShell.close();
+ }
+ });
+
+ validate();
+ }
+
+ /**
+ * Validates the content of the 2 text fields and enable/disable "ok", while
+ * setting up the warning/error message.
+ */
+ private void validate() {
+ // first we reset the warning dialog. This allows us to latter
+ // display warnings.
+ mWarning.setText(""); //$NON-NLS-1$
+
+ // check the device name field is not empty
+ if (mDeviceSn == null || mDeviceSn.length() == 0) {
+ mWarning.setText("Device name missing.");
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // check the application name field is not empty
+ if (mAppName == null || mAppName.length() == 0) {
+ mWarning.setText("Application name missing.");
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ String packageError = "Application name must be a valid Java package name.";
+
+ // validate the package name as well. It must be a fully qualified
+ // java package.
+ String[] packageSegments = mAppName.split("\\."); //$NON-NLS-1$
+ for (String p : packageSegments) {
+ if (p.matches("^[a-zA-Z][a-zA-Z0-9]*") == false) { //$NON-NLS-1$
+ mWarning.setText(packageError);
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // lets also display a warning if the package contains upper case
+ // letters.
+ if (p.matches("^[a-z][a-z0-9]*") == false) { //$NON-NLS-1$
+ mWarning.setText("Lower case is recommended for Java packages.");
+ }
+ }
+
+ // the split will not detect the last char being a '.'
+ // so we test it manually
+ if (mAppName.charAt(mAppName.length()-1) == '.') {
+ mWarning.setText(packageError);
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // now we test the package name field is not empty.
+ if (mPortNumber == null || mPortNumber.length() == 0) {
+ mWarning.setText("Port Number missing.");
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // then we check it only contains digits.
+ if (mPortNumber.matches("[0-9]*") == false) { //$NON-NLS-1$
+ mWarning.setText("Port Number invalid.");
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // get the int from the port number to validate
+ long port = Long.valueOf(mPortNumber);
+ if (port >= 32767) {
+ mOkButton.setEnabled(false);
+ return;
+ }
+
+ // check if its in the list of already used ports
+ if (port != mEditPort) {
+ for (Integer i : mPorts) {
+ if (port == i.intValue()) {
+ mWarning.setText("Port already in use.");
+ mOkButton.setEnabled(false);
+ return;
+ }
+ }
+ }
+
+ // at this point there's not error, so we enable the ok button.
+ mOkButton.setEnabled(true);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/handlers/StaticPortConfigHandler.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/handlers/StaticPortConfigHandler.java
new file mode 100644
index 000000000..ff63aca2f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/handlers/StaticPortConfigHandler.java
@@ -0,0 +1,33 @@
+/*
+ * 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.handlers;
+
+import com.android.ide.eclipse.monitor.ddms.StaticPortConfigDialog;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class StaticPortConfigHandler extends AbstractHandler {
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ StaticPortConfigDialog dlg = new StaticPortConfigDialog(HandlerUtil.getActiveShell(event));
+ dlg.open();
+ return null;
+ }
+}