aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse')
-rw-r--r--eclipse/features/com.android.ide.eclipse.adt/feature.xml7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java14
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java226
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java135
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java11
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java156
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java68
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java65
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java338
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java38
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java54
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java14
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java49
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java56
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java9
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java39
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java18
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java (renamed from eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class1.java)0
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java (renamed from eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class2.java)0
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java27
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml24
-rwxr-xr-xeclipse/scripts/create_test_symlinks.sh34
71 files changed, 1175 insertions, 542 deletions
diff --git a/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/eclipse/features/com.android.ide.eclipse.adt/feature.xml
index 191b76d..676a89e 100644
--- a/eclipse/features/com.android.ide.eclipse.adt/feature.xml
+++ b/eclipse/features/com.android.ide.eclipse.adt/feature.xml
@@ -40,6 +40,13 @@
<import plugin="org.eclipse.ui"/>
<import plugin="org.eclipse.ui.ide"/>
<import plugin="org.eclipse.ui.forms"/>
+ <import plugin="org.eclipse.gef"/>
+ <import plugin="org.eclipse.ui.browser"/>
+ <import plugin="org.eclipse.ui.views"/>
+ <import plugin="org.eclipse.wst.sse.core"/>
+ <import plugin="org.eclipse.wst.sse.ui"/>
+ <import plugin="org.eclipse.wst.xml.core"/>
+ <import plugin="org.eclipse.wst.xml.ui"/>
</requires>
<plugin
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
index 61b3f4d..7304e5e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.adt;
+import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
/**
@@ -42,8 +43,8 @@ public class AdtConstants {
/** Marker for Android Target errors.
* This is not cleared on each like other markers. Instead, it's cleared
- * when a ContainerClasspathInitialized has succeeded in creating an
- * {@link AndroidClasspathContainer}*/
+ * when an {@link AndroidClasspathContainerInitializer} has succeeded in creating an
+ * AndroidClasspathContainer */
public final static String MARKER_TARGET = AdtPlugin.PLUGIN_ID + ".targetProblem"; //$NON-NLS-1$
/** Build verbosity "Always". Those messages are always displayed. */
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
index d9c18cf..62bc7ed 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
@@ -1201,7 +1201,7 @@ public class AdtPlugin extends AbstractUIPlugin {
if (file.getFullPath().segmentCount() == 4) {
// check if we are inside the res folder.
String segment = file.getFullPath().segment(1);
- if (segment.equalsIgnoreCase(AndroidConstants.FD_RESOURCES)) {
+ if (segment.equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
// we are inside a res/ folder, get the actual ResourceFolder
ProjectResources resources = ResourceManager.getInstance().
getProjectResources(file.getProject());
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
index 4d16120..e38419a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
@@ -31,6 +31,7 @@ import com.android.jarutils.DebugKeyProvider.KeytoolException;
import com.android.jarutils.SignedJarBuilder.IZipEntryFilter;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -120,6 +121,10 @@ public class ApkBuilder extends BaseBuilder {
}
}
+ /**
+ * {@inheritDoc}
+ * @throws CoreException
+ */
public boolean visit(IResourceDelta delta) throws CoreException {
// no need to keep looking if we already know we need to convert
// to dex and make the final package.
@@ -589,7 +594,7 @@ public class ApkBuilder extends BaseBuilder {
* @param osBinPath the path to the output folder of the project
* @param osOutFilePath the path of the dex file to create.
* @param referencedJavaProjects the list of referenced projects for this project.
- * @return
+ *
* @throws CoreException
*/
private boolean executeDx(IJavaProject javaProject, String osBinPath, String osOutFilePath,
@@ -756,8 +761,7 @@ public class ApkBuilder extends BaseBuilder {
// now write the native libraries.
// First look if the lib folder is there.
- IResource libFolder = javaProject.getProject().findMember(
- AndroidConstants.FD_NATIVE_LIBS);
+ IResource libFolder = javaProject.getProject().findMember(SdkConstants.FD_NATIVE_LIBS);
if (libFolder != null && libFolder.exists() &&
libFolder.getType() == IResource.FOLDER) {
// look inside and put .so in lib/* by keeping the relative folder path.
@@ -829,7 +833,7 @@ public class ApkBuilder extends BaseBuilder {
* lib folder directly goes in this "lib" folder in the archive.
*
*
- * @param rooSegmentCount The number of segment of the path of the folder containing the
+ * @param rootSegmentCount The number of segment of the path of the folder containing the
* libraries. This is used to compute the path in the archive.
* @param jarBuilder the {@link SignedJarBuilder} used to create the archive.
* @param resource the IResource to write.
@@ -847,7 +851,7 @@ public class ApkBuilder extends BaseBuilder {
path = path.removeFirstSegments(rootSegmentCount);
// add it to the archive.
- IPath apkPath = new Path(AndroidConstants.FD_APK_NATIVE_LIBS);
+ IPath apkPath = new Path(SdkConstants.FD_APK_NATIVE_LIBS);
apkPath = apkPath.append(path);
// writes the file in the apk.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java
index 47ef626..aec703d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java
@@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.build;
import com.android.ide.eclipse.adt.build.BaseBuilder.BaseDeltaVisitor;
import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -98,17 +99,17 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor
mOutputPath = outputfolder.getFullPath();
}
- IResource assetFolder = builder.getProject().findMember(AndroidConstants.FD_ASSETS);
+ IResource assetFolder = builder.getProject().findMember(SdkConstants.FD_ASSETS);
if (assetFolder != null) {
mAssetPath = assetFolder.getFullPath();
}
- IResource resFolder = builder.getProject().findMember(AndroidConstants.FD_RESOURCES);
+ IResource resFolder = builder.getProject().findMember(SdkConstants.FD_RESOURCES);
if (resFolder != null) {
mResPath = resFolder.getFullPath();
}
- IResource libFolder = builder.getProject().findMember(AndroidConstants.FD_NATIVE_LIBS);
+ IResource libFolder = builder.getProject().findMember(SdkConstants.FD_NATIVE_LIBS);
if (libFolder != null) {
mLibFolder = libFolder.getFullPath();
}
@@ -126,8 +127,9 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor
return mMakeFinalPackage;
}
- /*
- * (non-Javadoc)
+ /**
+ * {@inheritDoc}
+ * @throws CoreException
*
* @see org.eclipse.core.resources.IResourceDeltaVisitor
* #visit(org.eclipse.core.resources.IResourceDelta)
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java
index f94bdc7..534c123 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java
@@ -69,15 +69,15 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
/**
* First line of dual line aapt error.<br>
* "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
- * " (Occured while parsing &lt;path&gt;)"
+ * " (Occurred while parsing &lt;path&gt;)"
*/
private final static Pattern sPattern1Line1 = Pattern.compile(
"^ERROR\\s+at\\s+line\\s+(\\d+):\\s+(.*)$"); //$NON-NLS-1$
/**
* Second line of dual line aapt error.<br>
* "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
- * " (Occured while parsing &lt;path&gt;)"<br>
- * @see sPattern1Line1
+ * " (Occurred while parsing &lt;path&gt;)"<br>
+ * @see #sPattern1Line1
*/
private final static Pattern sPattern1Line2 = Pattern.compile(
"^\\s+\\(Occurred while parsing\\s+(.*)\\)$"); //$NON-NLS-1$
@@ -92,7 +92,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
* Second line of dual line aapt error.<br>
* "ERROR: &lt;error&gt;"<br>
* "Defined at file &lt;path&gt; line &lt;line&gt;"<br>
- * @see sPattern2Line1
+ * @see #sPattern2Line1
*/
private final static Pattern sPattern2Line2 = Pattern.compile(
"Defined\\s+at\\s+file\\s+(.+)\\s+line\\s+(\\d+)"); //$NON-NLS-1$
@@ -113,7 +113,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
* Second line of dual line aapt error.<br>
* "ERROR parsing XML file &lt;path&gt;"<br>
* "&lt;error&gt; at line &lt;line&gt;"<br>
- * @see sPattern4Line1
+ * @see #sPattern4Line1
*/
private final static Pattern sPattern4Line2 = Pattern.compile(
"^(.+)\\s+at\\s+line\\s+(\\d+)$"); //$NON-NLS-1$
@@ -263,7 +263,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
/**
* Adds a marker to the current project.
- * @param file the file to be marked
+ *
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
* @param severity the severity of the marker.
@@ -292,12 +292,11 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
/**
* Removes markers from a container and its children.
- * @param container The container from which to delete the markers.
+ * @param folder The container from which to delete the markers.
* @param markerId The id of the markers to remove. If null, all marker of
* type <code>IMarker.PROBLEM</code> will be removed.
*/
- protected final void removeMarkersFromContainer(IContainer folder,
- String markerId) {
+ protected final void removeMarkersFromContainer(IContainer folder, String markerId) {
try {
if (folder.exists()) {
folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
index 1a4aa8c..9fc4348 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
@@ -1128,10 +1128,8 @@ public class PreCompilerBuilder extends BaseBuilder {
* Finish a file created/modified by an outside command line process.
* The file is marked as modified by Android, and the parent folder is refreshed, so that,
* in case the file didn't exist beforehand, the file appears in the package explorer.
- * @param file The file to "finish".
- * @param parent The parent container. Can be null (in which case it'll be
- * figured out from the file's IResource.
- * @param monitor a monitor to display progress.
+ * @param rFile The R file to "finish".
+ * @param manifestFile The manifest file to "finish".
* @throws CoreException
*/
private void finishJavaFilesAfterExternalModification(IFile rFile, IFile manifestFile)
@@ -1150,9 +1148,7 @@ public class PreCompilerBuilder extends BaseBuilder {
* The file is marked as modified by Android, and the parent folder is refreshed, so that,
* in case the file didn't exist beforehand, the file appears in the package explorer.
* @param file The file to "finish".
- * @param parent The parent container. Can be null (in which case it'll be
- * figured out from the file's IResource.
- * @param monitor a monitor to display progress.
+ * @param aidlFile The AIDL file to "finish".
* @throws CoreException
*/
private void finishFileAfterExternalModification(IFile file, IFile aidlFile)
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java
index 33d5fa6..f4778d7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java
@@ -23,6 +23,7 @@ import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -154,7 +155,7 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
// then we are not yet in a source or resource folder
mInRes = mInSrc = false;
- if (AndroidConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) {
+ if (SdkConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) {
// this is the resource folder that was modified. we want to
// see its content.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java
index 48ec7c3..2b7d01d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java
@@ -31,8 +31,12 @@ import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.debug.launching.DeviceChooserDialog.DeviceChooserResponse;
import com.android.ide.eclipse.adt.debug.ui.EmulatorConfigTab;
import com.android.ide.eclipse.adt.project.ProjectHelper;
+import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
-import com.android.sdklib.SdkConstants;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkManager;
+import com.android.sdklib.vm.VmManager;
+import com.android.sdklib.vm.VmManager.VmInfo;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -58,6 +62,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -69,9 +74,9 @@ import java.util.regex.Pattern;
public final class AndroidLaunchController implements IDebugBridgeChangeListener,
IDeviceChangeListener, IClientChangeListener {
+ private static final String FLAG_VM = "-vm"; //$NON-NLS-1$
private static final String FLAG_NETDELAY = "-netdelay"; //$NON-NLS-1$
private static final String FLAG_NETSPEED = "-netspeed"; //$NON-NLS-1$
- private static final String FLAG_SKIN = "-skin"; //$NON-NLS-1$
private static final String FLAG_WIPE_DATA = "-wipe-data"; //$NON-NLS-1$
private static final String FLAG_NO_BOOT_ANIM = "-no-boot-anim"; //$NON-NLS-1$
@@ -223,11 +228,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
public boolean mNoBootAnim = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM;
/**
- * Screen size parameters.
- * This value can be provided to the emulator directly for the option "-skin"
+ * Vm Name.
*/
- public String mSkin = null;
-
+ public String mVmName = null;
+
public String mNetworkSpeed = EmulatorConfigTab.getSpeed(
LaunchConfigDelegate.DEFAULT_SPEED);
public String mNetworkDelay = EmulatorConfigTab.getDelay(
@@ -258,12 +262,8 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
}
try {
- mSkin = config.getAttribute(LaunchConfigDelegate.ATTR_SKIN, mSkin);
- if (mSkin == null) {
- mSkin = SdkConstants.SKIN_DEFAULT;
- }
+ mVmName = config.getAttribute(LaunchConfigDelegate.ATTR_VM_NAME, mVmName);
} catch (CoreException e) {
- mSkin = SdkConstants.SKIN_DEFAULT;
}
int index = LaunchConfigDelegate.DEFAULT_SPEED;
@@ -526,11 +526,14 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
// set the launch mode to default.
wc.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION);
-
+
// set default target mode
wc.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
LaunchConfigDelegate.DEFAULT_TARGET_MODE);
+ // default VM: None
+ wc.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, (String)null);
+
// set the default network speed
wc.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
LaunchConfigDelegate.DEFAULT_SPEED);
@@ -539,9 +542,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
wc.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
LaunchConfigDelegate.DEFAULT_DELAY);
- // default skin
- wc.setAttribute(LaunchConfigDelegate.ATTR_SKIN, SdkConstants.SKIN_DEFAULT);
-
// default wipe data mode
wc.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
LaunchConfigDelegate.DEFAULT_WIPE_DATA);
@@ -627,32 +627,171 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
// set the debug mode
launchInfo.mDebugMode = mode.equals(ILaunchManager.DEBUG_MODE);
- // device chooser response.
+ // get the SDK
+ Sdk currentSdk = Sdk.getCurrent();
+ VmManager vmManager = currentSdk.getVmManager();
+
+ // get the project target
+ final IAndroidTarget projectTarget = currentSdk.getTarget(project);
+
+ // FIXME: check errors on missing sdk, vm manager, or project target.
+
+ // device chooser response object.
final DeviceChooserResponse response = new DeviceChooserResponse();
+ /*
+ * Launch logic:
+ * - Manually Mode
+ * Always display a UI that lets a user see the current running emulators/devices.
+ * The UI must show which devices are compatibles, and allow launching new emulators
+ * with compatible (and not yet running) VM.
+ * - Automatic Way
+ * * Preferred VM set.
+ * If Preferred VM is not running: launch it.
+ * Launch the application on the preferred VM.
+ * * No preferred VM.
+ * Count the number of compatible emulators/devices.
+ * If != 1, display a UI similar to manual mode.
+ * If == 1, launch the application on this VM/device.
+ */
+
if (config.mTargetMode == AndroidLaunchConfiguration.AUTO_TARGET_MODE) {
// if we are in automatic target mode, we need to find the current devices
Device[] devices = AndroidDebugBridge.getBridge().getDevices();
- // depending on the number of devices, we'll simulate an automatic choice
- // from the device chooser or simply show up the device chooser.
- if (devices.length == 0) {
- // if zero devices, we launch the device.
- AdtPlugin.printToConsole(project, "Automatic Target Mode: launching new emulator.");
+ // first check if we have a preferred VM name, and if it actually exists, and is valid
+ // (ie able to run the project).
+ // We need to check this in case the VM was recreated with a different target that is
+ // not compatible.
+ VmInfo preferredVm = null;
+ if (config.mVmName != null) {
+ preferredVm = vmManager.getVm(config.mVmName);
+ if (projectTarget.isCompatibleBaseFor(preferredVm.getTarget()) == false) {
+ preferredVm = null;
+
+ AdtPlugin.printErrorToConsole(project, String.format(
+ "Preferred VM '%1$s' is not compatible with the project target '%2$s'. Looking for a compatible VM...",
+ config.mVmName, projectTarget.getName()));
+ }
+ }
+
+ if (preferredVm != null) {
+ // look for a matching device
+ for (Device d : devices) {
+ String deviceVm = d.getVmName();
+ if (deviceVm != null && deviceVm.equals(config.mVmName)) {
+ response.mustContinue = true;
+ response.mustLaunchEmulator = false;
+ response.deviceToUse = d;
+
+ AdtPlugin.printToConsole(project, String.format(
+ "Automatic Target Mode: Preferred VM '%1$s' is available on emulator '%2$s'",
+ config.mVmName, d));
+
+ continueLaunch(response, project, launch, launchInfo, config);
+ return;
+ }
+ }
+
+ // at this point we have a valid preferred VM that is not running.
+ // We need to start it.
response.mustContinue = true;
response.mustLaunchEmulator = true;
+ response.vmToLaunch = preferredVm;
+
+ AdtPlugin.printToConsole(project, String.format(
+ "Automatic Target Mode: Preferred VM '%1$s' is not available. Launching new emulator.",
+ config.mVmName));
+
continueLaunch(response, project, launch, launchInfo, config);
return;
- } else if (devices.length == 1) {
+ }
+
+ // no (valid) preferred VM? look for one.
+ HashMap<Device, VmInfo> compatibleRunningVms = new HashMap<Device, VmInfo>();
+ boolean hasDevice = false; // if there's 1+ device running, we may force manual mode,
+ // as we cannot always detect proper compatibility with
+ // devices. This is the case if the project target is not
+ // a standard platform
+ for (Device d : devices) {
+ String deviceVm = d.getVmName();
+ if (deviceVm != null) { // physical devices return null.
+ VmInfo info = vmManager.getVm(deviceVm);
+ if (info != null && projectTarget.isCompatibleBaseFor(info.getTarget())) {
+ compatibleRunningVms.put(d, info);
+ }
+ } else {
+ if (projectTarget.isPlatform()) { // means this can run on any device as long
+ // as api level is high enough
+ String apiString = d.getProperty(SdkManager.PROP_VERSION_SDK);
+ try {
+ int apiNumber = Integer.parseInt(apiString);
+ if (apiNumber >= projectTarget.getApiVersionNumber()) {
+ // device is compatible with project
+ compatibleRunningVms.put(d, null);
+ continue;
+ }
+ } catch (NumberFormatException e) {
+ // do nothing, we'll consider it a non compatible device below.
+ }
+ }
+ hasDevice = true;
+ }
+ }
+
+ // depending on the number of devices, we'll simulate an automatic choice
+ // from the device chooser or simply show up the device chooser.
+ if (hasDevice == false && compatibleRunningVms.size() == 0) {
+ // if zero emulators/devices, we launch an emulator.
+ // We need to figure out which VM first.
+
+ // we are going to take the closest VM. ie a compatible VM that has the API level
+ // closest to the project target.
+ VmInfo[] vms = vmManager.getVms();
+ VmInfo defaultVm = null;
+ for (VmInfo vm : vms) {
+ if (projectTarget.isCompatibleBaseFor(vm.getTarget())) {
+ if (defaultVm == null ||
+ vm.getTarget().getApiVersionNumber() <
+ defaultVm.getTarget().getApiVersionNumber()) {
+ defaultVm = vm;
+ }
+ }
+ }
+
+ if (defaultVm != null) {
+ response.mustContinue = true;
+ response.mustLaunchEmulator = true;
+ response.vmToLaunch = defaultVm;
+
+ AdtPlugin.printToConsole(project, String.format(
+ "Automatic Target Mode: launching new emulator with compatible VM '%1$s'",
+ defaultVm.getName()));
+
+ continueLaunch(response, project, launch, launchInfo, config);
+ return;
+ } else {
+ // FIXME: ask the user if he wants to create a VM.
+ // we found no compatible VM.
+ AdtPlugin.printErrorToConsole(project, String.format(
+ "Failed to find a VM compatible with target '%1$s'. Launch aborted.",
+ projectTarget.getName()));
+ launch.stopLaunch();
+ return;
+ }
+ } else if (hasDevice == false && compatibleRunningVms.size() == 1) {
+ Entry<Device, VmInfo> e = compatibleRunningVms.entrySet().iterator().next();
response.mustContinue = true;
response.mustLaunchEmulator = false;
- response.deviceToUse = devices[0];
+ response.deviceToUse = e.getKey();
- if (response.deviceToUse.isEmulator()) {
- message = String.format("Automatic Target Mode: using existing emulator: %1$s",
- response.deviceToUse);
+ // get the VmInfo, if null, the device is a physical device.
+ VmInfo vmInfo = e.getValue();
+ if (vmInfo != null) {
+ message = String.format("Automatic Target Mode: using existing emulator '%1$s' running compatible VM '%2$s'",
+ response.deviceToUse, e.getValue().getName());
} else {
- message = String.format("Automatic Target Mode: using existing device: %1$s",
+ message = String.format("Automatic Target Mode: using device '%1$s'",
response.deviceToUse);
}
AdtPlugin.printToConsole(project, message);
@@ -662,8 +801,13 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
}
// if more than one device, we'll bring up the DeviceChooser dialog below.
- AdtPlugin.printToConsole(project,
- "Automatic Target Mode: user selection for 2+ devices.");
+ if (compatibleRunningVms.size() >= 2) {
+ message = "Automatic Target Mode: Several compatible targets. Please select a target device.";
+ } else if (hasDevice) {
+ message = "Automatic Target Mode: Unable to detect device compatibility. Please select a target device.";
+ }
+
+ AdtPlugin.printToConsole(project, message);
}
// bring up the device chooser.
@@ -671,7 +815,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
public void run() {
DeviceChooserDialog dialog = new DeviceChooserDialog(
AdtPlugin.getDisplay().getActiveShell());
- dialog.open(response, project, launch, launchInfo, config);
+ dialog.open(response, project, projectTarget, launch, launchInfo, config);
}
});
@@ -705,7 +849,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
synchronized (sListLock) {
mWaitingForEmulatorLaunches.add(launchInfo);
AdtPlugin.printToConsole(project, "Launching a new emulator.");
- boolean status = launchEmulator(config);
+ boolean status = launchEmulator(config, response.vmToLaunch);
if (status == false) {
// launching the emulator failed!
@@ -775,9 +919,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* the device requires it and it is not set in the manifest, the launch will be forced to
* "release" mode instead of "debug"</li>
* <ul>
- * @param launchInfo
- * @param device
- * @return
*/
private boolean checkBuildInfo(DelayedLaunchInfo launchInfo, Device device) {
if (device != null) {
@@ -1122,7 +1263,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
/**
* launches an application on a device or emulator
*
- * @param classToLaunch the fully-qualified name of the activity to launch
+ * @param info the {@link DelayedLaunchInfo} that indicates the activity to launch
* @param device the device or emulator to launch the application on
*/
private void launchApp(final DelayedLaunchInfo info, Device device) {
@@ -1182,7 +1323,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
}
}
- private boolean launchEmulator(AndroidLaunchConfiguration config) {
+ private boolean launchEmulator(AndroidLaunchConfiguration config, VmInfo vmToLaunch) {
// split the custom command line in segments
ArrayList<String> customArgs = new ArrayList<String>();
@@ -1212,10 +1353,8 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
ArrayList<String> list = new ArrayList<String>();
list.add(AdtPlugin.getOsAbsoluteEmulator());
- if (config.mSkin != null) {
- list.add(FLAG_SKIN);
- list.add(config.mSkin);
- }
+ list.add(FLAG_VM);
+ list.add(vmToLaunch.getName());
if (config.mNetworkSpeed != null) {
list.add(FLAG_NETSPEED);
@@ -1329,7 +1468,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* @param debugPort The port to connect the debugger to
* @param androidLaunch The associated AndroidLaunch object.
* @param monitor A Progress monitor
- * @see connectRemoveDebugger()
+ * @see #connectRemoteDebugger(int, AndroidLaunch, IProgressMonitor)
*/
public static void launchRemoteDebugger( final int debugPort, final AndroidLaunch androidLaunch,
final IProgressMonitor monitor) {
@@ -1352,7 +1491,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* This is sent from a non UI thread.
* @param bridge the new {@link AndroidDebugBridge} object.
*
- * @see IDebugBridgeChangeListener#serverChanged(AndroidDebugBridge)
+ * @see IDebugBridgeChangeListener#bridgeChanged(AndroidDebugBridge)
*/
public void bridgeChanged(AndroidDebugBridge bridge) {
// The adb server has changed. We cancel any pending launches.
@@ -1447,7 +1586,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* @param device the device that was updated.
* @param changeMask the mask indicating what changed.
*
- * @see IDeviceChangeListener#deviceChanged(Device)
+ * @see IDeviceChangeListener#deviceChanged(Device, int)
*/
public void deviceChanged(Device device, int changeMask) {
// We could check if any starting device we care about is now ready, but we can wait for
@@ -1622,7 +1761,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
* Get the stderr/stdout outputs of a process and return when the process is done.
* Both <b>must</b> be read or the process will block on windows.
* @param process The process to get the ouput from
- * @throws InterruptedException
*/
private void grabEmulatorOutput(final Process process) {
// read the lines as they come. if null is returned, it's
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java
index 2cb11c3..19ec9a7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java
@@ -19,6 +19,7 @@ package com.android.ide.eclipse.adt.debug.launching;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Client;
import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
import com.android.ddmlib.Device.DeviceState;
import com.android.ddmuilib.IImageLoader;
@@ -27,7 +28,10 @@ import com.android.ddmuilib.TableHelper;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController.AndroidLaunchConfiguration;
import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController.DelayedLaunchInfo;
+import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.vm.VmManager.VmInfo;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.preference.IPreferenceStore;
@@ -67,19 +71,26 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
private final static String PREFS_COL_SERIAL = "deviceChooser.serial"; //$NON-NLS-1$
private final static String PREFS_COL_STATE = "deviceChooser.state"; //$NON-NLS-1$
- private final static String PREFS_COL_BUILD = "deviceChooser.build"; //$NON-NLS-1$
+ private final static String PREFS_COL_VM = "deviceChooser.vm"; //$NON-NLS-1$
+ private final static String PREFS_COL_TARGET = "deviceChooser.target"; //$NON-NLS-1$
+ private final static String PREFS_COL_DEBUG = "deviceChooser.debug"; //$NON-NLS-1$
private Table mDeviceTable;
private TableViewer mViewer;
private Image mDeviceImage;
private Image mEmulatorImage;
+ private Image mMatchImage;
+ private Image mNoMatchImage;
+ private Image mWarningImage;
private Button mOkButton;
private Button mCreateButton;
private DeviceChooserResponse mResponse;
private DelayedLaunchInfo mLaunchInfo;
+ private IAndroidTarget mProjectTarget;
+ private Sdk mSdk;
/**
* Basic Content Provider for a table full of {@link Device} objects. The input is
@@ -111,13 +122,44 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
private class LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
- if (columnIndex == 0 && element instanceof Device) {
- if (((Device)element).isEmulator()) {
- return mEmulatorImage;
+ if (element instanceof Device) {
+ Device device = (Device)element;
+ switch (columnIndex) {
+ case 0:
+ return device.isEmulator() ? mEmulatorImage : mDeviceImage;
+
+ case 2:
+ // check for compatibility.
+ if (device.isEmulator() == false) { // physical device
+ // get the api level of the device
+ try {
+ String apiValue = device.getProperty(
+ IDevice.PROP_BUILD_VERSION_NUMBER);
+ int api = Integer.parseInt(apiValue);
+ if (api >= mProjectTarget.getApiVersionNumber()) {
+ // if the project is compiling against an add-on, the optional
+ // API may be missing from the device.
+ return mProjectTarget.isPlatform() ?
+ mMatchImage : mWarningImage;
+ } else {
+ return mNoMatchImage;
+ }
+ } catch (NumberFormatException e) {
+ // lets consider the device non compatible
+ return mNoMatchImage;
+ }
+ } else {
+ // get the VmInfo
+ VmInfo info = mSdk.getVmManager().getVm(device.getVmName());
+ if (info == null) {
+ return mWarningImage;
+ }
+ return mProjectTarget.isCompatibleBaseFor(info.getTarget()) ?
+ mMatchImage : mNoMatchImage;
+ }
}
-
- return mDeviceImage;
}
+
return null;
}
@@ -128,15 +170,30 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
case 0:
return device.getSerialNumber();
case 1:
- return getStateString(device);
+ if (device.isEmulator()) {
+ return device.getVmName();
+ } else {
+ return "N/A"; // devices don't have VM names.
+ }
case 2:
- String debuggable = device.getProperty(Device.PROP_DEBUGGABLE);
- String version = device.getProperty(Device.PROP_BUILD_VERSION);
+ if (device.isEmulator()) {
+ VmInfo info = mSdk.getVmManager().getVm(device.getVmName());
+ if (info == null) {
+ return "?";
+ }
+ return info.getTarget().getFullName();
+ } else {
+ return device.getProperty(IDevice.PROP_BUILD_VERSION);
+ }
+ case 3:
+ String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE);
if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
- return String.format("%1$s (debug)", version); //$NON-NLS-1$
+ return "Yes";
} else {
- return String.format("%1$s", version); //$NON-NLS-1$
+ return "";
}
+ case 4:
+ return getStateString(device);
}
}
@@ -164,6 +221,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
public static class DeviceChooserResponse {
public boolean mustContinue;
public boolean mustLaunchEmulator;
+ public VmInfo vmToLaunch;
public Device deviceToUse;
}
@@ -175,14 +233,18 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
* Prepare and display the dialog.
* @param response
* @param project
+ * @param projectTarget
* @param launch
* @param launchInfo
* @param config
*/
public void open(DeviceChooserResponse response, IProject project,
- AndroidLaunch launch, DelayedLaunchInfo launchInfo, AndroidLaunchConfiguration config) {
+ IAndroidTarget projectTarget, AndroidLaunch launch, DelayedLaunchInfo launchInfo,
+ AndroidLaunchConfiguration config) {
mResponse = response;
+ mProjectTarget = projectTarget;
mLaunchInfo = launchInfo;
+ mSdk = Sdk.getCurrent();
Shell parent = getParent();
Shell shell = new Shell(parent, getStyle());
@@ -218,6 +280,9 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
mEmulatorImage.dispose();
mDeviceImage.dispose();
+ mMatchImage.dispose();
+ mNoMatchImage.dispose();
+ mWarningImage.dispose();
AndroidLaunchController.getInstance().continueLaunch(response, project, launch,
launchInfo, config);
@@ -249,14 +314,22 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
SWT.LEFT, "AAA+AAAAAAAAAAAAAAAAAAA", //$NON-NLS-1$
PREFS_COL_SERIAL, store);
+ TableHelper.createTableColumn(mDeviceTable, "VM Name",
+ SWT.LEFT, "engineering", //$NON-NLS-1$
+ PREFS_COL_VM, store);
+
+ TableHelper.createTableColumn(mDeviceTable, "Target",
+ SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$
+ PREFS_COL_TARGET, store);
+
+ TableHelper.createTableColumn(mDeviceTable, "Debug",
+ SWT.LEFT, "Debug", //$NON-NLS-1$
+ PREFS_COL_DEBUG, store);
+
TableHelper.createTableColumn(mDeviceTable, "State",
SWT.LEFT, "bootloader", //$NON-NLS-1$
PREFS_COL_STATE, store);
- TableHelper.createTableColumn(mDeviceTable, "Build Info",
- SWT.LEFT, "engineering", //$NON-NLS-1$
- PREFS_COL_BUILD, store);
-
// create the viewer for it
mViewer = new TableViewer(mDeviceTable);
mViewer.setContentProvider(new ContentProvider());
@@ -357,20 +430,42 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
}
private void loadImages() {
- IImageLoader loader = DdmsPlugin.getImageLoader();
+ IImageLoader ddmsLoader = DdmsPlugin.getImageLoader();
Display display = DdmsPlugin.getDisplay();
+ IImageLoader adtLoader = AdtPlugin.getImageLoader();
if (mDeviceImage == null) {
- mDeviceImage = ImageHelper.loadImage(loader, display,
+ mDeviceImage = ImageHelper.loadImage(ddmsLoader, display,
"device.png", //$NON-NLS-1$
ICON_WIDTH, ICON_WIDTH,
display.getSystemColor(SWT.COLOR_RED));
}
if (mEmulatorImage == null) {
- mEmulatorImage = ImageHelper.loadImage(loader, display,
+ mEmulatorImage = ImageHelper.loadImage(ddmsLoader, display,
"emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
display.getSystemColor(SWT.COLOR_BLUE));
}
+
+ if (mMatchImage == null) {
+ mMatchImage = ImageHelper.loadImage(adtLoader, display,
+ "match.png", //$NON-NLS-1$
+ ICON_WIDTH, ICON_WIDTH,
+ display.getSystemColor(SWT.COLOR_GREEN));
+ }
+
+ if (mNoMatchImage == null) {
+ mNoMatchImage = ImageHelper.loadImage(adtLoader, display,
+ "error.png", //$NON-NLS-1$
+ ICON_WIDTH, ICON_WIDTH,
+ display.getSystemColor(SWT.COLOR_RED));
+ }
+
+ if (mWarningImage == null) {
+ mWarningImage = ImageHelper.loadImage(adtLoader, display,
+ "warning.png", //$NON-NLS-1$
+ ICON_WIDTH, ICON_WIDTH,
+ display.getSystemColor(SWT.COLOR_YELLOW));
+ }
}
@@ -438,7 +533,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
* @param device the device that was updated.
* @param changeMask the mask indicating what changed.
*
- * @see IDeviceChangeListener#deviceChanged(Device)
+ * @see IDeviceChangeListener#deviceChanged(Device, int)
*/
public void deviceChanged(final Device device, int changeMask) {
if ((changeMask & (Device.CHANGE_STATE | Device.CHANGE_BUILD_INFO)) != 0) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java
index 5d3e349..68deec3 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java
@@ -80,9 +80,8 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
*/
public static final String ATTR_ACTIVITY = AdtPlugin.PLUGIN_ID + ".activity"; //$NON-NLS-1$
- /** Skin to be used to launch the emulator */
- public static final String ATTR_SKIN = AdtPlugin.PLUGIN_ID + ".skin"; //$NON-NLS-1$
-
+ public static final String ATTR_VM_NAME = AdtPlugin.PLUGIN_ID + ".vm"; //$NON-NLS-1$
+
public static final String ATTR_SPEED = AdtPlugin.PLUGIN_ID + ".speed"; //$NON-NLS-1$
/**
@@ -317,6 +316,10 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
1 /* code, unused */, "Can't find the project!", null /* exception */));
}
+ /**
+ * {@inheritDoc}
+ * @throws CoreException
+ */
@Override
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
throws CoreException {
@@ -406,8 +409,6 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
/**
* Returns the name of the activity.
- * @param configuration
- * @return
*/
private String getActivityName(ILaunchConfiguration configuration) {
String empty = "";
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java
index c7b340c..f4f5281 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java
@@ -22,7 +22,9 @@ import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
+import com.android.sdklib.vm.VmManager;
+import com.android.sdklib.vm.VmManager.VmInfo;
+import com.android.sdkuilib.VmSelector;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
@@ -70,6 +72,11 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
{ "UMTS", "umts" }, //$NON-NLS-2$
};
+ private Button mAutoTargetButton;
+ private Button mManualTargetButton;
+
+ private VmSelector mPreferredVmSelector;
+
private Combo mSpeedCombo;
private Combo mDelayCombo;
@@ -78,18 +85,10 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
private Text mEmulatorCLOptions;
- private Combo mSkinCombo;
-
- private Button mAutoTargetButton;
-
- private Button mManualTargetButton;
-
private Button mWipeDataButton;
private Button mNoBootAnimButton;
- private IAndroidTarget mTarget;
-
/**
* Returns the emulator ready speed option value.
* @param value The index of the combo selection.
@@ -147,6 +146,11 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
targetModeGroup.setLayout(layout);
targetModeGroup.setFont(font);
+ mManualTargetButton = new Button(targetModeGroup, SWT.RADIO);
+ mManualTargetButton.setText("Manual");
+ // Since there are only 2 radio buttons, we can put a listener on only one (they
+ // are both called on select and unselect event.
+
// add the radio button
mAutoTargetButton = new Button(targetModeGroup, SWT.RADIO);
mAutoTargetButton.setText("Automatic");
@@ -159,11 +163,16 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
}
});
- mManualTargetButton = new Button(targetModeGroup, SWT.RADIO);
- mManualTargetButton.setText("Manual");
- // Since there are only 2 radio buttons, we can put a listener on only
- // one (they
- // are both called on select and unselect event.
+ new Label(targetModeGroup, SWT.NONE).setText("Preferred VM");
+ VmInfo[] vms = new VmInfo[0];
+ mPreferredVmSelector = new VmSelector(targetModeGroup, vms,
+ false /*allowMultipleSelection*/);
+ mPreferredVmSelector.setSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
// emulator size
mEmulatorOptionsGroup = new Group(topComp, SWT.NONE);
@@ -174,17 +183,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
mEmulatorOptionsGroup.setLayout(layout);
mEmulatorOptionsGroup.setFont(font);
- new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Screen Size:");
-
- mSkinCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY);
- mSkinCombo.addSelectionListener(new SelectionAdapter() {
- // called when selection changes
- @Override
- public void widgetSelected(SelectionEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
-
// network options
new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Speed:");
@@ -279,8 +277,9 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
*/
public void initializeFrom(ILaunchConfiguration configuration) {
- boolean value = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true ==
- // automatic
+ VmManager vmManager = Sdk.getCurrent().getVmManager();
+
+ boolean value = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == automatic
try {
value = configuration.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, value);
} catch (CoreException e) {
@@ -290,11 +289,12 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
mManualTargetButton.setSelection(!value);
// look for the project name to get its target.
- String projectName = "";
+ String stringValue = "";
try {
- projectName = configuration.getAttribute(
- IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName);
+ stringValue = configuration.getAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, stringValue);
} catch (CoreException ce) {
+ // let's not do anything here, we'll use the default value
}
IProject project = null;
@@ -304,25 +304,41 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
if (projects != null) {
// look for the project whose name we read from the configuration.
for (IJavaProject p : projects) {
- if (p.getElementName().equals(projectName)) {
+ if (p.getElementName().equals(stringValue)) {
project = p.getProject();
break;
}
}
}
- mSkinCombo.removeAll();
+ // update the VM list
+ VmInfo[] vms = null;
+ if (vmManager != null) {
+ vms = vmManager.getVms();
+ }
+
+ IAndroidTarget projectTarget = null;
if (project != null) {
- mTarget = Sdk.getCurrent().getTarget(project);
- if (mTarget != null) {
- String[] skins = mTarget.getSkins();
- if (skins != null) {
- for (String skin : skins) {
- mSkinCombo.add(skin);
- }
- mSkinCombo.pack();
- }
- }
+ projectTarget = Sdk.getCurrent().getTarget(project);
+ } else {
+ vms = null; // no project? we don't want to display any "compatible" VMs.
+ }
+
+ mPreferredVmSelector.setVms(vms, projectTarget);
+
+ stringValue = "";
+ try {
+ stringValue = configuration.getAttribute(LaunchConfigDelegate.ATTR_VM_NAME,
+ stringValue);
+ } catch (CoreException e) {
+ // let's not do anything here, we'll use the default value
+ }
+
+ if (stringValue != null && stringValue.length() > 0 && vmManager != null) {
+ VmInfo targetVm = vmManager.getVm(stringValue);
+ mPreferredVmSelector.setSelection(targetVm);
+ } else {
+ mPreferredVmSelector.setSelection(null);
}
value = LaunchConfigDelegate.DEFAULT_WIPE_DATA;
@@ -342,23 +358,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
mNoBootAnimButton.setSelection(value);
int index = -1;
- try {
- String skin = configuration.getAttribute(LaunchConfigDelegate.ATTR_SKIN, (String)null);
- if (skin == null) {
- skin = SdkConstants.SKIN_DEFAULT;
- }
-
- index = getSkinIndex(skin);
- } catch (CoreException e) {
- index = getSkinIndex(SdkConstants.SKIN_DEFAULT);
- }
-
- if (index == -1) {
- mSkinCombo.select(0);
- updateLaunchConfigurationDialog();
- } else {
- mSkinCombo.select(index);
- }
index = LaunchConfigDelegate.DEFAULT_SPEED;
try {
@@ -405,8 +404,12 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
mAutoTargetButton.getSelection());
- configuration.setAttribute(LaunchConfigDelegate.ATTR_SKIN,
- getSkinNameByIndex(mSkinCombo.getSelectionIndex()));
+ VmInfo vm = mPreferredVmSelector.getFirstSelected();
+ if (vm != null) {
+ configuration.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, vm.getName());
+ } else {
+ configuration.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, (String)null);
+ }
configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
mSpeedCombo.getSelectionIndex());
configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
@@ -425,8 +428,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
LaunchConfigDelegate.DEFAULT_TARGET_MODE);
- configuration.setAttribute(LaunchConfigDelegate.ATTR_SKIN,
- SdkConstants.SKIN_DEFAULT);
configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
LaunchConfigDelegate.DEFAULT_SPEED);
configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
@@ -440,33 +441,4 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
String emuOptions = store.getString(AdtPlugin.PREFS_EMU_OPTIONS);
configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE, emuOptions);
}
-
- private String getSkinNameByIndex(int index) {
- if (mTarget != null && index > 0) {
- String[] skins = mTarget.getSkins();
- if (skins != null && index < skins.length) {
- return skins[index];
- }
- }
-
- return null;
- }
-
- private int getSkinIndex(String name) {
- if (mTarget != null) {
- String[] skins = mTarget.getSkins();
- if (skins != null) {
- int index = 0;
- for (String skin : skins) {
- if (skin.equalsIgnoreCase(name)) {
- return index;
- }
- index++;
- }
- }
- }
-
- return -1;
- }
-
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java
index af7f2bb..6a40ed0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java
@@ -398,11 +398,13 @@ public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab {
config.setMappedResources(resources);
}
- /** Loads the ui with the activities of the specified project, and store the
- * activities in <code>mActivities</code>
+ /**
+ * Loads the ui with the activities of the specified project, and stores the
+ * activities in <code>mActivities</code>.
+ * <p/>
* First activity is selected by default if present.
- * @param project The project to load the activities from
- * @return The array of activities or null if none could be found.
+ *
+ * @param project The project to load the activities from.
*/
private void loadActivities(IProject project) {
if (project != null) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java
index 434269c..e64c2f4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java
@@ -199,7 +199,7 @@ public class BuildPreferencePage extends FieldEditorPreferencePage implements
*/
private void handleException(Throwable t) {
String msg = t.getMessage();
- if (t == null) {
+ if (msg == null) {
Throwable cause = t.getCause();
if (cause != null) {
handleException(cause);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java
index 1ca89cd..7fc3318 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java
@@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.project;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@@ -53,13 +54,13 @@ public class FolderDecorator implements ILightweightLabelDecorator {
// check the folder is directly under the project.
if (folder.getParent().getType() == IResource.PROJECT) {
String name = folder.getName();
- if (name.equals(AndroidConstants.FD_ASSETS)) {
+ if (name.equals(SdkConstants.FD_ASSETS)) {
decorate(decoration, " [Android assets]");
decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT);
- } else if (name.equals(AndroidConstants.FD_RESOURCES)) {
+ } else if (name.equals(SdkConstants.FD_RESOURCES)) {
decorate(decoration, " [Android resources]");
decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT);
- } else if (name.equals(AndroidConstants.FD_NATIVE_LIBS)) {
+ } else if (name.equals(SdkConstants.FD_NATIVE_LIBS)) {
decorate(decoration, " [Native Libraries]");
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
index de4b339..399eac9 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
@@ -493,7 +493,7 @@ public final class ExportWizard extends Wizard implements IExportWizard {
}
// no more cause and still no message. display the first exception.
- return cause.getClass().getCanonicalName();
+ return t.getClass().getCanonicalName();
}
return message;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java
index 3614be3..e161e18 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java
@@ -256,7 +256,6 @@ final class ProjectCheckPage extends ExportWizardPage {
/**
* Checks the parameters for correctness, and update the error message and buttons.
- * @return the current IProject of this launch config.
*/
private void handleProjectNameChange() {
setPageComplete(false);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
index 2cafa01..4da216c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
@@ -28,8 +28,12 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
@@ -125,7 +129,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
*/
private static IClasspathContainer allocateAndroidContainer(String containerId,
IJavaProject javaProject) {
- IProject iProject = javaProject.getProject();
+ final IProject iProject = javaProject.getProject();
// remove potential MARKER_TARGETs.
try {
@@ -139,7 +143,9 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
}
- // first we check if the SDK has been loaded
+ // First we check if the SDK has been loaded.
+ // By passing the javaProject to getSdkLoadStatus(), we ensure that, should the SDK
+ // not be loaded yet, the classpath container will be resolved again once the SDK is loaded.
boolean sdkIsLoaded = AdtPlugin.getDefault().getSdkLoadStatus(javaProject) ==
LoadStatus.LOADED;
@@ -172,8 +178,14 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
String message = null;
boolean outputToConsole = true;
if (hashString == null || hashString.length() == 0) {
- message = String.format(
- "Project has no target set. Edit the project properties to set one.");
+ // if there is no hash string we only show this if the SDK is loaded.
+ // For a project opened at start-up with no target, this would be displayed twice,
+ // once when the project is opened, and once after the SDK has finished loading.
+ // By testing the sdk is loaded, we only show this once in the console.
+ if (sdkIsLoaded) {
+ message = String.format(
+ "Project has no target set. Edit the project properties to set one.");
+ }
} else if (sdkIsLoaded) {
message = String.format(
"Unable to resolve target '%s'", hashString);
@@ -187,23 +199,41 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
// and it's expected. (we do keep the error marker though).
outputToConsole = false;
}
-
- // log the error and put the marker on the project
- if (outputToConsole) {
- AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, iProject, message);
- }
- IMarker marker = BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, message,
- IMarker.SEVERITY_ERROR);
- // add a marker priority as this is an more important error than the error that will
- // spring from the lack of library
- try {
- marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
- } catch (CoreException e) {
- // just log the error
- AdtPlugin.log(e, "Error changing target marker priority.");
+ if (message != null) {
+ // log the error and put the marker on the project if we can.
+ if (outputToConsole) {
+ AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, iProject, message);
+ }
+
+ try {
+ BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, message, -1,
+ IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH);
+ } catch (CoreException e) {
+ // In some cases, the workspace may be locked for modification when we pass here.
+ // We schedule a new job to put the marker after.
+ final String fmessage = message;
+ Job markerJob = new Job("Android SDK: Resolving error markers") {
+ @SuppressWarnings("unchecked")
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET,
+ fmessage, -1, IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH);
+ } catch (CoreException e2) {
+ return e2.getStatus();
+ }
+
+ return Status.OK_STATUS;
+ }
+ };
+
+ // build jobs are run after other interactive jobs
+ markerJob.setPriority(Job.BUILD);
+ markerJob.schedule();
+ }
}
-
+
// return a dummy container to replace the one we may have had before.
return new IClasspathContainer() {
public IClasspathEntry[] getClasspathEntries() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java
index fad4f19..1f6ebf1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java
@@ -37,7 +37,8 @@ import javax.management.InvalidAttributeValueException;
public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader {
/**
- * Wrapper around a {@link Class} to provide the methods of {@link IClassDescriptor}.
+ * Wrapper around a {@link Class} to provide the methods of
+ * {@link IAndroidClassLoader.IClassDescriptor}.
*/
public final static class ClassWrapper implements IClassDescriptor {
private Class<?> mClass;
@@ -416,7 +417,7 @@ public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader
}
/**
- * Returns a {@link IClass} by its fully-qualified name.
+ * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
* @param className the fully-qualified name of the class to return.
* @throws ClassNotFoundException
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java
index 232b9e8..dfe876f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java
@@ -82,11 +82,8 @@ public final class AndroidTargetParser {
/**
* Parses the framework, collects all interesting information and stores them in the
- * {@link FrameworkResourceManager} given to the constructor.
+ * {@link IAndroidTarget} given to the constructor.
*
- * @param osSdkPath the OS path of the SDK directory.
- * @param resourceManager the {@link FrameworkResourceManager} that will store the parsed
- * resources.
* @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
* @return True if the SDK path was valid and parsing has been attempted.
*/
@@ -400,7 +397,6 @@ public final class AndroidTargetParser {
* Loads and collects the action and category default values from the framework.
* The values are added to the <code>actions</code> and <code>categories</code> lists.
*
- * @param osLibPath The OS path to the SDK tools/lib folder, ending with a separator.
* @param activityActions the list which will receive the activity action values.
* @param broadcastActions the list which will receive the broadcast action values.
* @param serviceActions the list which will receive the service action values.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java
index 50d319e..35057d1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java
@@ -64,7 +64,7 @@ public interface IAndroidClassLoader {
throws IOException, InvalidAttributeValueException, ClassFormatError;
/**
- * Returns a {@link IClass} by its fully-qualified name.
+ * Returns a {@link IClassDescriptor} by its fully-qualified name.
* @param className the fully-qualified name of the class to return.
* @throws ClassNotFoundException
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
index 3b9d10e..19f8f45 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
@@ -18,17 +18,17 @@ package com.android.ide.eclipse.adt.sdk;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.project.ProjectProperties;
+import com.android.sdklib.project.ProjectProperties.PropertyType;
+import com.android.sdklib.vm.VmManager;
import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
@@ -46,21 +46,20 @@ import java.util.HashMap;
* To start using an SDK, call {@link #loadSdk(String)} which returns the instance of
* the Sdk object.
*
- * To get the list of platforms present in the SDK, call {@link #getPlatforms()}.
- * To get the list of add-ons present in the SDK, call {@link #getAddons()}.
- *
+ * To get the list of platforms or add-ons present in the SDK, call {@link #getTargets()}.
*/
public class Sdk {
- private final static String PROPERTY_PROJECT_TARGET = "androidTarget"; //$NON-NLS-1$
-
private static Sdk sCurrentSdk = null;
private final SdkManager mManager;
+ private final VmManager mVmManager;
+
private final HashMap<IProject, IAndroidTarget> mProjectMap =
new HashMap<IProject, IAndroidTarget>();
private final HashMap<IAndroidTarget, AndroidTargetData> mTargetMap =
new HashMap<IAndroidTarget, AndroidTargetData>();
private final String mDocBaseUrl;
+
/**
* Loads an SDK and returns an {@link Sdk} object if success.
@@ -74,18 +73,33 @@ public class Sdk {
final ArrayList<String> logMessages = new ArrayList<String>();
ISdkLog log = new ISdkLog() {
- public void error(String errorFormat, Object... arg) {
- logMessages.add(String.format(errorFormat, arg));
+ public void error(Throwable throwable, String errorFormat, Object... arg) {
+ if (errorFormat != null) {
+ logMessages.add(String.format(errorFormat, arg));
+ }
+
+ if (throwable != null) {
+ logMessages.add(throwable.getMessage());
+ }
}
public void warning(String warningFormat, Object... arg) {
logMessages.add(String.format(warningFormat, arg));
}
+ public void printf(String msgFormat, Object... arg) {
+ logMessages.add(String.format(msgFormat, arg));
+ }
};
// get an SdkManager object for the location
SdkManager manager = SdkManager.createManager(sdkLocation, log);
if (manager != null) {
- sCurrentSdk = new Sdk(manager);
+ VmManager vmManager = null;
+ try {
+ vmManager = new VmManager(manager, log);
+ } catch (AndroidLocationException e) {
+ log.error(e, "Error parsing the VMs");
+ }
+ sCurrentSdk = new Sdk(manager, vmManager);
return sCurrentSdk;
} else {
StringBuilder sb = new StringBuilder("Error Loading the SDK:\n");
@@ -106,6 +120,13 @@ public class Sdk {
}
/**
+ * Returns the location (OS path) of the current SDK.
+ */
+ public String getSdkLocation() {
+ return mManager.getLocation();
+ }
+
+ /**
* Returns the URL to the local documentation.
* Can return null if no documentation is found in the current SDK.
*
@@ -181,7 +202,8 @@ public class Sdk {
*/
public static String getProjectTargetHashString(IProject project) {
// load the default.properties from the project folder.
- ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString());
+ ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
+ PropertyType.DEFAULT);
if (properties == null) {
AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'",
project.getName());
@@ -200,10 +222,12 @@ public class Sdk {
public static void setProjectTargetHashString(IProject project, String targetHashString) {
// because we don't want to erase other properties from default.properties, we first load
// them
- ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString());
+ ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
+ PropertyType.DEFAULT);
if (properties == null) {
// doesn't exist yet? we create it.
- properties = ProjectProperties.create(project.getLocation().toOSString());
+ properties = ProjectProperties.create(project.getLocation().toOSString(),
+ PropertyType.DEFAULT);
}
// add/change the target hash string.
@@ -218,7 +242,7 @@ public class Sdk {
}
}
/**
- * Return the {@link PlatformData} for a given {@link IAndroidTarget}.
+ * Return the {@link AndroidTargetData} for a given {@link IAndroidTarget}.
*/
public AndroidTargetData getTargetData(IAndroidTarget target) {
synchronized (mTargetMap) {
@@ -226,8 +250,17 @@ public class Sdk {
}
}
- private Sdk(SdkManager manager) {
+ /**
+ * Returns the {@link VmManager}. If the VmManager failed to parse the VM folder, this could
+ * be <code>null</code>.
+ */
+ public VmManager getVmManager() {
+ return mVmManager;
+ }
+
+ private Sdk(SdkManager manager, VmManager vmManager) {
mManager = manager;
+ mVmManager = vmManager;
// pre-compute some paths
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java
index 8db09f2..0e60f8a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java
@@ -323,7 +323,7 @@ public final class WidgetClassLoader implements IAndroidClassLoader {
}
/**
- * Returns a {@link IClass} by its fully-qualified name.
+ * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
* @param className the fully-qualified name of the class to return.
* @throws ClassNotFoundException
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
index 8044bcb..7fc94ef 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
@@ -26,6 +26,7 @@ import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import com.android.sdkuilib.SdkTargetSelector;
import org.eclipse.core.filesystem.URIUtil;
@@ -64,9 +65,11 @@ import java.util.regex.Pattern;
* NewAndroidProjectCreationPage is a project creation page that provides the
* following fields:
* <ul>
+ * <li> Project name
+ * <li> SDK Target
+ * <li> Application name
* <li> Package name
* <li> Activity name
- * <li> Location of the SDK
* </ul>
* Note: this class is public so that it can be accessed from unit tests.
* It is however an internal class. Its API may change without notice.
@@ -93,13 +96,14 @@ public class NewProjectCreationPage extends WizardPage {
private static final Pattern sProjectNamePattern = Pattern.compile("^[\\w][\\w. -]*$"); //$NON-NLS-1$
/** Last user-browsed location, static so that it be remembered for the whole session */
private static String sCustomLocationOsPath = ""; //$NON-NLS-1$
+ private static boolean sAutoComputeCustomLocation = true;
private final int MSG_NONE = 0;
private final int MSG_WARNING = 1;
private final int MSG_ERROR = 2;
private String mUserPackageName = ""; //$NON-NLS-1$
- private String mUserActivityName = ""; //$NON-NLS-1$
+ private String mUserActivityName = ""; //$NON-NLS-1$
private boolean mUserCreateActivityCheck = INITIAL_CREATE_ACTIVITY;
private String mSourceFolder = ""; //$NON-NLS-1$
@@ -114,6 +118,8 @@ public class NewProjectCreationPage extends WizardPage {
private Text mLocationPathField;
private Button mBrowseButton;
private Button mCreateActivityCheck;
+ private Text mMinSdkVersionField;
+ private SdkTargetSelector mSdkTargetSelector;
private boolean mInternalLocationPathUpdate;
protected boolean mInternalProjectNameUpdate;
@@ -122,7 +128,7 @@ public class NewProjectCreationPage extends WizardPage {
private boolean mInternalActivityNameUpdate;
protected boolean mProjectNameModifiedByUser;
protected boolean mApplicationNameModifiedByUser;
- private SdkTargetSelector mSdkTargetSelector;
+ private boolean mInternalMinSdkVersionUpdate;
/**
@@ -133,13 +139,6 @@ public class NewProjectCreationPage extends WizardPage {
public NewProjectCreationPage(String pageName) {
super(pageName);
setPageComplete(false);
- if (sCustomLocationOsPath == null ||
- sCustomLocationOsPath.length() == 0 ||
- !new File(sCustomLocationOsPath).isDirectory()) {
- // FIXME location of samples is pretty much impossible here.
- //sCustomLocationOsPath = AdtPlugin.getOsSdkSamplesFolder();
- sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath();
- }
}
// --- Getters used by NewProjectWizard ---
@@ -170,6 +169,11 @@ public class NewProjectCreationPage extends WizardPage {
return mActivityNameField == null ? INITIAL_NAME : mActivityNameField.getText().trim();
}
+ /** Returns the value of the min sdk version field with spaces trimmed. */
+ public String getMinSdkVersion() {
+ return mMinSdkVersionField == null ? "" : mMinSdkVersionField.getText().trim();
+ }
+
/** Returns the value of the application name field with spaces trimmed. */
public String getApplicationName() {
// Return the name of the activity as default application name.
@@ -200,7 +204,7 @@ public class NewProjectCreationPage extends WizardPage {
* "src" constant. */
public String getSourceFolder() {
if (isNewProject() || mSourceFolder == null || mSourceFolder.length() == 0) {
- return AndroidConstants.FD_SOURCES;
+ return SdkConstants.FD_SOURCES;
} else {
return mSourceFolder;
}
@@ -389,9 +393,16 @@ public class NewProjectCreationPage extends WizardPage {
}
mSdkTargetSelector = new SdkTargetSelector(group, targets, false /*multi-selection*/);
+
+ // If there's only one target, select it
+ if (targets != null && targets.length == 1) {
+ mSdkTargetSelector.setSelection(targets[0]);
+ }
+
mSdkTargetSelector.setSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
+ updateLocationPathField(null);
setPageComplete(validatePage());
}
});
@@ -506,6 +517,25 @@ public class NewProjectCreationPage extends WizardPage {
onActivityNameFieldModified();
}
});
+
+ // min sdk version label
+ label = new Label(group, SWT.NONE);
+ label.setText("Min SDK Version:");
+ label.setFont(parent.getFont());
+ label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
+
+ // min sdk version entry field
+ mMinSdkVersionField = new Text(group, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
+ mMinSdkVersionField.setLayoutData(data);
+ mMinSdkVersionField.setFont(parent.getFont());
+ mMinSdkVersionField.addListener(SWT.Modify, new Listener() {
+ public void handleEvent(Event event) {
+ onMinSdkVersionFieldModified();
+ setPageComplete(validatePage());
+ }
+ });
}
@@ -588,7 +618,29 @@ public class NewProjectCreationPage extends WizardPage {
mInternalLocationPathUpdate = true;
if (custom_location) {
if (abs_dir != null) {
+ // We get here if the user selected a directory with the "Browse" button.
+ // Disable auto-compute of the custom location unless the user selected
+ // the exact same path.
+ sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
+ abs_dir.equals(sCustomLocationOsPath);
sCustomLocationOsPath = TextProcessor.process(abs_dir);
+ } else if (sAutoComputeCustomLocation ||
+ !new File(sCustomLocationOsPath).isDirectory()) {
+ // By default select the samples directory of the current target
+ IAndroidTarget target = getSdkTarget();
+ if (target != null) {
+ sCustomLocationOsPath = target.getPath(IAndroidTarget.SAMPLES);
+ }
+
+ // If we don't have a target, select the base directory of the
+ // "universal sdk". If we don't even have that, use a root drive.
+ if (sCustomLocationOsPath == null || sCustomLocationOsPath.length() == 0) {
+ if (Sdk.getCurrent() != null) {
+ sCustomLocationOsPath = Sdk.getCurrent().getSdkLocation();
+ } else {
+ sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath();
+ }
+ }
}
if (!mLocationPathField.getText().equals(sCustomLocationOsPath)) {
mLocationPathField.setText(sCustomLocationOsPath);
@@ -615,8 +667,13 @@ public class NewProjectCreationPage extends WizardPage {
private void onLocationPathFieldModified() {
if (!mInternalLocationPathUpdate) {
// When the updates doesn't come from updateLocationPathField, it must be the user
- // editing the field manually, in which case we want to save the value internally.
- sCustomLocationOsPath = getLocationPathFieldValue();
+ // editing the field manually, in which case we want to save the value internally
+ // and we disable auto-compute of the custom location (to avoid overriding the user
+ // value)
+ String newPath = getLocationPathFieldValue();
+ sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
+ newPath.equals(sCustomLocationOsPath);
+ sCustomLocationOsPath = newPath;
extractNamesFromAndroidManifest();
setPageComplete(validatePage());
}
@@ -665,6 +722,31 @@ public class NewProjectCreationPage extends WizardPage {
}
/**
+ * Called when the min sdk version field has been modified.
+ *
+ * Ignore the internal modifications. When modified by the user, try to match
+ * a target with the same API level.
+ */
+ private void onMinSdkVersionFieldModified() {
+ if (mInternalMinSdkVersionUpdate) {
+ return;
+ }
+
+ try {
+ int version = Integer.parseInt(getMinSdkVersion());
+
+ for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+ if (target.getApiVersionNumber() == version) {
+ mSdkTargetSelector.setSelection(target);
+ break;
+ }
+ }
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ /**
* Called when the radio buttons are changed between the "create new project" and the
* "use existing source" mode. This reverts the fields to whatever the user manually
* entered before.
@@ -697,89 +779,132 @@ public class NewProjectCreationPage extends WizardPage {
* can actually be found in the custom user directory.
*/
private void extractNamesFromAndroidManifest() {
- if (!isNewProject()) {
- File f = new File(getProjectLocation());
- if (f.isDirectory()) {
- Path path = new Path(f.getPath());
- String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
- AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
- if (manifest.exists()) {
- String packageName = null;
- String activityName = null;
- try {
- packageName = manifest.getPackageName();
- activityName = manifest.getActivityName(1);
- } catch (Exception e) {
- // pass
- }
+ if (isNewProject()) {
+ return;
+ }
+ String projectLocation = getProjectLocation();
+ File f = new File(projectLocation);
+ if (!f.isDirectory()) {
+ return;
+ }
- if (packageName != null && packageName.length() > 0) {
- mPackageNameField.setText(packageName);
- }
+ Path path = new Path(f.getPath());
+ String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
+ AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
+ if (!manifest.exists()) {
+ return;
+ }
+
+ String packageName = null;
+ String activityName = null;
+ String minSdkVersion = null;
+ try {
+ packageName = manifest.getPackageName();
+ activityName = manifest.getActivityName(1);
+ minSdkVersion = manifest.getMinSdkVersion();
+ } catch (Exception e) {
+ // ignore exceptions
+ }
- if (activityName != null && activityName.length() > 0) {
- mInternalActivityNameUpdate = true;
- mInternalCreateActivityUpdate = true;
- mActivityNameField.setText(activityName);
- mCreateActivityCheck.setSelection(true);
- mInternalCreateActivityUpdate = false;
- mInternalActivityNameUpdate = false;
-
- // If project name and application names are empty, use the activity
- // name as a default. If the activity name has dots, it's a part of a
- // package specification and only the last identifier must be used.
- if (activityName.indexOf('.') != -1) {
- String[] ids = activityName.split(AndroidConstants.RE_DOT);
- activityName = ids[ids.length - 1];
- }
- if (mProjectNameField.getText().length() == 0 ||
- !mProjectNameModifiedByUser) {
- mInternalProjectNameUpdate = true;
- mProjectNameField.setText(activityName);
- mInternalProjectNameUpdate = false;
- }
- if (mApplicationNameField.getText().length() == 0 ||
- !mApplicationNameModifiedByUser) {
- mInternalApplicationNameUpdate = true;
- mApplicationNameField.setText(activityName);
- mInternalApplicationNameUpdate = false;
- }
- } else {
- mInternalActivityNameUpdate = true;
- mInternalCreateActivityUpdate = true;
- mActivityNameField.setText("");
- mCreateActivityCheck.setSelection(false);
- mInternalCreateActivityUpdate = false;
- mInternalActivityNameUpdate = false;
-
- // There is no activity name to use to fill in the project and application
- // name. However if there's a package name, we can use this as a base.
- if (packageName != null && packageName.length() > 0) {
- // Package name is a java identifier, so it's most suitable for
- // an application name.
-
- if (mApplicationNameField.getText().length() == 0 ||
- !mApplicationNameModifiedByUser) {
- mInternalApplicationNameUpdate = true;
- mApplicationNameField.setText(packageName);
- mInternalApplicationNameUpdate = false;
- }
-
- // For the project name, remove any dots
- packageName = packageName.replace('.', '_');
- if (mProjectNameField.getText().length() == 0 ||
- !mProjectNameModifiedByUser) {
- mInternalProjectNameUpdate = true;
- mProjectNameField.setText(packageName);
- mInternalProjectNameUpdate = false;
- }
-
- }
+
+ if (packageName != null && packageName.length() > 0) {
+ mPackageNameField.setText(packageName);
+ }
+
+ if (activityName != null && activityName.length() > 0) {
+ mInternalActivityNameUpdate = true;
+ mInternalCreateActivityUpdate = true;
+ mActivityNameField.setText(activityName);
+ mCreateActivityCheck.setSelection(true);
+ mInternalCreateActivityUpdate = false;
+ mInternalActivityNameUpdate = false;
+
+ // If project name and application names are empty, use the activity
+ // name as a default. If the activity name has dots, it's a part of a
+ // package specification and only the last identifier must be used.
+ if (activityName.indexOf('.') != -1) {
+ String[] ids = activityName.split(AndroidConstants.RE_DOT);
+ activityName = ids[ids.length - 1];
+ }
+ if (mProjectNameField.getText().length() == 0 ||
+ !mProjectNameModifiedByUser) {
+ mInternalProjectNameUpdate = true;
+ mProjectNameField.setText(activityName);
+ mInternalProjectNameUpdate = false;
+ }
+ if (mApplicationNameField.getText().length() == 0 ||
+ !mApplicationNameModifiedByUser) {
+ mInternalApplicationNameUpdate = true;
+ mApplicationNameField.setText(activityName);
+ mInternalApplicationNameUpdate = false;
+ }
+ } else {
+ mInternalActivityNameUpdate = true;
+ mInternalCreateActivityUpdate = true;
+ mActivityNameField.setText(""); //$NON-NLS-1$
+ mCreateActivityCheck.setSelection(false);
+ mInternalCreateActivityUpdate = false;
+ mInternalActivityNameUpdate = false;
+
+ // There is no activity name to use to fill in the project and application
+ // name. However if there's a package name, we can use this as a base.
+ if (packageName != null && packageName.length() > 0) {
+ // Package name is a java identifier, so it's most suitable for
+ // an application name.
+
+ if (mApplicationNameField.getText().length() == 0 ||
+ !mApplicationNameModifiedByUser) {
+ mInternalApplicationNameUpdate = true;
+ mApplicationNameField.setText(packageName);
+ mInternalApplicationNameUpdate = false;
+ }
+
+ // For the project name, remove any dots
+ packageName = packageName.replace('.', '_');
+ if (mProjectNameField.getText().length() == 0 ||
+ !mProjectNameModifiedByUser) {
+ mInternalProjectNameUpdate = true;
+ mProjectNameField.setText(packageName);
+ mInternalProjectNameUpdate = false;
+ }
+
+ }
+ }
+
+ // Select the target matching the manifest's sdk, if any
+ boolean foundTarget = false;
+ if (minSdkVersion != null) {
+ try {
+ int sdkVersion = Integer.parseInt(minSdkVersion);
+
+ for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+ if (target.getApiVersionNumber() == sdkVersion) {
+ mSdkTargetSelector.setSelection(target);
+ foundTarget = true;
+ break;
}
}
+ } catch(NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (!foundTarget) {
+ for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+ if (projectLocation.startsWith(target.getLocation())) {
+ mSdkTargetSelector.setSelection(target);
+ foundTarget = true;
+ break;
+ }
}
}
+
+ if (!foundTarget) {
+ mInternalMinSdkVersionUpdate = true;
+ mMinSdkVersionField.setText(minSdkVersion == null ? "" : minSdkVersion); //$NON-NLS-1$
+ mInternalMinSdkVersionUpdate = false;
+ }
}
/**
@@ -805,6 +930,9 @@ public class NewProjectCreationPage extends WizardPage {
status |= validateActivityField();
}
if ((status & MSG_ERROR) == 0) {
+ status |= validateMinSdkVersionField();
+ }
+ if ((status & MSG_ERROR) == 0) {
status |= validateSourceFolder();
}
if (status == MSG_NONE) {
@@ -950,6 +1078,38 @@ public class NewProjectCreationPage extends WizardPage {
}
/**
+ * Validates the sdk target choice.
+ *
+ * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
+ */
+ private int validateMinSdkVersionField() {
+
+ // If the min sdk version is empty, it is always accepted.
+ if (getMinSdkVersion().length() == 0) {
+ return MSG_NONE;
+ }
+
+ int version = -1;
+ try {
+ // If not empty, it must be a valid integer > 0
+ version = Integer.parseInt(getMinSdkVersion());
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+
+ if (version < 1) {
+ return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR);
+ }
+
+ if (getSdkTarget() != null && getSdkTarget().getApiVersionNumber() != version) {
+ return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
+ MSG_WARNING);
+ }
+
+ return MSG_NONE;
+ }
+
+ /**
* Validates the activity name field.
*
* @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
index a582217..607159a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
@@ -22,6 +22,7 @@ import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -85,32 +86,36 @@ public class NewProjectWizard extends Wizard implements INewWizard {
private static final String PARAM_IS_NEW_PROJECT = "IS_NEW_PROJECT"; //$NON-NLS-1$
private static final String PARAM_SRC_FOLDER = "SRC_FOLDER"; //$NON-NLS-1$
private static final String PARAM_SDK_TARGET = "SDK_TARGET"; //$NON-NLS-1$
+ private static final String PARAM_MIN_SDK_VERSION = "MIN_SDK_VERSION"; //$NON-NLS-1$
private static final String PH_ACTIVITIES = "ACTIVITIES"; //$NON-NLS-1$
+ private static final String PH_USES_SDK = "USES-SDK"; //$NON-NLS-1$
private static final String PH_INTENT_FILTERS = "INTENT_FILTERS"; //$NON-NLS-1$
private static final String PH_STRINGS = "STRINGS"; //$NON-NLS-1$
private static final String BIN_DIRECTORY =
- AndroidConstants.FD_BINARIES + AndroidConstants.WS_SEP;
+ SdkConstants.FD_OUTPUT + AndroidConstants.WS_SEP;
private static final String RES_DIRECTORY =
- AndroidConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
+ SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
private static final String ASSETS_DIRECTORY =
- AndroidConstants.FD_ASSETS + AndroidConstants.WS_SEP;
+ SdkConstants.FD_ASSETS + AndroidConstants.WS_SEP;
private static final String DRAWABLE_DIRECTORY =
- AndroidConstants.FD_DRAWABLE + AndroidConstants.WS_SEP;
+ SdkConstants.FD_DRAWABLE + AndroidConstants.WS_SEP;
private static final String LAYOUT_DIRECTORY =
- AndroidConstants.FD_LAYOUT + AndroidConstants.WS_SEP;
+ SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP;
private static final String VALUES_DIRECTORY =
- AndroidConstants.FD_VALUES + AndroidConstants.WS_SEP;
+ SdkConstants.FD_VALUES + AndroidConstants.WS_SEP;
private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$
private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY
+ "AndroidManifest.template"; //$NON-NLS-1$
private static final String TEMPLATE_ACTIVITIES = TEMPLATES_DIRECTORY
+ "activity.template"; //$NON-NLS-1$
+ private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY
+ + "uses-sdk.template"; //$NON-NLS-1$
private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY
+ "launcher_intent_filter.template"; //$NON-NLS-1$
-
+
private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY
+ "strings.template"; //$NON-NLS-1$
private static final String TEMPLATE_STRING = TEMPLATES_DIRECTORY
@@ -235,6 +240,7 @@ public class NewProjectWizard extends Wizard implements INewWizard {
parameters.put(PARAM_IS_NEW_PROJECT, mMainPage.isNewProject());
parameters.put(PARAM_SRC_FOLDER, mMainPage.getSourceFolder());
parameters.put(PARAM_SDK_TARGET, mMainPage.getSdkTarget());
+ parameters.put(PARAM_MIN_SDK_VERSION, mMainPage.getMinSdkVersion());
if (mMainPage.isCreateActivity()) {
// An activity name can be of the form ".package.Class" or ".Class".
@@ -449,6 +455,15 @@ public class NewProjectWizard extends Wizard implements INewWizard {
// remove the activity(ies) from the manifest
manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, "");
}
+
+ String minSdkVersion = (String) parameters.get(PARAM_MIN_SDK_VERSION);
+ if (minSdkVersion != null && minSdkVersion.length() > 0) {
+ String usesSdkTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_USES_SDK);
+ String usesSdk = replaceParameters(usesSdkTemplate, parameters);
+ manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, usesSdk);
+ } else {
+ manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, "");
+ }
// Save in the project as UTF-8
InputStream stream = new ByteArrayInputStream(
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
index f3f7b79..0e780a9 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
@@ -130,48 +130,14 @@ public class AndroidConstants {
public final static String FN_TRACEVIEW = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"traceview.exe" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$
- /** Folder Names for Android Projects . */
-
- /* Resources folder name, i.e. "res". */
- public final static String FD_RESOURCES = "res"; //$NON-NLS-1$
- /** Assets folder name, i.e. "assets" */
- public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
- /** Default source folder name, i.e. "src" */
- public final static String FD_SOURCES = "src"; //$NON-NLS-1$
- /** Default native library folder name inside the project, i.e. "libs"
- * While the folder inside the .apk is "lib", we call that one libs because
- * that's what we use in ant for both .jar and .so and we need to make the 2 development ways
- * compatible. */
- public final static String FD_NATIVE_LIBS = "libs"; //$NON-NLS-1$
- /** Native lib folder inside the APK: "lib" */
- public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$
- /** Default bin folder name, i.e. "bin" */
- public final static String FD_BINARIES = "bin"; //$NON-NLS-1$
- /** Default anim resource folder name, i.e. "anim" */
- public final static String FD_ANIM = "anim"; //$NON-NLS-1$
- /** Default color resource folder name, i.e. "color" */
- public final static String FD_COLOR = "color"; //$NON-NLS-1$
- /** Default drawable resource folder name, i.e. "drawable" */
- public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$
- /** Default layout resource folder name, i.e. "layout" */
- public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$
- /** Default menu resource folder name, i.e. "menu" */
- public final static String FD_MENU = "menu"; //$NON-NLS-1$
- /** Default values resource folder name, i.e. "values" */
- public final static String FD_VALUES = "values"; //$NON-NLS-1$
- /** Default xml resource folder name, i.e. "xml" */
- public final static String FD_XML = "xml"; //$NON-NLS-1$
- /** Default raw resource folder name, i.e. "raw" */
- public final static String FD_RAW = "raw"; //$NON-NLS-1$
-
/** Absolute path of the workspace root, i.e. "/" */
public final static String WS_ROOT = WS_SEP;
/** Absolute path of the resource folder, eg "/res".<br> This is a workspace path. */
- public final static String WS_RESOURCES = WS_SEP + FD_RESOURCES;
+ public final static String WS_RESOURCES = WS_SEP + SdkConstants.FD_RESOURCES;
/** Absolute path of the resource folder, eg "/assets".<br> This is a workspace path. */
- public final static String WS_ASSETS = WS_SEP + FD_ASSETS;
+ public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS;
/** Leaf of the javaDoc folder. Does not start with a separator. */
public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/reference"; //$NON-NLS-1$
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java
index 2db9e9b..cd238d2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java
@@ -97,7 +97,7 @@ public class AndroidManifestHelper {
*/
public String getPackageName() {
try {
- return getPackageNameInternal(mXPath, getSource());
+ return mXPath.evaluate("/manifest/@package", getSource()); //$NON-NLS-1$
} catch (XPathExpressionException e1) {
// If the XPath failed to evaluate, we'll return null.
} catch (Exception e) {
@@ -111,17 +111,39 @@ public class AndroidManifestHelper {
}
/**
+ * Returns the minSdkVersion defined in the manifest file.
+ *
+ * @return A String object with the package or null if any error happened.
+ */
+ public String getMinSdkVersion() {
+ try {
+ return mXPath.evaluate("/manifest/uses-sdk/@" //$NON-NLS-1$
+ + AndroidXPathFactory.DEFAULT_NS_PREFIX
+ + ":minSdkVersion", getSource()); //$NON-NLS-1$
+ } catch (XPathExpressionException e1) {
+ // If the XPath failed to evaluate, we'll return null.
+ } catch (Exception e) {
+ // if this happens this is due to the resource being out of sync.
+ // so we must refresh it and do it again
+
+ // for any other kind of exception we must return null as well;
+ }
+
+ return null;
+ }
+ /**
* Returns the i-th activity defined in the manifest file.
*
- * @param manifest The manifest's IFile object.
* @param index The 1-based index of the activity to return.
- * @param xpath An optional xpath object. If null is provided a new one will
- * be created.
* @return A String object with the activity or null if any error happened.
*/
public String getActivityName(int index) {
try {
- return getActivityNameInternal(index, mXPath, getSource());
+ return mXPath.evaluate("/manifest/application/activity[" //$NON-NLS-1$
+ + index
+ + "]/@" //$NON-NLS-1$
+ + AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$
+ getSource());
} catch (XPathExpressionException e1) {
// If the XPath failed to evaluate, we'll return null.
} catch (Exception e) {
@@ -216,26 +238,4 @@ public class AndroidManifestHelper {
return null;
}
- /**
- * Performs the actual XPath evaluation to get the package name.
- * Extracted so that we can share it with AndroidManifestFromProject.
- */
- private static String getPackageNameInternal(XPath xpath, InputSource source)
- throws XPathExpressionException {
- return xpath.evaluate("/manifest/@package", source); //$NON-NLS-1$
- }
-
- /**
- * Performs the actual XPath evaluation to get the activity name.
- * Extracted so that we can share it with AndroidManifestFromProject.
- */
- private static String getActivityNameInternal(int index, XPath xpath, InputSource source)
- throws XPathExpressionException {
- return xpath.evaluate("/manifest/application/activity[" //$NON-NLS-1$
- + index
- + "]/@" //$NON-NLS-1$
- + AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$
- source);
- }
-
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
index cb98525..2866ce2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
@@ -319,7 +319,7 @@ public class AndroidManifestParser {
* @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
*/
@Override
- public void error(SAXParseException e) throws SAXException {
+ public void error(SAXParseException e) {
if (mMarkErrors) {
handleError(e, e.getLineNumber());
}
@@ -329,7 +329,7 @@ public class AndroidManifestParser {
* @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
*/
@Override
- public void fatalError(SAXParseException e) throws SAXException {
+ public void fatalError(SAXParseException e) {
if (mMarkErrors) {
handleError(e, e.getLineNumber());
}
@@ -348,7 +348,6 @@ public class AndroidManifestParser {
/**
* Processes the activity node.
* @param attributes the attributes for the activity node.
- * @throws CoreException
*/
private void processActivityNode(Attributes attributes) {
// lets get the activity name, and add it to the list
@@ -381,7 +380,6 @@ public class AndroidManifestParser {
* @param attributes the attributes for the activity node.
* @param superClassName the fully qualified name of the super class that this
* node is representing
- * @throws CoreException
*/
private void processNode(Attributes attributes, String superClassName) {
// lets get the class name, and check it if required.
@@ -567,12 +565,11 @@ public class AndroidManifestParser {
/**
* Parses the manifest file, collects data, and checks for errors.
* @param javaProject The java project. Required.
- * @param manifestFile
+ * @param manifestFile The manifest file to parse.
* @param errorListener the {@link XmlErrorListener} object being notified of the presence
* of errors. Optional.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
- * @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)}
*/
public static AndroidManifestParser parseForError(IJavaProject javaProject, IFile manifestFile,
XmlErrorListener errorListener) throws CoreException {
@@ -581,12 +578,9 @@ public class AndroidManifestParser {
/**
* Parses the manifest file, and collects data.
- * @param manifestFile
- * @param errorListener the {@link XmlErrorListener} object being notified of the presence
- * of errors. Optional.
+ * @param manifestFile The manifest file to parse.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
- * @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)}
*/
public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException {
return parse(null /* javaProject */, manifestFile, null /* errorListener */,
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
index 530c89e..8544b25 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
@@ -39,7 +39,7 @@ public class AndroidXPathFactory {
/**
* Construct the context with the prefix associated with the android namespace.
- * @param prefix the Prefix
+ * @param androidPrefix the Prefix
*/
public AndroidNamespaceContext(String androidPrefix) {
mAndroidPrefix = androidPrefix;
@@ -71,7 +71,7 @@ public class AndroidXPathFactory {
/**
* Creates a new XPath object, specifying which prefix in the query is used for the
* android namespace.
- * @param prefix The namespace prefix.
+ * @param androidPrefix The namespace prefix.
*/
public static XPath newXPath(String androidPrefix) {
XPath xpath = sFactory.newXPath();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java
index c69e875..bd8b444 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java
@@ -82,11 +82,13 @@ public final class BaseProjectHelper {
}
/**
- * Adds a marker to a file on a specific line
+ * Adds a marker to a file on a specific line. This methods catches thrown
+ * {@link CoreException}, and returns null instead.
* @param file the file to be marked
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
- * @param lineNumber the line number where to put the mark
+ * @param lineNumber the line number where to put the mark. If line is < 1, it puts the marker
+ * on line 1.
* @param severity the severity of the marker.
* @return the IMarker that was added or null if it failed to add one.
*/
@@ -96,7 +98,7 @@ public final class BaseProjectHelper {
IMarker marker = file.createMarker(markerId);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, severity);
- if (lineNumber == -1) {
+ if (lineNumber < 1) {
lineNumber = 1;
}
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
@@ -108,7 +110,7 @@ public final class BaseProjectHelper {
return marker;
} catch (CoreException e) {
- AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'",
+ AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$
markerId, file.getFullPath());
}
@@ -116,7 +118,8 @@ public final class BaseProjectHelper {
}
/**
- * Adds a marker to a resource.
+ * Adds a marker to a resource. This methods catches thrown {@link CoreException},
+ * and returns null instead.
* @param resource the file to be marked
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
@@ -129,7 +132,7 @@ public final class BaseProjectHelper {
IMarker marker = resource.createMarker(markerId);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, severity);
-
+
// on Windows, when adding a marker to a project, it takes a refresh for the marker
// to show. In order to fix this we're forcing a refresh of elements receiving
// markers (and only the element, not its children), to force the marker display.
@@ -137,13 +140,43 @@ public final class BaseProjectHelper {
return marker;
} catch (CoreException e) {
- AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'",
+ AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$
markerId, resource.getFullPath());
}
return null;
}
-
+
+ /**
+ * Adds a marker to a resource. This method does not catch {@link CoreException} and instead
+ * throw them.
+ * @param resource the file to be marked
+ * @param markerId The id of the marker to add.
+ * @param message the message associated with the mark
+ * @param lineNumber the line number where to put the mark if != -1.
+ * @param severity the severity of the marker.
+ * @param priority the priority of the marker
+ * @return the IMarker that was added.
+ * @throws CoreException
+ */
+ public final static IMarker addMarker(IResource resource, String markerId,
+ String message, int lineNumber, int severity, int priority) throws CoreException {
+ IMarker marker = resource.createMarker(markerId);
+ marker.setAttribute(IMarker.MESSAGE, message);
+ marker.setAttribute(IMarker.SEVERITY, severity);
+ if (lineNumber != -1) {
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ }
+ marker.setAttribute(IMarker.PRIORITY, priority);
+
+ // on Windows, when adding a marker to a project, it takes a refresh for the marker
+ // to show. In order to fix this we're forcing a refresh of elements receiving
+ // markers (and only the element, not its children), to force the marker display.
+ resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+
+ return marker;
+ }
+
/**
* Tests that a class name is valid for usage in the manifest.
* <p/>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
index 26fbf42..fda55c4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
@@ -62,6 +62,7 @@ public class XmlErrorHandler extends DefaultHandler {
/**
* Xml Error call back
* @param exception the parsing exception
+ * @throws SAXException
*/
@Override
public void error(SAXParseException exception) throws SAXException {
@@ -71,6 +72,7 @@ public class XmlErrorHandler extends DefaultHandler {
/**
* Xml Fatal Error call back
* @param exception the parsing exception
+ * @throws SAXException
*/
@Override
public void fatalError(SAXParseException exception) throws SAXException {
@@ -80,6 +82,7 @@ public class XmlErrorHandler extends DefaultHandler {
/**
* Xml Warning call back
* @param exception the parsing exception
+ * @throws SAXException
*/
@Override
public void warning(SAXParseException exception) throws SAXException {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java
index 3176c8e..3875e81 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java
@@ -20,6 +20,7 @@ import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format;
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
+import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import org.eclipse.core.runtime.IStatus;
import org.w3c.dom.Document;
@@ -228,7 +229,7 @@ public final class AttrsXmlParser {
}
mStyleMap.put(name, style);
if (lastComment != null) {
- style.setJavaDoc(formatJavadoc(lastComment.getNodeValue()));
+ style.setJavaDoc(parseJavadoc(lastComment.getNodeValue()));
}
}
}
@@ -263,14 +264,15 @@ public final class AttrsXmlParser {
}
if (info != null) {
if (lastComment != null) {
- info.setJavaDoc(formatJavadoc(lastComment.getNodeValue()));
+ info.setJavaDoc(parseJavadoc(lastComment.getNodeValue()));
+ info.setDeprecatedDoc(parseDeprecatedDoc(lastComment.getNodeValue()));
}
}
}
}
return info;
}
-
+
/**
* Finds all the attributes for a particular style node,
* e.g. a declare-styleable of name "TextView" or "LinearLayout_Layout".
@@ -431,16 +433,23 @@ public final class AttrsXmlParser {
}
/**
- * Formats the javadoc.
+ * Parses the javadoc comment.
* Only keeps the first sentence.
- * Removes and simplifies links and references.
+ * <p/>
+ * This does not remove nor simplify links and references. Such a transformation
+ * is done later at "display" time in {@link DescriptorsUtils#formatTooltip(String)} and co.
*/
- private String formatJavadoc(String comment) {
+ private String parseJavadoc(String comment) {
if (comment == null) {
return null;
}
+
// sanitize & collapse whitespace
comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Explicitly remove any @deprecated tags since they are handled separately.
+ comment = comment.replaceAll("(?:\\{@deprecated[^}]*\\}|@deprecated[^@}]*)", "");
+
// take everything up to the first dot that is followed by a space or the end of the line.
// I love regexps :-). For the curious, the regexp is:
// - start of line
@@ -456,6 +465,41 @@ public final class AttrsXmlParser {
// - followed by a space (?= non-capturing zero-width positive look-ahead)
// - anything else is ignored
comment = comment.replaceFirst("^\\s*(.*?(?:$|(?<![a-zA-Z]\\.[a-zA-Z])\\.(?=\\s))).*", "$1"); //$NON-NLS-1$ //$NON-NLS-2$
+
return comment;
}
+
+
+ /**
+ * Parses the javadoc and extract the first @deprecated tag, if any.
+ * Returns null if there's no @deprecated tag.
+ * The deprecated tag can be of two forms:
+ * - {+@deprecated ...text till the next bracket }
+ * Note: there should be no space or + between { and @. I need one in this comment otherwise
+ * this method will be tagged as deprecated ;-)
+ * - @deprecated ...text till the next @tag or end of the comment.
+ * In both cases the comment can be multi-line.
+ */
+ private String parseDeprecatedDoc(String comment) {
+ // Skip if we can't even find the tag in the comment.
+ if (comment == null) {
+ return null;
+ }
+
+ // sanitize & collapse whitespace
+ comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
+
+ int pos = comment.indexOf("{@deprecated");
+ if (pos >= 0) {
+ comment = comment.substring(pos + 12 /* len of {@deprecated */);
+ comment = comment.replaceFirst("^([^}]*).*", "$1");
+ } else if ((pos = comment.indexOf("@deprecated")) >= 0) {
+ comment = comment.substring(pos + 11 /* len of @deprecated */);
+ comment = comment.replaceFirst("^(.*?)(?:@.*|$)", "$1");
+ } else {
+ return null;
+ }
+
+ return comment.trim();
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
index 6cff62c..efa5981 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
@@ -55,8 +55,10 @@ public class DeclareStyleableInfo {
private String[] mEnumValues;
/** Values for flag. null for other types. */
private String[] mFlagValues;
- /** Short javadoc */
+ /** Short javadoc (i.e. the first sentence). */
private String mJavaDoc;
+ /** Documentation for deprecated attributes. Null if not deprecated. */
+ private String mDeprecatedDoc;
/**
* @param name The XML Name of the attribute
@@ -74,6 +76,7 @@ public class DeclareStyleableInfo {
mEnumValues = info.mEnumValues;
mFlagValues = info.mFlagValues;
mJavaDoc = info.mJavaDoc;
+ mDeprecatedDoc = info.mDeprecatedDoc;
}
/** Returns the XML Name of the attribute */
@@ -93,10 +96,14 @@ public class DeclareStyleableInfo {
public String[] getFlagValues() {
return mFlagValues;
}
- /** Returns a short javadoc */
+ /** Returns a short javadoc, .i.e. the first sentence. */
public String getJavaDoc() {
return mJavaDoc;
}
+ /** Returns the documentation for deprecated attributes. Null if not deprecated. */
+ public String getDeprecatedDoc() {
+ return mDeprecatedDoc;
+ }
/** Sets the values for enums. null for other types. */
public void setEnumValues(String[] values) {
@@ -106,10 +113,14 @@ public class DeclareStyleableInfo {
public void setFlagValues(String[] values) {
mFlagValues = values;
}
- /** Sets a short javadoc */
+ /** Sets a short javadoc, .i.e. the first sentence. */
public void setJavaDoc(String javaDoc) {
mJavaDoc = javaDoc;
}
+ /** Sets the documentation for deprecated attributes. Null if not deprecated. */
+ public void setDeprecatedDoc(String deprecatedDoc) {
+ mDeprecatedDoc = deprecatedDoc;
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
index d1b4547..50d3d28 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
@@ -91,7 +91,12 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
/**
* Constructor for AndroidContentAssist
- * @param rootElementDescriptors The valid root elements of the XML hierarchy
+ * @param descriptorId An id for {@link AndroidTargetData#getDescriptorProvider(int)}.
+ * The Id can be one of {@link AndroidTargetData#DESCRIPTOR_MANIFEST},
+ * {@link AndroidTargetData#DESCRIPTOR_LAYOUT},
+ * {@link AndroidTargetData#DESCRIPTOR_MENU},
+ * or {@link AndroidTargetData#DESCRIPTOR_XML}.
+ * All other values will throw an {@link IllegalArgumentException} later at runtime.
*/
public AndroidContentAssist(int descriptorId) {
mDescriptorId = descriptorId;
@@ -723,7 +728,6 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
/**
* Computes (if needed) and returns the root descriptor.
- * @return
*/
private ElementDescriptor getRootDescriptor() {
if (mRootDescriptor == null) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java
index 78e0401..dca7db0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java
@@ -722,7 +722,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
}
/**
- * Returns the {@link PlatformData} for the edited file.
+ * Returns the {@link AndroidTargetData} for the edited file.
*/
public AndroidTargetData getTargetData() {
IProject project = getProject();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
index 2c779b2..70d03a1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
@@ -38,6 +38,7 @@ public abstract class AttributeDescriptor {
private String mXmlLocalName;
private ElementDescriptor mParent;
private final String mNsUri;
+ private boolean mDeprecated;
/**
* Creates a new {@link AttributeDescriptor}
@@ -70,6 +71,14 @@ public abstract class AttributeDescriptor {
return mParent;
}
+ public void setDeprecated(boolean isDeprecated) {
+ mDeprecated = isDeprecated;
+ }
+
+ public boolean isDeprecated() {
+ return mDeprecated;
+ }
+
/**
* Returns an optional icon for the attribute.
* <p/>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java
index 05ae922..2729565 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.editors.descriptors;
+import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiAbstractTextAttributeNode;
import org.eclipse.jface.viewers.ILabelProvider;
@@ -35,6 +36,17 @@ public class AttributeDescriptorLabelProvider implements ILabelProvider {
}
public Image getImage(Object element) {
+ if (element instanceof UiAbstractTextAttributeNode) {
+ UiAbstractTextAttributeNode node = (UiAbstractTextAttributeNode) element;
+ if (node.getDescriptor().isDeprecated()) {
+ String v = node.getCurrentValue();
+ if (v != null && v.length() > 0) {
+ IconFactory factory = IconFactory.getInstance();
+ return factory.getIcon("warning"); //$NON-NLS-1$
+ }
+ }
+ }
+
return null;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
index c84bf57..09f1478 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
@@ -92,8 +92,9 @@ public final class DescriptorsUtils {
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
* See {@link AndroidConstants#NS_RESOURCES} for a common value.
* @param infos The array of {@link AttributeInfo} to read and append to attributes
- * @param requiredAttributes An optional list of attributes to mark as "required" (i.e. append
- * a "*" to their UI name as a hint for the user.)
+ * @param requiredAttributes An optional set of attributes to mark as "required" (i.e. append
+ * a "*" to their UI name as a hint for the user.) If not null, must contains
+ * entries in the form "elem-name/attr-name". Elem-name can be "*".
* @param overrides A map [attribute name => TextAttributeDescriptor creator]. A creator
* can either by a Class<? extends TextAttributeDescriptor> or an instance of
* {@link ITextAttributeCreator} that instantiates the right TextAttributeDescriptor.
@@ -101,16 +102,15 @@ public final class DescriptorsUtils {
public static void appendAttributes(ArrayList<AttributeDescriptor> attributes,
String elementXmlName,
String nsUri, AttributeInfo[] infos,
- String[] requiredAttributes,
+ Set<String> requiredAttributes,
Map<String, Object> overrides) {
for (AttributeInfo info : infos) {
boolean required = false;
if (requiredAttributes != null) {
- for(String attr_name : requiredAttributes) {
- if (attr_name.equals(info.getName())) {
- required = true;
- break;
- }
+ String attr_name = info.getName();
+ if (requiredAttributes.contains("*/" + attr_name) ||
+ requiredAttributes.contains(elementXmlName + "/" + attr_name)) {
+ required = true;
}
}
appendAttribute(attributes, elementXmlName, nsUri, info, required, overrides);
@@ -144,7 +144,26 @@ public final class DescriptorsUtils {
if (required) {
uiName += "*"; //$NON-NLS-1$
}
- String tooltip = formatTooltip(info.getJavaDoc()); // tooltip
+
+ String tooltip = null;
+ String rawTooltip = info.getJavaDoc();
+ if (rawTooltip == null) {
+ rawTooltip = "";
+ }
+
+ String deprecated = info.getDeprecatedDoc();
+ if (deprecated != null) {
+ if (rawTooltip.length() > 0) {
+ rawTooltip += "@@"; //$NON-NLS-1$ insert a break
+ }
+ rawTooltip += "* Deprecated";
+ if (deprecated.length() != 0) {
+ rawTooltip += ": " + deprecated; //$NON-NLS-1$
+ }
+ if (deprecated.length() == 0 || !deprecated.endsWith(".")) { //$NON-NLS-1$
+ rawTooltip += "."; //$NON-NLS-1$
+ }
+ }
// Add the known types to the tooltip
Format[] formats_list = info.getFormats();
@@ -154,11 +173,14 @@ public final class DescriptorsUtils {
HashSet<Format> formats_set = new HashSet<Format>();
StringBuilder sb = new StringBuilder();
- if (tooltip != null) {
- sb.append(tooltip);
- sb.append(" "); //$NON-NLS-1$
+ if (rawTooltip != null && rawTooltip.length() > 0) {
+ sb.append(rawTooltip);
+ sb.append(" "); //$NON-NLS-1$
}
- sb.append("["); //$NON-NLS-1$
+ if (sb.length() > 0) {
+ sb.append("@@"); //$NON-NLS-1$ @@ inserts a break before the types
+ }
+ sb.append("["); //$NON-NLS-1$
for (int i = 0; i < flen; i++) {
Format f = formats_list[i];
formats_set.add(f);
@@ -172,19 +194,21 @@ public final class DescriptorsUtils {
sb.append("]"); //$NON-NLS-1$
if (required) {
- sb.append(". Required.");
+ sb.append(".@@* "); //$NON-NLS-1$ @@ inserts a break.
+ sb.append("Required.");
}
// The extra space at the end makes the tooltip more readable on Windows.
sb.append(" "); //$NON-NLS-1$
- tooltip = sb.toString();
+ rawTooltip = sb.toString();
+ tooltip = formatTooltip(rawTooltip);
// Create a specialized attribute if we can
if (overrides != null) {
for (Entry<String, Object> entry: overrides.entrySet()) {
String key = entry.getKey();
- String elements[] = key.split("/");
+ String elements[] = key.split("/"); //$NON-NLS-1$
String overrideAttrLocalName = null;
if (elements.length < 1) {
continue;
@@ -193,7 +217,7 @@ public final class DescriptorsUtils {
elements = null;
} else {
overrideAttrLocalName = elements[elements.length - 1];
- elements = elements[0].split(",");
+ elements = elements[0].split(","); //$NON-NLS-1$
}
if (overrideAttrLocalName == null ||
@@ -204,7 +228,8 @@ public final class DescriptorsUtils {
boolean ok_element = elements.length < 1;
if (!ok_element) {
for (String element : elements) {
- if (element.equals("*") || element.equals(elementXmlName)) {
+ if (element.equals("*") //$NON-NLS-1$
+ || element.equals(elementXmlName)) {
ok_element = true;
break;
}
@@ -271,8 +296,12 @@ public final class DescriptorsUtils {
// By default a simple text field is used
if (attr == null) {
+ if (tooltip == null) {
+ tooltip = formatTooltip(rawTooltip);
+ }
attr = new TextAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip);
}
+ attr.setDeprecated(info.getDeprecatedDoc() != null);
attributes.add(attr);
}
@@ -582,6 +611,8 @@ public final class DescriptorsUtils {
Pattern p_code = Pattern.compile("<code>(.+?)</code>(.*)"); //$NON-NLS-1$
// Detects @blah@, used in hard-coded tooltip descriptors
Pattern p_elem = Pattern.compile("@([\\w -]+)@(.*)"); //$NON-NLS-1$
+ // Detects a buffer that starts by @@ (request for a break)
+ Pattern p_break = Pattern.compile("@@(.*)"); //$NON-NLS-1$
// Detects a buffer that starts by @ < or { (one that was not matched above)
Pattern p_open = Pattern.compile("([@<\\{])(.*)"); //$NON-NLS-1$
// Detects everything till the next potential separator, i.e. @ < or {
@@ -616,6 +647,10 @@ public final class DescriptorsUtils {
if (text != null) {
currentLength += text.length() - 2;
}
+ } else if ((m = p_break.matcher(javadoc)).matches()) {
+ spans.add(BREAK);
+ currentLength = 0;
+ javadoc = m.group(1);
} else if ((m = p_open.matcher(javadoc)).matches()) {
s = m.group(1);
javadoc = m.group(2);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
index 632471d..a9d2b2e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
@@ -95,6 +95,10 @@ public class TextAttributeDescriptor extends AttributeDescriptor implements IPro
}
public String getCategory() {
+ if (isDeprecated()) {
+ return "Deprecated";
+ }
+
ElementDescriptor parent = getParent();
if (parent != null) {
return parent.getUiName();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java
index c512625..381539b 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java
@@ -20,7 +20,6 @@ import com.android.layoutlib.api.IXmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
@@ -178,7 +177,7 @@ public abstract class BasePullParser implements IXmlPullParser {
return mParsingState;
}
- public int nextTag() throws XmlPullParserException, IOException {
+ public int nextTag() throws XmlPullParserException {
int eventType = next();
if (eventType != START_TAG && eventType != END_TAG) {
throw new XmlPullParserException("expected start or end tag", this, null);
@@ -186,7 +185,7 @@ public abstract class BasePullParser implements IXmlPullParser {
return eventType;
}
- public String nextText() throws XmlPullParserException, IOException {
+ public String nextText() throws XmlPullParserException {
if (getEventType() != START_TAG) {
throw new XmlPullParserException("parser must be on START_TAG to read next text", this,
null);
@@ -208,7 +207,7 @@ public abstract class BasePullParser implements IXmlPullParser {
}
}
- public int nextToken() throws XmlPullParserException, IOException {
+ public int nextToken() throws XmlPullParserException {
return next();
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
index 87a14ad..a0b30ec 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
@@ -33,8 +33,10 @@ import org.eclipse.core.runtime.IStatus;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
@@ -166,7 +168,13 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
"android", //$NON-NLS-1$
AndroidConstants.NS_RESOURCES);
+ // -- setup the required attributes overrides --
+
+ Set<String> required = new HashSet<String>();
+ required.add("provider/authorities"); //$NON-NLS-1$
+
// -- setup the various attribute format overrides --
+
// The key for each override is "element1,element2,.../attr-xml-local-name" or
// "*/attr-xml-local-name" to match the attribute in any element.
@@ -181,7 +189,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
tooltip);
}
});
-
+
overrides.put("*/theme", ThemeAttributeDescriptor.class); //$NON-NLS-1$
overrides.put("*/permission", ListAttributeDescriptor.class); //$NON-NLS-1$
overrides.put("*/targetPackage", PackageAttributeDescriptor.class); //$NON-NLS-1$
@@ -212,8 +220,12 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
// --
- inflateElement(manifestMap, overrides, elementDescs,
- MANIFEST_ELEMENT, "AndroidManifest"); //$NON-NLS-1$
+ inflateElement(manifestMap,
+ overrides,
+ required,
+ elementDescs,
+ MANIFEST_ELEMENT,
+ "AndroidManifest"); //$NON-NLS-1$
insertAttribute(MANIFEST_ELEMENT, PACKAGE_ATTR_DESC);
sanityCheck(manifestMap, MANIFEST_ELEMENT);
@@ -312,16 +324,17 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
* "Inflates" the properties of an {@link ElementDescriptor} from the styleable declaration.
* <p/>
* This first creates all the attributes for the given ElementDescriptor.
- * It then find all children of the descriptor, inflate them recursively and set them
+ * It then finds all children of the descriptor, inflate them recursively and set them
* as child to this ElementDescriptor.
*
- * @param styleMap The input styleable map for manifest elements & attributes
+ * @param styleMap The input styleable map for manifest elements & attributes.
* @param overrides A list of attribute overrides (to customize the type of the attribute
- * descriptors)
+ * descriptors).
+ * @param requiredAttributes Set of attributes to be marked as required.
* @param existingElementDescs A map of already created element descriptors, keyed by
* XML local name. This is used to use the static elements created initially by this
* class, which are referenced directly by editors (so that reloading an SDK won't
- * break these references)
+ * break these references).
* @param elemDesc The current {@link ElementDescriptor} to inflate.
* @param styleName The name of the {@link ElementDescriptor} to inflate. Its XML local name
* will be guessed automatically from the style name.
@@ -329,6 +342,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
private void inflateElement(
Map<String, DeclareStyleableInfo> styleMap,
Map<String, Object> overrides,
+ Set<String> requiredAttributes,
HashMap<String, ElementDescriptor> existingElementDescs,
ElementDescriptor elemDesc,
String styleName) {
@@ -342,7 +356,9 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
DescriptorsUtils.appendAttributes(attrDescs,
elemDesc.getXmlLocalName(),
AndroidConstants.NS_RESOURCES,
- style.getAttributes(), null, overrides);
+ style.getAttributes(),
+ requiredAttributes,
+ overrides);
elemDesc.setTooltip(style.getJavaDoc());
elemDesc.setAttributes(attrDescs.toArray(new AttributeDescriptor[attrDescs.size()]));
}
@@ -373,7 +389,12 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
}
children.add(child);
- inflateElement(styleMap, overrides, existingElementDescs, child, childStyleName);
+ inflateElement(styleMap,
+ overrides,
+ requiredAttributes,
+ existingElementDescs,
+ child,
+ childStyleName);
}
}
elemDesc.setChildren(children.toArray(new ElementDescriptor[children.size()]));
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java
index 1d01260..9a61d17 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java
@@ -66,7 +66,7 @@ public final class CountryCodeQualifier extends ResourceQualifier {
/**
* Returns the folder name segment for the given value. This is equivalent to calling
* {@link #toString()} on a {@link CountryCodeQualifier} object.
- * @param value the value of the qualifier, as returned by {@link #getCode()}.
+ * @param code the value of the qualifier, as returned by {@link #getCode()}.
*/
public static String getFolderSegment(int code) {
if (code != DEFAULT_CODE && code >= 100 && code <=999) { // code is 3 digit.) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java
index ce527a4..7e30901 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java
@@ -66,7 +66,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier {
/**
* Returns the folder name segment for the given value. This is equivalent to calling
* {@link #toString()} on a {@link NetworkCodeQualifier} object.
- * @param value the value of the qualifier, as returned by {@link #getCode()}.
+ * @param code the value of the qualifier, as returned by {@link #getCode()}.
*/
public static String getFolderSegment(int code) {
if (code != DEFAULT_CODE && code >= 1 && code <= 999) { // code is 1-3 digit.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java
index 0fd05bf..c47bb83 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java
@@ -39,7 +39,7 @@ public final class PixelDensityQualifier extends ResourceQualifier {
/**
* Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
* <code>null</code> is returned.
- * @param segment the folder segment from which to create a qualifier.
+ * @param folderSegment the folder segment from which to create a qualifier.
* @return a new {@link CountryCodeQualifier} object or <code>null</code>
*/
public static PixelDensityQualifier getQualifier(String folderSegment) {
@@ -66,7 +66,7 @@ public final class PixelDensityQualifier extends ResourceQualifier {
/**
* Returns the folder name segment for the given value. This is equivalent to calling
* {@link #toString()} on a {@link NetworkCodeQualifier} object.
- * @param value the value of the qualifier, as returned by {@link #getCode()}.
+ * @param value the value of the qualifier, as returned by {@link #getValue()}.
*/
public static String getFolderSegment(int value) {
if (value != DEFAULT_DENSITY) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java
index 72438a6..3812791 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java
@@ -132,7 +132,7 @@ public final class MultiResourceFile extends ResourceFile implements IValueResou
/**
* Adds a resource item to the list
* @param resType The type of the resource
- * @param name The name of the resource.
+ * @param value The value of the resource.
*/
public void addResourceValue(String resType, ResourceValue value) {
ResourceType type = ResourceType.getEnum(resType);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java
index 183af27..8b6c3c1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java
@@ -107,7 +107,6 @@ public final class ProjectClassLoader extends ClassLoader {
* @param parent the root of the file.
* @param segments the segments containing the path of the file
* @param index the offset at which to start looking into segments.
- * @return
* @throws FileNotFoundException
*/
private File getFile(File parent, String[] segments, int index)
@@ -168,8 +167,6 @@ public final class ProjectClassLoader extends ClassLoader {
/**
* Loads a class from the 3rd party jar present in the project
- * @param name
- * @return
* @throws ClassNotFoundException
*/
private Class<?> loadClassFromJar(String name) throws ClassNotFoundException {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java
index b0881fa..40e4e3b 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java
@@ -393,8 +393,6 @@ public class ProjectResources implements IResourceRepository {
/**
* Resolves a compiled resource id of type int[] into the resource name.
- * @param id
- * @return
*/
public String resolveResourceValue(int[] id) {
if (mStyleableValueToNameMap != null) {
@@ -407,9 +405,6 @@ public class ProjectResources implements IResourceRepository {
/**
* Returns the value of a resource by its type and name.
- * @param type
- * @param name
- * @return
*/
public Integer getResourceValue(String type, String name) {
if (mResourceValueMap != null) {
@@ -444,8 +439,7 @@ public class ProjectResources implements IResourceRepository {
/**
* Returns the list of regions used in the resources with the given language.
- * @param currentLanguage the current language the region must be associated with
- * @return
+ * @param currentLanguage the current language the region must be associated with.
*/
public Set<String> getRegions(String currentLanguage) {
Set<String> set = new HashSet<String>();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java
index 6db0d94..98f5b39 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java
@@ -185,7 +185,7 @@ public final class ResourceFolder extends Resource {
/**
* Returns the {@link ResourceFile} matching a given name.
- * @param file The name of the file to return.
+ * @param filename The name of the file to return.
* @return the {@link ResourceFile} or <code>null</code> if no match was found.
*/
public ResourceFile getFile(String filename) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java
index bd93301..5fc7393 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java
@@ -16,21 +16,21 @@
package com.android.ide.eclipse.editors.resources.manager;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
+import com.android.sdklib.SdkConstants;
/**
* Enum representing a type of resource folder.
*/
public enum ResourceFolderType {
- ANIM(AndroidConstants.FD_ANIM),
- COLOR(AndroidConstants.FD_COLOR),
- DRAWABLE(AndroidConstants.FD_DRAWABLE),
- LAYOUT(AndroidConstants.FD_LAYOUT),
- MENU(AndroidConstants.FD_MENU),
- RAW(AndroidConstants.FD_RAW),
- VALUES(AndroidConstants.FD_VALUES),
- XML(AndroidConstants.FD_XML);
+ ANIM(SdkConstants.FD_ANIM),
+ COLOR(SdkConstants.FD_COLOR),
+ DRAWABLE(SdkConstants.FD_DRAWABLE),
+ LAYOUT(SdkConstants.FD_LAYOUT),
+ MENU(SdkConstants.FD_MENU),
+ RAW(SdkConstants.FD_RAW),
+ VALUES(SdkConstants.FD_VALUES),
+ XML(SdkConstants.FD_XML);
private final String mName;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java
index 9c5f0fc..6099008 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java
@@ -30,6 +30,7 @@ import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFolder;
import com.android.ide.eclipse.editors.resources.manager.files.IFileWrapper;
import com.android.ide.eclipse.editors.resources.manager.files.IFolderWrapper;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -269,8 +270,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
/**
* Loads and returns the resources for a given {@link IAndroidTarget}
- * @param osFilePath the path to the folder containing all the versions of the framework
- * resources
+ * @param androidTarget the target from which to load the framework resources
*/
public ProjectResources loadFrameworkResources(IAndroidTarget androidTarget) {
String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);
@@ -329,7 +329,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
return;
}
- IFolder resourceFolder = project.getFolder(AndroidConstants.FD_RESOURCES);
+ IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES);
ProjectResources projectResources = mMap.get(project);
if (projectResources == null) {
@@ -478,7 +478,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener,
* @return true if the path is under /project res/
*/
private boolean isInResFolder(IPath path) {
- return AndroidConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
+ return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
}
/**
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java
index 1211236..32b1107 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java
@@ -115,8 +115,6 @@ public class SingleResourceFile extends ResourceFile {
/**
* Returns the name of the resources.
- * @param type
- * @return
*/
private String getResourceName(ResourceType type) {
// get the name from the filename.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java
index 0a14214..d99cb13 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java
@@ -17,7 +17,6 @@
package com.android.ide.eclipse.editors.resources.manager.files;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
import java.io.File;
import java.io.FileInputStream;
@@ -45,7 +44,7 @@ public class FileWrapper implements IAbstractFile {
mFile = file;
}
- public InputStream getContents() throws CoreException {
+ public InputStream getContents() {
try {
return new FileInputStream(mFile);
} catch (FileNotFoundException e) {
@@ -74,7 +73,7 @@ public class FileWrapper implements IAbstractFile {
}
if (obj instanceof File) {
- return mFile.equals((File)obj);
+ return mFile.equals(obj);
}
return super.equals(obj);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java
index 8afea33..9ad7460 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java
@@ -59,7 +59,7 @@ public class FolderWrapper implements IAbstractFolder {
}
if (obj instanceof File) {
- return mFolder.equals((File)obj);
+ return mFolder.equals(obj);
}
return super.equals(obj);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java
index 441c65b..f0f5f2d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java
@@ -55,7 +55,7 @@ public class IFileWrapper implements IAbstractFile {
}
if (obj instanceof IFile) {
- return mFile.equals((IFile)obj);
+ return mFile.equals(obj);
}
return super.equals(obj);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java
index 92b5c07..b1fa3ef 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java
@@ -61,7 +61,7 @@ public class IFolderWrapper implements IAbstractFolder {
}
if (obj instanceof IFolder) {
- return mFolder.equals((IFolder)obj);
+ return mFolder.equals(obj);
}
return super.equals(obj);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java
index 772fb52..0729881 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java
@@ -17,7 +17,6 @@
package com.android.ide.eclipse.editors.ui.tree;
import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java
index b7dffdd..4a05b1e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java
@@ -79,8 +79,7 @@ import java.util.HashMap;
* To use this, instantiate somewhere in the UI and then:
* <ul>
* <li>Use {@link #setConfiguration(String)} or {@link #setConfiguration(FolderConfiguration)}.
- * <li>Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)} and
- * test it using {@link FolderConfiguration#isValid()}.
+ * <li>Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)}.
* </ul>
*/
public class ConfigurationSelector extends Composite {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
index b27dd4f..cc643be 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
@@ -30,6 +30,7 @@ import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptor
import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.ConfigurationState;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -243,7 +244,7 @@ class NewXmlFileCreationPage extends WizardPage {
/** Absolute destination folder root, e.g. "/res/" */
private static String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
/** Relative destination folder root, e.g. "res/" */
- private static String sResFolderRel = AndroidConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
+ private static String sResFolderRel = SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP;
private IProject mProject;
private Text mProjectTextField;
@@ -629,7 +630,7 @@ class NewXmlFileCreationPage extends WizardPage {
// Disregard this folder selection if it doesn't point to /res/something
if (wsFolderPath != null &&
wsFolderPath.segmentCount() > 1 &&
- AndroidConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) {
+ SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) {
score += 2;
} else {
wsFolderPath = null;
@@ -1002,7 +1003,7 @@ class NewXmlFileCreationPage extends WizardPage {
String fileName = getFileName();
if (fileName == null || fileName.length() == 0) {
error = "A destination file name is required.";
- } else if (fileName != null && !fileName.endsWith(AndroidConstants.DOT_XML)) {
+ } else if (!fileName.endsWith(AndroidConstants.DOT_XML)) {
error = String.format("The filename must end with %1$s.", AndroidConstants.DOT_XML);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java
index d3ff334..6913ce0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java
@@ -17,7 +17,6 @@
package com.android.ide.eclipse.editors.wizards;
import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.IResourceRepository;
import com.android.ide.eclipse.common.resources.ResourceItem;
import com.android.ide.eclipse.common.resources.ResourceType;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template b/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
index b4faae6..b43e75f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
@@ -6,4 +6,5 @@
<application android:icon="@drawable/icon" android:label="APPLICATION_NAME">
ACTIVITIES
</application>
+USES-SDK
</manifest>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template b/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
new file mode 100644
index 0000000..8adae71
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
@@ -0,0 +1 @@
+ <uses-sdk android:minSdkVersion="MIN_SDK_VERSION" />
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class1.java b/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
index 3cf1027..3cf1027 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class1.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class2.java b/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
index 4d15c47..4d15c47 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class2.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
index 4700821..5a89d01 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
@@ -60,8 +60,9 @@ public class ProjectHelperTest extends TestCase {
ProjectHelper.fixProjectClasspathEntries(javaProject);
IClasspathEntry[] fixedEntries = javaProject.getRawClasspath();
- assertEquals(2, fixedEntries.length);
+ assertEquals(3, fixedEntries.length);
assertEquals("Project/src", fixedEntries[0].getPath().toString());
- assertEquals(CONTAINER_ID, fixedEntries[1].getPath().toString());
+ assertEquals(OLD_CONTAINER_ID, fixedEntries[1].getPath().toString());
+ assertEquals(CONTAINER_ID, fixedEntries[2].getPath().toString());
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java
index f3d9b79..872938b 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java
@@ -45,6 +45,8 @@ public class AndroidJarLoaderTest extends TestCase {
@Override
public void tearDown() throws Exception {
+ mFrameworkClassLoader = null;
+ System.gc();
}
/** Preloads classes. They should load just fine. */
@@ -74,8 +76,9 @@ public class AndroidJarLoaderTest extends TestCase {
Class<?> c = _findClass(mFrameworkClassLoader, "jar.example.Class2"); //$NON-NLS-1$
assertEquals("jar.example.Class2", c.getName()); //$NON-NLS-1$
HashMap<String, Class<?>> map = getPrivateClassCache();
+ assertTrue(map.containsKey("jar.example.Class1")); //$NON-NLS-1$
assertTrue(map.containsKey("jar.example.Class2")); //$NON-NLS-1$
- assertEquals(1, map.size());
+ assertEquals(2, map.size());
}
/** call the protected method findClass */
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
index 76ebfc3..8338453 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
@@ -94,6 +94,33 @@ public class AttrsXmlParserTest extends TestCase {
assertEquals(Integer.valueOf(0), valueMap.get("horizontal"));
assertEquals(Integer.valueOf(1), valueMap.get("vertical"));
}
+
+ public final void testDeprecated() throws Exception {
+ mParser.preload();
+
+ DeclareStyleableInfo dep = mParser.getDeclareStyleableList().get("DeprecatedTest");
+ assertNotNull(dep);
+
+ AttributeInfo[] attrs = dep.getAttributes();
+ assertEquals(4, attrs.length);
+
+ assertEquals("deprecated-inline", attrs[0].getName());
+ assertEquals("In-line deprecated.", attrs[0].getDeprecatedDoc());
+ assertEquals("Deprecated comments using delimiters.", attrs[0].getJavaDoc());
+
+ assertEquals("deprecated-multiline", attrs[1].getName());
+ assertEquals("Multi-line version of deprecated that works till the next tag.",
+ attrs[1].getDeprecatedDoc());
+ assertEquals("Deprecated comments on their own line.", attrs[1].getJavaDoc());
+
+ assertEquals("deprecated-not", attrs[2].getName());
+ assertEquals(null, attrs[2].getDeprecatedDoc());
+ assertEquals("This attribute is not deprecated.", attrs[2].getJavaDoc());
+
+ assertEquals("deprecated-no-javadoc", attrs[3].getName());
+ assertEquals("There is no other javadoc here.", attrs[3].getDeprecatedDoc());
+ assertEquals("", attrs[3].getJavaDoc());
+ }
//---- access to private methods
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java
index 5506459..69c3ed8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java
@@ -99,28 +99,26 @@ public class DescriptorsUtilsTest extends TestCase {
ElementDescriptor desc = new ElementDescriptor("application");
desc.setSdkUrl(DescriptorsUtils.MANIFEST_SDK_URL + "TagApplication");
String docBaseUrl = "http://base";
- assertEquals("<form><p></p></form>", DescriptorsUtils.formatFormText("", desc, docBaseUrl));
+ assertEquals("<form><li style=\"image\" value=\"image\"></li></form>", DescriptorsUtils.formatFormText("", desc, docBaseUrl));
- assertEquals("<form><p><a href=\"http://base/reference/android/R.styleable.html#TagApplication\">application</a></p></form>",
+ assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#TagApplication\">application</a></li></form>",
DescriptorsUtils.formatFormText(
"<code>application</code>",
desc, docBaseUrl));
- assertEquals("<form><p><b>android.content.Intent</b></p></form>",
+ assertEquals("<form><li style=\"image\" value=\"image\"><b>android.content.Intent</b></li></form>",
DescriptorsUtils.formatFormText(
"{@link android.content.Intent}",
desc, docBaseUrl));
- assertEquals("<form><p><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">AndroidManifestPermission</a></p></form>",
+ assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">AndroidManifestPermission</a></li></form>",
DescriptorsUtils.formatFormText(
"{@link #AndroidManifestPermission}",
desc, docBaseUrl));
- assertEquals("<form><p><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">\"permission\"</a></p></form>",
+ assertEquals("<form><li style=\"image\" value=\"image\"><a href=\"http://base/reference/android/R.styleable.html#AndroidManifestPermission\">\"permission\"</a></li></form>",
DescriptorsUtils.formatFormText(
"{@link #AndroidManifestPermission &lt;permission&gt;}",
desc, docBaseUrl));
-
}
-
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java
index 9e01081..28f7871 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java
@@ -54,11 +54,11 @@ public class TextInputMethodQualifierTest extends TestCase {
}
public void testNoKey() {
- assertEquals(true, timq.checkAndSet("nokey", config)); //$NON-NLS-1$
+ assertEquals(true, timq.checkAndSet("nokeys", config)); //$NON-NLS-1$
assertTrue(config.getTextInputMethodQualifier() != null);
assertEquals(TextInputMethodQualifier.TextInputMethod.NOKEY,
config.getTextInputMethodQualifier().getValue());
- assertEquals("nokey", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$
+ assertEquals("nokeys", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$
}
public void testFailures() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
index 0c1a508..25a86c3 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
@@ -41,7 +41,7 @@ public class ConfigMatchTest extends TestCase {
private static final String MISC2_FILENAME = "bar.xml"; //$NON-NLS-1$
private ProjectResources mResources;
- private ArrayList<ResourceQualifier> mQualifierList;
+ private ResourceQualifier[] mQualifierList;
private FolderConfiguration config4;
private FolderConfiguration config3;
private FolderConfiguration config2;
@@ -60,7 +60,7 @@ public class ConfigMatchTest extends TestCase {
qualifierListField.setAccessible(true);
// get the actual list.
- mQualifierList = (ArrayList<ResourceQualifier>)qualifierListField.get(manager);
+ mQualifierList = (ResourceQualifier[])qualifierListField.get(manager);
// create the project resources.
mResources = new ProjectResources(false /* isFrameworkRepository */);
@@ -191,10 +191,10 @@ public class ConfigMatchTest extends TestCase {
FolderConfiguration config = new FolderConfiguration();
// those must be of the same length
- assertEquals(qualifierValues.length, mQualifierList.size());
+ assertEquals(qualifierValues.length, mQualifierList.length);
int index = 0;
-
+
for (ResourceQualifier qualifier : mQualifierList) {
String value = qualifierValues[index++];
if (value != null) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
index e51604c..aa9a1f7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
@@ -18,7 +18,7 @@
-->
<resources>
<!-- WARNING !!! THIS IS A MOCK FILE. DO NOT USE FOR DOCUMENTATION PURPOSES.
- This file has been trimmed down to only extract a number of interest cases
+ This file has been trimmed down to only extract a number of interesting cases
for unit tests.
What this contains:
@@ -314,5 +314,27 @@
<attr name="collapseColumns" format="string" />
</declare-styleable>
+ <!-- Test for deprecated attributes. -->
+ <declare-styleable name="DeprecatedTest">
+ <!-- Deprecated comments using delimiters.
+ Ignored. {@deprecated In-line deprecated.} {@ignore Ignored}.
+ -->
+ <attr name="deprecated-inline" />
+
+ <!-- Deprecated comments on their own line.
+ @deprecated Multi-line version of deprecated
+ that works till the next tag.
+ @ignore This tag must be ignored
+ -->
+ <attr name="deprecated-multiline" />
+
+ <!-- This attribute is not deprecated. -->
+ <attr name="deprecated-not" />
+
+ <!-- {@deprecated There is no other javadoc here. } -->
+ <attr name="deprecated-no-javadoc" format="boolean" />
+
+ </declare-styleable>
+
</resources>
diff --git a/eclipse/scripts/create_test_symlinks.sh b/eclipse/scripts/create_test_symlinks.sh
index 1479e04..931dce8 100755
--- a/eclipse/scripts/create_test_symlinks.sh
+++ b/eclipse/scripts/create_test_symlinks.sh
@@ -11,32 +11,38 @@ function back() {
echo $1 | sed 's@[^/]*@..@g'
}
+HOST=`uname`
+if [ "${HOST:0:6}" == "CYGWIN" ]; then
+ # We can't use symlinks under Cygwin
+ function cpdir() { # $1=dest $2=source
+ rsync -avW --delete-after $2 $1
+ }
+
+else
+ # For all other systems which support symlinks
+ function cpdir() { # $1=dest $2=source
+ ln -svf `back $1`/$2 $1
+ }
+fi
+
BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.tests"
DEST=$BASE
BACK=`back $DEST`
-
HOST=`uname`
if [ "$HOST" == "Linux" ]; then
- DIR="ln -svf"
ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/"
elif [ "$HOST" == "Darwin" ]; then
- DIR="ln -svf"
ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/"
elif [ "${HOST:0:6}" == "CYGWIN" ]; then
- DIR="rsync -avW --delete-after"
- JAR="kxml2-2.3.0.jar"
- if [ ! -f "$DEST/$JAR" ]; then
- # Get the jar from ADT if we can, otherwise download it.
- if [ -f "$DEST/../com.android.ide.eclipse.adt/$JAR" ]; then
- cp "$DEST/../com.android.ide.eclipse.adt/$JAR" "$DEST/$JAR"
- else
- wget -O "$DEST/$JAR" "http://internap.dl.sourceforge.net/sourceforge/kxml/$JAR"
- fi
- chmod a+rx "$DEST/$JAR"
+
+ if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then
+ cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/"
+ chmod -v a+rx "$DEST"/*.jar
fi
+
else
echo "Unsupported platform ($HOST). Nothing done."
fi
@@ -44,5 +50,5 @@ fi
# create link to ddmlib tests
DEST=$BASE/unittests/com/android
BACK=`back $DEST`
-$DIR $BACK/development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib $DEST/
+cpdir $DEST development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib