Merge "Reuse device display code from sdk-common"
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
index 6bd16ee..77108c8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -81,6 +81,13 @@
<persistent value="false" />
</extension>
<extension
+ id="com.android.ide.eclipse.adt.buildToolsProblem"
+ name="Android Build Tools Problem"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.core.resources.problemmarker" />
+ <persistent value="false" />
+ </extension>
+ <extension
id="com.android.ide.eclipse.adt.dependencyProblem"
name="Android Dependency Problem"
point="org.eclipse.core.resources.markers">
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 edfc30c..76808e4 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
@@ -151,6 +151,10 @@
* when an AndroidClasspathContainerInitializer has succeeded in creating an
* AndroidClasspathContainer */
public final static String MARKER_TARGET = AdtPlugin.PLUGIN_ID + ".targetProblem"; //$NON-NLS-1$
+ /** Marker for Android Build Tools errors.
+ * This is not cleared on each build like other markers. Instead, it's cleared
+ * when the build tools are setup in the projectState. */
+ public final static String MARKER_BUILD_TOOLS = AdtPlugin.PLUGIN_ID + ".buildToolsProblem"; //$NON-NLS-1$
/** Marker for Android Dependency errors.
* This is not cleared on each build like other markers. Instead, it's cleared
* when a LibraryClasspathContainerInitializer has succeeded in creating a
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 88e9c15..7aec8f5 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
@@ -1433,7 +1433,7 @@
// project that have been resolved before the sdk was loaded
// will have a ProjectState where the IAndroidTarget is null
// so we load the target now that the SDK is loaded.
- sdk.loadTarget(Sdk.getProjectState(iProject));
+ sdk.loadTargetAndBuildTools(Sdk.getProjectState(iProject));
list.add(javaProject);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java
index 71c8263..9d33230 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java
@@ -20,15 +20,14 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.DexWrapper;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.sdk.AdtConsoleSdkLog;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.io.FileOp;
+import com.android.sdklib.repository.ISdkChangeListener;
import com.android.sdklib.util.GrabProcessOutput;
import com.android.sdklib.util.GrabProcessOutput.IProcessOutput;
import com.android.sdklib.util.GrabProcessOutput.Wait;
-import com.android.sdklib.repository.ISdkChangeListener;
import com.android.sdkuilib.repository.SdkUpdaterWindow;
import com.android.sdkuilib.repository.SdkUpdaterWindow.SdkInvocationContext;
@@ -313,9 +312,7 @@
if (sdk != null) {
sdk.unloadTargetData(true /*preventReload*/);
-
- DexWrapper dx = sdk.getDexWrapper();
- dx.unload();
+ sdk.unloadDexWrappers();
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java
index fa878cf..806fa9c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java
@@ -17,12 +17,14 @@
package com.android.ide.eclipse.adt.internal.build;
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.io.FileOp;
@@ -81,8 +83,9 @@
// "^\\s*interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{.*)?$");
- public AidlProcessor(IJavaProject javaProject, IFolder genFolder) {
- super(javaProject, genFolder);
+ public AidlProcessor(@NonNull IJavaProject javaProject, @NonNull BuildToolInfo buildToolInfo,
+ @NonNull IFolder genFolder) {
+ super(javaProject, buildToolInfo, genFolder);
}
@Override
@@ -95,7 +98,6 @@
return PROPERTY_COMPILE_AIDL;
}
- @SuppressWarnings("deprecation")
@Override
protected void doCompileFiles(List<IFile> sources, BaseBuilder builder,
IProject project, IAndroidTarget projectTarget,
@@ -104,7 +106,7 @@
// create the command line
List<String> commandList = new ArrayList<String>(
4 + sourceFolders.size() + libraryProjectsOut.size());
- commandList.add(projectTarget.getPath(IAndroidTarget.AIDL));
+ commandList.add(getBuildToolInfo().getPath(BuildToolInfo.PathId.AIDL));
commandList.add(quote("-p" + projectTarget.getPath(IAndroidTarget.ANDROID_AIDL))); //$NON-NLS-1$
// since the path are relative to the workspace and not the project itself, we need
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
index c94ef9a..da8c2ea 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
@@ -27,6 +27,7 @@
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
import com.android.sdklib.build.ApkBuilder;
@@ -105,8 +106,13 @@
private static final String COMMAND_CRUNCH = "crunch"; //$NON-NLS-1$
private static final String COMMAND_PACKAGE = "package"; //$NON-NLS-1$
+ @NonNull
private final IProject mProject;
+ @NonNull
+ private final BuildToolInfo mBuildToolInfo;
+ @NonNull
private final AndroidPrintStream mOutStream;
+ @NonNull
private final AndroidPrintStream mErrStream;
private final boolean mForceJumbo;
private final boolean mDisableDexMerger;
@@ -139,11 +145,13 @@
* @throws CoreException
*/
public BuildHelper(@NonNull IProject project,
+ @NonNull BuildToolInfo buildToolInfo,
@NonNull AndroidPrintStream outStream,
@NonNull AndroidPrintStream errStream,
boolean forceJumbo, boolean disableDexMerger, boolean debugMode,
boolean verbose, ResourceMarker resMarker) throws CoreException {
mProject = project;
+ mBuildToolInfo = buildToolInfo;
mOutStream = outStream;
mErrStream = errStream;
mDebugMode = debugMode;
@@ -693,7 +701,7 @@
// get the dex wrapper
Sdk sdk = Sdk.getCurrent();
- DexWrapper wrapper = sdk.getDexWrapper();
+ DexWrapper wrapper = sdk.getDexWrapper(mBuildToolInfo);
if (wrapper == null) {
throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
@@ -833,7 +841,7 @@
String configFilter, int versionCode) throws AaptExecException, AaptResultException {
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
- @SuppressWarnings("deprecation") String aapt = target.getPath(IAndroidTarget.AAPT);
+ String aapt = mBuildToolInfo.getPath(BuildToolInfo.PathId.AAPT);
// Create the command line.
ArrayList<String> commandArray = new ArrayList<String>();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptProcessor.java
index 2652866..af58e41 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptProcessor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptProcessor.java
@@ -17,6 +17,7 @@
package com.android.ide.eclipse.adt.internal.build;
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
@@ -25,6 +26,7 @@
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.ResourceFolderType;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.google.common.collect.Sets;
@@ -145,8 +147,9 @@
private int mTargetApi = 11;
- public RenderScriptProcessor(IJavaProject javaProject, IFolder genFolder) {
- super(javaProject, genFolder, new RsChangeHandler());
+ public RenderScriptProcessor(@NonNull IJavaProject javaProject,
+ @NonNull BuildToolInfo buildToolInfo, @NonNull IFolder genFolder) {
+ super(javaProject, buildToolInfo, genFolder, new RsChangeHandler());
}
public void setTargetApi(int targetApi) {
@@ -164,7 +167,6 @@
return PROPERTY_COMPILE_RS;
}
- @SuppressWarnings("deprecation")
@Override
protected void doCompileFiles(List<IFile> sources, BaseBuilder builder,
IProject project, IAndroidTarget projectTarget,
@@ -186,9 +188,9 @@
command[index++] = quote(sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER
+ SdkConstants.FN_RENDERSCRIPT);
command[index++] = "-I"; //$NON-NLS-1$
- command[index++] = quote(projectTarget.getPath(IAndroidTarget.ANDROID_RS_CLANG));
+ command[index++] = quote(getBuildToolInfo().getPath(BuildToolInfo.PathId.ANDROID_RS_CLANG));
command[index++] = "-I"; //$NON-NLS-1$
- command[index++] = quote(projectTarget.getPath(IAndroidTarget.ANDROID_RS));
+ command[index++] = quote(getBuildToolInfo().getPath(BuildToolInfo.PathId.ANDROID_RS));
command[index++] = "-p"; //$NON-NLS-1$
command[index++] = quote(genFolder.getLocation().toOSString());
command[index++] = "-o"; //$NON-NLS-1$
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java
index 4ecb91d..a82d54d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java
@@ -17,9 +17,11 @@
package com.android.ide.eclipse.adt.internal.build;
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import org.eclipse.core.resources.IFile;
@@ -59,6 +61,7 @@
private final Map<IFile, SourceFileData> mFiles = new HashMap<IFile, SourceFileData>();
private final IJavaProject mJavaProject;
+ private BuildToolInfo mBuildToolInfo;
private final IFolder mGenFolder;
private final SourceChangeHandler mDeltaVisitor;
@@ -83,9 +86,11 @@
return path;
}
- protected SourceProcessor(IJavaProject javaProject, IFolder genFolder,
- SourceChangeHandler deltaVisitor) {
+ protected SourceProcessor(@NonNull IJavaProject javaProject,
+ @NonNull BuildToolInfo buildToolInfo, @NonNull IFolder genFolder,
+ @NonNull SourceChangeHandler deltaVisitor) {
mJavaProject = javaProject;
+ mBuildToolInfo = buildToolInfo;
mGenFolder = genFolder;
mDeltaVisitor = deltaVisitor;
@@ -109,8 +114,13 @@
}
}
- protected SourceProcessor(IJavaProject javaProject, IFolder genFolder) {
- this(javaProject, genFolder, new SourceChangeHandler());
+ protected SourceProcessor(@NonNull IJavaProject javaProject,
+ @NonNull BuildToolInfo buildToolInfo, @NonNull IFolder genFolder) {
+ this(javaProject, buildToolInfo, genFolder, new SourceChangeHandler());
+ }
+
+ public void setBuildToolInfo(BuildToolInfo buildToolInfo) {
+ mBuildToolInfo = buildToolInfo;
}
@@ -168,6 +178,10 @@
return mJavaProject;
}
+ final BuildToolInfo getBuildToolInfo() {
+ return mBuildToolInfo;
+ }
+
final IFolder getGenFolder() {
return mGenFolder;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
index f58af56..1cbf7f2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
@@ -16,19 +16,24 @@
package com.android.ide.eclipse.adt.internal.build.builders;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.sdk.LoadStatus;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.build.BuildHelper;
import com.android.ide.eclipse.adt.internal.build.Messages;
+import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
+import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.io.IAbstractFile;
import com.android.io.StreamException;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import org.eclipse.core.resources.IContainer;
@@ -64,6 +69,13 @@
private SAXParserFactory mParserFactory;
/**
+ * The build tool to use to build. This is guaranteed to be non null after a call to
+ * {@link #abortOnBadSetup(IJavaProject, ProjectState)} since this will throw if it can't be
+ * queried.
+ */
+ protected BuildToolInfo mBuildToolInfo;
+
+ /**
* Base Resource Delta Visitor to handle XML error
*/
protected static class BaseDeltaVisitor implements XmlErrorListener {
@@ -293,9 +305,11 @@
* display any errors.
*
* @param javaProject The {@link IJavaProject} being compiled.
+ * @param projectState the project state, optional. will be queried if null.
* @throws CoreException
*/
- protected void abortOnBadSetup(IJavaProject javaProject) throws AbortBuildException {
+ protected void abortOnBadSetup(@NonNull IJavaProject javaProject,
+ @Nullable ProjectState projectState) throws AbortBuildException, CoreException {
IProject iProject = javaProject.getProject();
// check if we have finished loading the project target.
Sdk sdk = Sdk.getCurrent();
@@ -303,8 +317,12 @@
throw new AbortBuildException();
}
+ if (projectState == null) {
+ projectState = Sdk.getProjectState(javaProject.getProject());
+ }
+
// get the target for the project
- IAndroidTarget target = sdk.getTarget(javaProject.getProject());
+ IAndroidTarget target = projectState.getTarget();
if (target == null) {
throw new AbortBuildException();
@@ -315,6 +333,20 @@
throw new AbortBuildException();
}
+ mBuildToolInfo = projectState.getBuildToolInfo();
+ if (mBuildToolInfo == null) {
+ mBuildToolInfo = sdk.getLatestBuildTool();
+
+ if (mBuildToolInfo == null) {
+ throw new AbortBuildException();
+ } else {
+ AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, iProject,
+ String.format("Using default Build Tools revision %s",
+ mBuildToolInfo.getRevision())
+ );
+ }
+ }
+
// abort if there are TARGET or ADT type markers
stopOnMarker(iProject, AdtConstants.MARKER_TARGET, IResource.DEPTH_ZERO,
false /*checkSeverity*/);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
index 6e3dce3..baeb154 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
@@ -341,7 +341,7 @@
// Top level check to make sure the build can move forward. Only do this after recording
// delta changes.
- abortOnBadSetup(javaProject);
+ abortOnBadSetup(javaProject, projectState);
// Get the output stream. Since the builder is created for the life of the
// project, they can be kept around.
@@ -369,7 +369,7 @@
if (DEBUG_LOG) {
AdtPlugin.log(IStatus.INFO, "%s running crunch!", project.getName());
}
- BuildHelper helper = new BuildHelper(project,
+ BuildHelper helper = new BuildHelper(project, mBuildToolInfo,
mOutStream, mErrStream,
false /*jumbo mode doesn't matter here*/,
false /*dex merger doesn't matter here*/,
@@ -484,7 +484,7 @@
AdtConstants.DEX_OPTIONS_DISABLE_MERGER);
Boolean dexMerger = Boolean.valueOf(dexMergerStr);
- BuildHelper helper = new BuildHelper(project,
+ BuildHelper helper = new BuildHelper(project, mBuildToolInfo,
mOutStream, mErrStream,
jumbo.booleanValue(),
dexMerger.booleanValue(),
@@ -913,8 +913,9 @@
}
@Override
- protected void abortOnBadSetup(IJavaProject javaProject) throws AbortBuildException {
- super.abortOnBadSetup(javaProject);
+ protected void abortOnBadSetup(IJavaProject javaProject, ProjectState projectState)
+ throws AbortBuildException, CoreException {
+ super.abortOnBadSetup(javaProject, projectState);
IProject iProject = getProject();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
index 0f0cbcc..ae6b3f5 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
@@ -47,6 +47,7 @@
import com.android.manifmerger.ManifestMerger;
import com.android.manifmerger.MergerLog;
import com.android.sdklib.AndroidVersion;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.internal.build.BuildConfigGenerator;
import com.android.sdklib.internal.build.SymbolLoader;
@@ -95,7 +96,6 @@
* </ul>
*
*/
-@SuppressWarnings("deprecation")
public class PreCompilerBuilder extends BaseBuilder {
/** This ID is used in plugin.xml and in each project's .project file.
@@ -144,6 +144,7 @@
*/
private DerivedProgressMonitor mDerivedProgressMonitor;
+ private AidlProcessor mAidlProcessor;
private RenderScriptProcessor mRenderScriptProcessor;
/**
@@ -276,7 +277,9 @@
IJavaProject javaProject = JavaCore.create(project);
// Top level check to make sure the build can move forward.
- abortOnBadSetup(javaProject);
+ abortOnBadSetup(javaProject, projectState);
+
+ setupSourceProcessors(javaProject, projectState);
// now we need to get the classpath list
List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(javaProject);
@@ -707,8 +710,8 @@
proguardFile = androidOutputFolder.getFile(AdtConstants.FN_AAPT_PROGUARD);
}
- handleResources(project, javaPackage, projectTarget, manifestFile, libProjects,
- isLibrary, proguardFile);
+ handleResources(project, javaPackage, projectTarget, manifestFile,
+ libProjects, isLibrary, proguardFile);
}
if (processorStatus == SourceProcessor.COMPILE_STATUS_NONE &&
@@ -796,18 +799,25 @@
mLastBuildConfigMode = v;
}
- IJavaProject javaProject = JavaCore.create(project);
-
- // load the source processors
- SourceProcessor aidlProcessor = new AidlProcessor(javaProject, mGenFolder);
- mRenderScriptProcessor = new RenderScriptProcessor(javaProject, mGenFolder);
- mProcessors.add(aidlProcessor);
- mProcessors.add(mRenderScriptProcessor);
} catch (Throwable throwable) {
AdtPlugin.log(throwable, "Failed to finish PrecompilerBuilder#startupOnInitialize()");
}
}
+ private void setupSourceProcessors(@NonNull IJavaProject javaProject,
+ @NonNull ProjectState projectState) {
+ if (mAidlProcessor == null) {
+ mAidlProcessor = new AidlProcessor(javaProject, mBuildToolInfo, mGenFolder);
+ mRenderScriptProcessor = new RenderScriptProcessor(javaProject, mBuildToolInfo,
+ mGenFolder);
+ mProcessors.add(mAidlProcessor);
+ mProcessors.add(mRenderScriptProcessor);
+ } else {
+ mAidlProcessor.setBuildToolInfo(mBuildToolInfo);
+ mRenderScriptProcessor.setBuildToolInfo(mBuildToolInfo);
+ }
+ }
+
@SuppressWarnings("deprecation")
private void handleBuildConfig(@SuppressWarnings("rawtypes") Map args)
throws IOException, CoreException {
@@ -916,7 +926,7 @@
outFile.getLocation().toFile(),
manifest.getLocation().toFile(),
libManifests,
- null /*injectAttributes*/) == false) {
+ null /*injectAttributes*/, null /*packageOverride*/) == false) {
if (errors.size() > 1) {
StringBuilder sb = new StringBuilder();
for (String s : errors) {
@@ -1054,7 +1064,7 @@
// launch aapt: create the command line
ArrayList<String> array = new ArrayList<String>();
- String aaptPath = projectTarget.getPath(IAndroidTarget.AAPT);
+ String aaptPath = mBuildToolInfo.getPath(BuildToolInfo.PathId.AAPT);
array.add(aaptPath);
array.add("package"); //$NON-NLS-1$
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
index 39f7d1f..770710d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
@@ -24,8 +24,6 @@
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
import com.android.utils.Pair;
import org.eclipse.core.resources.IFolder;
@@ -87,7 +85,7 @@
// check for existing target marker, in which case we abort.
// (this means: no SDK, no target, or unresolvable target.)
try {
- abortOnBadSetup(javaProject);
+ abortOnBadSetup(javaProject, null);
} catch (AbortBuildException e) {
return null;
}
@@ -129,13 +127,6 @@
return null;
}
- // check the project has a target
- IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
- if (projectTarget == null) {
- // no target. marker has been set by the container initializer: exit silently.
- return null;
- }
-
// check the 'gen' source folder is present
boolean hasGenSrcFolder = false; // whether the project has a 'gen' source folder setup
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
index 94c5299..9f69e41 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
@@ -272,6 +272,7 @@
int initialDepth = 0;
int replaceStart;
int replaceEnd;
+ boolean endWithNewline = false;
if (startNode == null || endNode == null) {
// Process the entire document
root = domDocument;
@@ -281,6 +282,11 @@
endNode = root;
replaceStart = 0;
replaceEnd = document.getLength();
+ try {
+ endWithNewline = replaceEnd > 0 && document.getChar(replaceEnd - 1) == '\n';
+ } catch (BadLocationException e) {
+ // Can't happen
+ }
} else {
root = DomUtilities.getCommonAncestor(startNode, endNode);
initialDepth = root != null ? DomUtilities.getDepth(root) - 1 : 0;
@@ -337,7 +343,8 @@
XmlFormatStyle style = guessStyle(model, domDocument);
XmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
String delimiter = TextUtilities.getDefaultLineDelimiter(document);
- XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, delimiter);
+ XmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style, delimiter);
+ printer.setEndWithNewline(endWithNewline);
if (indentationLevels != null) {
printer.setIndentationLevels(indentationLevels);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java
index d3b6803..d3f7ec8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java
@@ -82,6 +82,10 @@
if (document != null) {
EclipseXmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style,
lineSeparator);
+ if (xml.endsWith("\n")) { //$NON-NLS-1$
+ printer.setEndWithNewline(true);
+ }
+
StringBuilder sb = new StringBuilder(3 * xml.length() / 2);
printer.prettyPrint(-1, document, null, null, sb, false /*openTagOnly*/);
return sb.toString();
@@ -92,9 +96,9 @@
}
@NonNull
- public static String prettyPrint(@NonNull Node node) {
+ public static String prettyPrint(@NonNull Node node, boolean endWithNewline) {
return prettyPrint(node, EclipseXmlFormatPreferences.create(), XmlFormatStyle.get(node),
- null);
+ null, endWithNewline);
}
private static String getDefaultLineSeparator() {
@@ -122,8 +126,10 @@
@NonNull Node node,
@NonNull XmlFormatPreferences prefs,
@NonNull XmlFormatStyle style,
- @Nullable String lineSeparator) {
+ @Nullable String lineSeparator,
+ boolean endWithNewline) {
XmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style, lineSeparator);
+ printer.setEndWithNewline(endWithNewline);
StringBuilder sb = new StringBuilder(1000);
printer.prettyPrint(-1, node, null, null, sb, false /*openTagOnly*/);
String xml = sb.toString();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationChooser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationChooser.java
index c11268c..d4cc6df 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationChooser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationChooser.java
@@ -590,8 +590,13 @@
if (resFolder != null) {
mConfiguration.setEditedConfig(resFolder.getConfiguration());
} else {
- mConfiguration.setEditedConfig(FolderConfiguration.getConfig(
- parent.getName().split(RES_QUALIFIER_SEP)));
+ FolderConfiguration config = FolderConfiguration.getConfig(
+ parent.getName().split(RES_QUALIFIER_SEP));
+ if (config != null) {
+ mConfiguration.setEditedConfig(config);
+ } else {
+ mConfiguration.setEditedConfig(new FolderConfiguration());
+ }
}
onXmlModelLoaded();
@@ -745,8 +750,13 @@
if (resFolder != null) {
mConfiguration.setEditedConfig(resFolder.getConfiguration());
} else {
- mConfiguration.setEditedConfig(FolderConfiguration.getConfig(
- parent.getName().split(RES_QUALIFIER_SEP)));
+ FolderConfiguration config = FolderConfiguration.getConfig(
+ parent.getName().split(RES_QUALIFIER_SEP));
+ if (config != null) {
+ mConfiguration.setEditedConfig(config);
+ } else {
+ mConfiguration.setEditedConfig(new FolderConfiguration());
+ }
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
index d3c4fab..f5d3290 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
@@ -107,7 +107,7 @@
for (ConfigurationDescription description : mList) {
description.toXml(document);
}
- String xml = EclipseXmlPrettyPrinter.prettyPrint(document);
+ String xml = EclipseXmlPrettyPrinter.prettyPrint(document, true);
Files.write(xml, file, Charsets.UTF_8);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
index a775686..0e56bdf 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
@@ -356,7 +356,7 @@
String xml = EclipseXmlPrettyPrinter.prettyPrint(
tempDocument.getDocumentElement(),
EclipseXmlFormatPreferences.create(),
- XmlFormatStyle.LAYOUT, null);
+ XmlFormatStyle.LAYOUT, null, false);
TextEdit replace = new ReplaceEdit(mSelectionStart, mSelectionEnd - mSelectionStart, xml);
rootEdit.addChild(replace);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
index f3d6371..c526edf 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
@@ -586,7 +586,8 @@
// project that have been resolved before the sdk was loaded
// will have a ProjectState where the IAndroidTarget is null
// so we load the target now that the SDK is loaded.
- IAndroidTarget target = currentSdk.loadTarget(Sdk.getProjectState(iProject));
+ IAndroidTarget target = currentSdk.loadTargetAndBuildTools(
+ Sdk.getProjectState(iProject));
if (target == null) {
// this is really not supposed to happen. This would mean there are cached paths,
// but project.properties was deleted. Keep the project in the list to force
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
index d215f2f..52870a4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
@@ -31,6 +31,7 @@
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.build.ApkCreationException;
import com.android.sdklib.build.DuplicateFileException;
import com.android.sdklib.internal.project.ProjectProperties;
@@ -132,7 +133,17 @@
String dexMergerStr = projectState.getProperty(AdtConstants.DEX_OPTIONS_DISABLE_MERGER);
Boolean dexMerger = Boolean.valueOf(dexMergerStr);
- BuildHelper helper = new BuildHelper(project,
+ BuildToolInfo buildToolInfo = projectState.getBuildToolInfo();
+ if (buildToolInfo == null) {
+ buildToolInfo = Sdk.getCurrent().getLatestBuildTool();
+ }
+
+ if (buildToolInfo == null) {
+ throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "No Build Tools installed in the SDK."));
+ }
+
+ BuildHelper helper = new BuildHelper(project, buildToolInfo,
fakeStream, fakeStream,
jumbo.booleanValue(),
dexMerger.booleanValue(),
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java
index 64053ad..4628509 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java
@@ -19,6 +19,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
@@ -160,6 +161,7 @@
private final IProject mProject;
private final ProjectProperties mProperties;
private IAndroidTarget mTarget;
+ private BuildToolInfo mBuildToolInfo;
/**
* list of libraries. Access to this list must be protected by
@@ -240,6 +242,23 @@
return mTarget;
}
+ public void setBuildToolInfo(BuildToolInfo buildToolInfo) {
+ mBuildToolInfo = buildToolInfo;
+ }
+
+ public BuildToolInfo getBuildToolInfo() {
+ return mBuildToolInfo;
+ }
+
+ /**
+ * Returns the build tools version from the project's properties.
+ * @return the value or null
+ */
+ @Nullable
+ public String getBuildToolInfoVersion() {
+ return mProperties.getProperty(ProjectProperties.PROPERTY_BUILD_TOOLS);
+ }
+
public static class LibraryDifference {
public boolean removed = false;
public boolean added = false;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
index 16df952..74f08c2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -43,6 +43,7 @@
import com.android.io.StreamException;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.AndroidVersion;
+import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.devices.DeviceManager;
@@ -50,10 +51,13 @@
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
+import com.android.sdklib.repository.FullRevision;
import com.android.utils.ILogger;
+import com.google.common.collect.Maps;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -130,7 +134,7 @@
}
private final SdkManager mManager;
- private final DexWrapper mDexWrapper;
+ private final Map<String, DexWrapper> mDexWrappers = Maps.newHashMap();
private final AvdManager mAvdManager;
private final DeviceManager mDeviceManager;
@@ -265,17 +269,6 @@
// get an SdkManager object for the location
SdkManager manager = SdkManager.createManager(sdkLocation, log);
if (manager != null) {
- // load DX.
- DexWrapper dexWrapper = new DexWrapper();
- String dexLocation =
- sdkLocation + File.separator +
- SdkConstants.OS_SDK_PLATFORM_TOOLS_LIB_FOLDER + SdkConstants.FN_DX_JAR;
- IStatus res = dexWrapper.loadDex(dexLocation);
- if (res != Status.OK_STATUS) {
- log.error(null, res.getMessage());
- dexWrapper = null;
- }
-
// create the AVD Manager
AvdManager avdManager = null;
try {
@@ -283,7 +276,7 @@
} catch (AndroidLocationException e) {
log.error(e, "Error parsing the AVDs");
}
- sCurrentSdk = new Sdk(manager, dexWrapper, avdManager);
+ sCurrentSdk = new Sdk(manager, avdManager);
return sCurrentSdk;
} else {
StringBuilder sb = new StringBuilder("Error Loading the SDK:\n");
@@ -376,6 +369,24 @@
return mManager.getTargetFromHashString(hash);
}
+ @Nullable
+ public BuildToolInfo getBuildToolInfo(@Nullable String buildToolVersion) {
+ if (buildToolVersion != null) {
+ try {
+ return mManager.getBuildTool(FullRevision.parseRevision(buildToolVersion));
+ } catch (Exception e) {
+ // ignore, return null below.
+ }
+ }
+
+ return null;
+ }
+
+ @Nullable
+ public BuildToolInfo getLatestBuildTool() {
+ return mManager.getLatestBuildTool(false /*isPreview*/);
+ }
+
/**
* Initializes a new project with a target. This creates the <code>project.properties</code>
* file.
@@ -487,7 +498,7 @@
// try to resolve the target
if (AdtPlugin.getDefault().getSdkLoadStatus() == LoadStatus.LOADED) {
- sCurrentSdk.loadTarget(state);
+ sCurrentSdk.loadTargetAndBuildTools(state);
}
}
@@ -513,26 +524,84 @@
}
/**
- * Loads the {@link IAndroidTarget} for a given project.
+ * Loads the {@link IAndroidTarget} and BuildTools for a given project.
* <p/>This method will get the target hash string from the project properties, and resolve
* it to an {@link IAndroidTarget} object and store it inside the {@link ProjectState}.
* @param state the state representing the project to load.
* @return the target that was loaded.
*/
@Nullable
- public IAndroidTarget loadTarget(ProjectState state) {
+ public IAndroidTarget loadTargetAndBuildTools(ProjectState state) {
IAndroidTarget target = null;
if (state != null) {
String hash = state.getTargetHashString();
if (hash != null) {
state.setTarget(target = getTargetFromHashString(hash));
}
+
+ String markerMessage = null;
+ String buildToolInfoVersion = state.getBuildToolInfoVersion();
+ if (buildToolInfoVersion != null) {
+ BuildToolInfo buildToolsInfo = getBuildToolInfo(buildToolInfoVersion);
+
+ if (buildToolsInfo != null) {
+ state.setBuildToolInfo(buildToolsInfo);
+ } else {
+ markerMessage = String.format("Unable to resolve %s property value '%s'",
+ ProjectProperties.PROPERTY_BUILD_TOOLS,
+ buildToolInfoVersion);
+ }
+ } else {
+ // this is ok, we'll use the latest one automatically.
+ state.setBuildToolInfo(null);
+ }
+
+ handleBuildToolsMarker(state.getProject(), markerMessage);
}
return target;
}
/**
+ * Adds or edit a build tools marker from the given project. This is done through a Job.
+ * @param project the project
+ * @param markerMessage the message. if null the marker is removed.
+ */
+ private void handleBuildToolsMarker(final IProject project, final String markerMessage) {
+ Job markerJob = new Job("Android SDK: Build Tools Marker") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ if (project.isAccessible()) {
+ // always delete existing marker first
+ project.deleteMarkers(AdtConstants.MARKER_BUILD_TOOLS, true,
+ IResource.DEPTH_ZERO);
+
+ // add the new one if needed.
+ if (markerMessage != null) {
+ BaseProjectHelper.markProject(project,
+ AdtConstants.MARKER_BUILD_TOOLS,
+ markerMessage, IMarker.SEVERITY_ERROR,
+ IMarker.PRIORITY_HIGH);
+ }
+ }
+ } catch (CoreException e2) {
+ AdtPlugin.log(e2, null);
+ // Don't return e2.getStatus(); the job control will then produce
+ // a popup with this error, which isn't very interesting for the
+ // user.
+ }
+
+ return Status.OK_STATUS;
+ }
+ };
+
+ // build jobs are run after other interactive jobs
+ markerJob.setPriority(Job.BUILD);
+ markerJob.schedule();
+ }
+
+ /**
* Checks and loads (if needed) the data for a given target.
* <p/> The data is loaded in a separate {@link Job}, and opened editors will be notified
* through their implementation of {@link ITargetChangeListener#onTargetLoaded(IAndroidTarget)}.
@@ -668,8 +737,38 @@
* Returns a {@link DexWrapper} object to be used to execute dx commands. If dx.jar was not
* loaded properly, then this will return <code>null</code>.
*/
- public DexWrapper getDexWrapper() {
- return mDexWrapper;
+ @Nullable
+ public DexWrapper getDexWrapper(@Nullable BuildToolInfo buildToolInfo) {
+ if (buildToolInfo == null) {
+ return null;
+ }
+ synchronized (LOCK) {
+ String dexLocation = buildToolInfo.getPath(BuildToolInfo.PathId.DX_JAR);
+ DexWrapper dexWrapper = mDexWrappers.get(dexLocation);
+
+ if (dexWrapper == null) {
+ // load DX.
+ dexWrapper = new DexWrapper();
+ IStatus res = dexWrapper.loadDex(dexLocation);
+ if (res != Status.OK_STATUS) {
+ AdtPlugin.log(null, res.getMessage());
+ dexWrapper = null;
+ } else {
+ mDexWrappers.put(dexLocation, dexWrapper);
+ }
+ }
+
+ return dexWrapper;
+ }
+ }
+
+ public void unloadDexWrappers() {
+ synchronized (LOCK) {
+ for (DexWrapper wrapper : mDexWrappers.values()) {
+ wrapper.unload();
+ }
+ mDexWrappers.clear();
+ }
}
/**
@@ -763,9 +862,8 @@
}
}
- private Sdk(SdkManager manager, DexWrapper dexWrapper, AvdManager avdManager) {
+ private Sdk(SdkManager manager, AvdManager avdManager) {
mManager = manager;
- mDexWrapper = dexWrapper;
mAvdManager = avdManager;
// listen to projects closing
@@ -787,8 +885,7 @@
// update whatever ProjectState is already present with new IAndroidTarget objects.
synchronized (LOCK) {
for (Entry<IProject, ProjectState> entry: sProjectStateMap.entrySet()) {
- entry.getValue().setTarget(
- getTargetFromHashString(entry.getValue().getTargetHashString()));
+ loadTargetAndBuildTools(entry.getValue());
}
}
}
@@ -1042,7 +1139,7 @@
ProjectState state = Sdk.getProjectState(iProject);
- // get the current target
+ // get the current target and build tools
IAndroidTarget oldTarget = state.getTarget();
// get the current library flag
@@ -1051,7 +1148,7 @@
LibraryDifference diff = state.reloadProperties();
// load the (possibly new) target.
- IAndroidTarget newTarget = loadTarget(state);
+ IAndroidTarget newTarget = loadTargetAndBuildTools(state);
// reload the libraries if needed
if (diff.hasDiff()) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
index eb3d94a..bd9c0fa 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
@@ -706,7 +706,8 @@
if (ok) {
if (modified) {
contents = EclipseXmlPrettyPrinter.prettyPrint(currentDocument,
- EclipseXmlFormatPreferences.create(), formatStyle, null);
+ EclipseXmlFormatPreferences.create(), formatStyle, null,
+ currentXml.endsWith("\n")); //$NON-NLS-1$
}
} else {
// Just insert into file along with comment, using the "standard" conflict
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
index 8fc8dd1..ac5fd01 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
@@ -63,6 +63,7 @@
XmlFormatStyle style = AndroidXmlFormattingStrategy.guessStyle(model, document);
EclipseXmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style, delimiter);
+ printer.setEndWithNewline(xml.endsWith("\n"));
StringBuilder sb = new StringBuilder(1000);
Node startNode = document;
@@ -180,7 +181,7 @@
" <item name=\"title_container\" type=\"id\"/>\n" +
" <item name=\"title_logo\" type=\"id\"/>\n" +
"\n" +
- "</resources>");
+ "</resources>\n");
}
public void testResources() throws Exception {
@@ -876,7 +877,7 @@
" <string name=\"untitled2\"><untitled2></string>\n" +
" <string name=\"untitled3\">'untitled3"</string>\n" +
"\n" +
- "</resources>");
+ "</resources>\n");
}
public void testCData1() throws Exception {
@@ -954,4 +955,24 @@
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\" />\n");
}
+
+ public void testPreserveLastNewline() throws Exception {
+ checkFormat(
+ "res/values/strings.xml",
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<resources>\n" +
+ "<string name=\"progress_completed_export_all\">The database has " +
+ "<b>successfully</b> been exported into: <br /><br /><font size=\"14\">" +
+ "\\\"<i>%s</i>\\\"</font></string>" +
+ "</resources>\n",
+
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<resources>\n" +
+ "\n" +
+ " <string name=\"progress_completed_export_all\">The database has " +
+ "<b>successfully</b> been exported into: <br /><br /><font size=\"14\">" +
+ "\\\"<i>%s</i>\\\"</font></string>\n" +
+ "\n" +
+ "</resources>\n");
+ }
}
diff --git a/eclipse/scripts/build_ide.sh b/eclipse/scripts/build_ide.sh
index 0b080d8..50125cf 100755
--- a/eclipse/scripts/build_ide.sh
+++ b/eclipse/scripts/build_ide.sh
@@ -4,6 +4,11 @@
# $2 = ide qualifier
# $3 = zip qualifier
+if [[ "Linux" != $(uname) ]]; then
+ echo "$0: ADT IDE build script runs only on Linux"
+ exit 0
+fi
+
PROG_DIR=$(dirname "$0")
DEST_DIR="$1"
diff --git a/eclipse/scripts/build_server.sh b/eclipse/scripts/build_server.sh
index da7184a..4efd609 100755
--- a/eclipse/scripts/build_server.sh
+++ b/eclipse/scripts/build_server.sh
@@ -111,9 +111,7 @@
}
function build_adt_ide() {
- # Build the ADT IDE if this runs on Linux.
- # Qualifier for the zip files is just the build number if available.
- if [[ -z $INTERNAL_BUILD && "Linux" == $(uname) ]]; then
+ if [[ -z $INTERNAL_BUILD ]]; then
# This needs to run from the top android directory
D="$PROG_DIR"
cd "$D/../../../" && echo "Switched to directory $PWD"
diff --git a/files/ant/build.xml b/files/ant/build.xml
index efe6b7d..b50363a 100644
--- a/files/ant/build.xml
+++ b/files/ant/build.xml
@@ -154,18 +154,8 @@
<condition property="bat" value=".bat" else=""><os family="windows" /></condition>
<property name="adb" location="${android.platform.tools.dir}/adb${exe}" />
<property name="zipalign" location="${android.tools.dir}/zipalign${exe}" />
- <property name="aidl" location="${android.platform.tools.dir}/aidl${exe}" />
- <property name="aapt" location="${android.platform.tools.dir}/aapt${exe}" />
- <property name="dx" location="${android.platform.tools.dir}/dx${bat}" />
- <property name="renderscript" location="${android.platform.tools.dir}/llvm-rs-cc${exe}"/>
<property name="lint" location="${android.tools.dir}/lint${bat}" />
- <!-- Renderscript include Path -->
- <path id="android.renderscript.include.path">
- <pathelement location="${android.platform.tools.dir}/renderscript/include" />
- <pathelement location="${android.platform.tools.dir}/renderscript/clang-include" />
- </path>
-
<!-- Intermediate files -->
<property name="dex.file.name" value="classes.dex" />
<property name="intermediate.dex.file" location="${out.absolute.dir}/${dex.file.name}" />
@@ -484,6 +474,18 @@
<!-- Pre build setup -->
<target name="-build-setup" depends="-setup">
+ <!-- find location of build tools -->
+ <getbuildtools name="android.build.tools.dir" />
+ <property name="aidl" location="${android.build.tools.dir}/aidl${exe}" />
+ <property name="aapt" location="${android.build.tools.dir}/aapt${exe}" />
+ <property name="dx" location="${android.build.tools.dir}/dx${bat}" />
+ <property name="renderscript" location="${android.build.tools.dir}/llvm-rs-cc${exe}"/>
+
+ <!-- Renderscript include Path -->
+ <path id="android.renderscript.include.path">
+ <pathelement location="${android.platform.tools.dir}/renderscript/include" />
+ <pathelement location="${android.platform.tools.dir}/renderscript/clang-include" />
+ </path>
<!-- read the previous build mode -->
<property file="${out.build.prop.file}" />
diff --git a/files/ant/uibuild.xml b/files/ant/uibuild.xml
index 93782ba..788ca77 100644
--- a/files/ant/uibuild.xml
+++ b/files/ant/uibuild.xml
@@ -94,7 +94,6 @@
<condition property="exe" value=".exe" else=""><os family="windows" /></condition>
<condition property="bat" value=".bat" else=""><os family="windows" /></condition>
<property name="adb" location="${android.platform.tools.dir}/adb${exe}" />
- <property name="dx" location="${android.platform.tools.dir}/dx${bat}" />
<!-- Intermediate files -->
<property name="dex.file.name" value="classes.dex" />
@@ -153,6 +152,8 @@
<!-- Pre build setup -->
<target name="-build-setup" depends="-check-env">
+ <getbuildtools name="android.build.tools.dir" />
+ <property name="dx" location="${android.build.tools.dir}/dx${bat}" />
<echo level="info">Resolving Build Target for ${ant.project.name}...</echo>
<!-- load project properties, resolve Android target, library dependencies