auto import from //branches/cupcake/...@132276
This commit is contained in:
@@ -20,7 +20,6 @@ import com.android.ddmuilib.StackTracePanel;
|
||||
import com.android.ddmuilib.StackTracePanel.ISourceRevealer;
|
||||
import com.android.ddmuilib.console.DdmConsole;
|
||||
import com.android.ddmuilib.console.IDdmConsole;
|
||||
import com.android.ide.eclipse.adt.build.DexWrapper;
|
||||
import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController;
|
||||
import com.android.ide.eclipse.adt.preferences.BuildPreferencePage;
|
||||
import com.android.ide.eclipse.adt.project.ProjectHelper;
|
||||
@@ -423,8 +422,6 @@ public class AdtPlugin extends AbstractUIPlugin {
|
||||
|
||||
stopEditors();
|
||||
|
||||
DexWrapper.unloadDex();
|
||||
|
||||
mRed.dispose();
|
||||
synchronized (AdtPlugin.class) {
|
||||
sPlugin = null;
|
||||
@@ -465,21 +462,11 @@ public class AdtPlugin extends AbstractUIPlugin {
|
||||
return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_ADB;
|
||||
}
|
||||
|
||||
/** Returns the aapt path relative to the sdk folder */
|
||||
public static String getOsRelativeAapt() {
|
||||
return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_AAPT;
|
||||
}
|
||||
|
||||
/** Returns the emulator path relative to the sdk folder */
|
||||
public static String getOsRelativeEmulator() {
|
||||
return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_EMULATOR;
|
||||
}
|
||||
|
||||
/** Returns the aidl path relative to the sdk folder */
|
||||
public static String getOsRelativeAidl() {
|
||||
return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_AIDL;
|
||||
}
|
||||
|
||||
/** Returns the absolute adb path */
|
||||
public static String getOsAbsoluteAdb() {
|
||||
return getOsSdkFolder() + getOsRelativeAdb();
|
||||
@@ -491,21 +478,11 @@ public class AdtPlugin extends AbstractUIPlugin {
|
||||
AndroidConstants.FN_TRACEVIEW;
|
||||
}
|
||||
|
||||
/** Returns the absolute aapt path */
|
||||
public static String getOsAbsoluteAapt() {
|
||||
return getOsSdkFolder() + getOsRelativeAapt();
|
||||
}
|
||||
|
||||
/** Returns the absolute emulator path */
|
||||
public static String getOsAbsoluteEmulator() {
|
||||
return getOsSdkFolder() + getOsRelativeEmulator();
|
||||
}
|
||||
|
||||
/** Returns the absolute aidl path */
|
||||
public static String getOsAbsoluteAidl() {
|
||||
return getOsSdkFolder() + getOsRelativeAidl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Url file path to the javaDoc folder.
|
||||
*/
|
||||
@@ -968,8 +945,6 @@ public class AdtPlugin extends AbstractUIPlugin {
|
||||
// check the path to various tools we use
|
||||
String[] filesToCheck = new String[] {
|
||||
osSdkLocation + getOsRelativeAdb(),
|
||||
osSdkLocation + getOsRelativeAapt(),
|
||||
osSdkLocation + getOsRelativeAidl(),
|
||||
osSdkLocation + getOsRelativeEmulator()
|
||||
};
|
||||
for (String file : filesToCheck) {
|
||||
@@ -1058,17 +1033,6 @@ public class AdtPlugin extends AbstractUIPlugin {
|
||||
// FIXME: move this per platform, or somewhere else.
|
||||
progress = SubMonitor.convert(monitor,
|
||||
Messages.AdtPlugin_Parsing_Resources, 20);
|
||||
DexWrapper.unloadDex();
|
||||
|
||||
IStatus res = DexWrapper.loadDex(
|
||||
mOsSdkLocation + AndroidConstants.OS_SDK_LIBS_DX_JAR);
|
||||
if (res != Status.OK_STATUS) {
|
||||
synchronized (getSdkLockObject()) {
|
||||
mSdkIsLoaded = LoadStatus.FAILED;
|
||||
mPostLoadProjectsToResolve.clear();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
synchronized (getSdkLockObject()) {
|
||||
mSdkIsLoaded = LoadStatus.LOADED;
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.android.ide.eclipse.adt.build;
|
||||
import com.android.ide.eclipse.adt.AdtConstants;
|
||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||
import com.android.ide.eclipse.adt.project.ProjectHelper;
|
||||
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
||||
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
|
||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||
import com.android.ide.eclipse.common.AndroidConstants;
|
||||
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
||||
@@ -67,6 +67,8 @@ import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ApkBuilder extends BaseBuilder {
|
||||
|
||||
@@ -280,8 +282,12 @@ public class ApkBuilder extends BaseBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// also check the final file!
|
||||
String finalPackageName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
|
||||
// get the extra configs for the project. This will give us a list of custom apk
|
||||
// to build based on a restricted set of resources.
|
||||
Map<String, String> configs = Sdk.getCurrent().getProjectConfigs(project);
|
||||
|
||||
// also check the final file(s)!
|
||||
String finalPackageName = getFileName(project, null /*config*/);
|
||||
if (mBuildFinalPackage == false && outputFolder != null) {
|
||||
tmp = outputFolder.findMember(finalPackageName);
|
||||
if (tmp == null || (tmp instanceof IFile &&
|
||||
@@ -290,6 +296,24 @@ public class ApkBuilder extends BaseBuilder {
|
||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
||||
mBuildFinalPackage = true;
|
||||
}
|
||||
|
||||
if (configs != null) {
|
||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
||||
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
String filename = getFileName(project, entry.getKey());
|
||||
|
||||
tmp = outputFolder.findMember(filename);
|
||||
if (tmp == null || (tmp instanceof IFile &&
|
||||
tmp.exists() == false)) {
|
||||
String msg = String.format(Messages.s_Missing_Repackaging,
|
||||
finalPackageName);
|
||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
||||
mBuildFinalPackage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// store the build status in the persistent storage
|
||||
@@ -358,6 +382,17 @@ public class ApkBuilder extends BaseBuilder {
|
||||
// handle already present .apk, and if that one failed as well, the user will be
|
||||
// notified.
|
||||
finalPackage.delete();
|
||||
|
||||
if (configs != null) {
|
||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
String packageFilepath = osBinPath + File.separator +
|
||||
getFileName(project, entry.getKey());
|
||||
|
||||
finalPackage = new File(packageFilepath);
|
||||
finalPackage.delete();
|
||||
}
|
||||
}
|
||||
|
||||
// first we check if we need to package the resources.
|
||||
if (mPackageResources) {
|
||||
@@ -401,13 +436,30 @@ public class ApkBuilder extends BaseBuilder {
|
||||
osAssetsPath = assetsFolder.getLocation().toOSString();
|
||||
}
|
||||
|
||||
// build the default resource package
|
||||
if (executeAapt(project, osManifestPath, osResPath,
|
||||
osAssetsPath, osBinPath + File.separator +
|
||||
AndroidConstants.FN_RESOURCES_AP_) == false) {
|
||||
AndroidConstants.FN_RESOURCES_AP_, null /*configFilter*/) == false) {
|
||||
// aapt failed. Whatever files that needed to be marked
|
||||
// have already been marked. We just return.
|
||||
return referencedProjects;
|
||||
}
|
||||
|
||||
// now do the same thing for all the configured resource packages.
|
||||
if (configs != null) {
|
||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
String outPathFormat = osBinPath + File.separator +
|
||||
AndroidConstants.FN_RESOURCES_S_AP_;
|
||||
String outPath = String.format(outPathFormat, entry.getKey());
|
||||
if (executeAapt(project, osManifestPath, osResPath,
|
||||
osAssetsPath, outPath, entry.getValue()) == false) {
|
||||
// aapt failed. Whatever files that needed to be marked
|
||||
// have already been marked. We just return.
|
||||
return referencedProjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build has been done. reset the state of the builder
|
||||
mPackageResources = false;
|
||||
@@ -433,25 +485,49 @@ public class ApkBuilder extends BaseBuilder {
|
||||
}
|
||||
|
||||
// now we need to make the final package from the intermediary apk
|
||||
// and classes.dex
|
||||
// and classes.dex.
|
||||
// This is the default package with all the resources.
|
||||
|
||||
String classesDexPath = osBinPath + File.separator + AndroidConstants.FN_CLASSES_DEX;
|
||||
if (finalPackage(osBinPath + File.separator + AndroidConstants.FN_RESOURCES_AP_,
|
||||
osBinPath + File.separator + AndroidConstants.FN_CLASSES_DEX,
|
||||
osFinalPackagePath, javaProject, referencedJavaProjects) == false) {
|
||||
classesDexPath,osFinalPackagePath, javaProject,
|
||||
referencedJavaProjects) == false) {
|
||||
return referencedProjects;
|
||||
} else {
|
||||
// get the resource to bin
|
||||
outputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
|
||||
|
||||
// build has been done. reset the state of the builder
|
||||
mBuildFinalPackage = false;
|
||||
|
||||
// and store it
|
||||
saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
|
||||
|
||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
|
||||
"Build Success!");
|
||||
}
|
||||
|
||||
// now do the same thing for all the configured resource packages.
|
||||
if (configs != null) {
|
||||
String resPathFormat = osBinPath + File.separator +
|
||||
AndroidConstants.FN_RESOURCES_S_AP_;
|
||||
|
||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
// make the filename for the resource package.
|
||||
String resPath = String.format(resPathFormat, entry.getKey());
|
||||
|
||||
// make the filename for the apk to generate
|
||||
String apkOsFilePath = osBinPath + File.separator +
|
||||
getFileName(project, entry.getKey());
|
||||
if (finalPackage(resPath, classesDexPath, apkOsFilePath, javaProject,
|
||||
referencedJavaProjects) == false) {
|
||||
return referencedProjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we are done.
|
||||
|
||||
// get the resource to bin
|
||||
outputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
|
||||
|
||||
// build has been done. reset the state of the builder
|
||||
mBuildFinalPackage = false;
|
||||
|
||||
// and store it
|
||||
saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
|
||||
|
||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
|
||||
"Build Success!");
|
||||
}
|
||||
return referencedProjects;
|
||||
}
|
||||
@@ -475,19 +551,26 @@ public class ApkBuilder extends BaseBuilder {
|
||||
* @param osResPath The path to the res folder
|
||||
* @param osAssetsPath The path to the assets folder. This can be null.
|
||||
* @param osOutFilePath The path to the temporary resource file to create.
|
||||
* @param configFilter The configuration filter for the resources to include
|
||||
* (used with -c option)
|
||||
* @return true if success, false otherwise.
|
||||
*/
|
||||
private boolean executeAapt(IProject project, String osManifestPath,
|
||||
String osResPath, String osAssetsPath, String osOutFilePath) {
|
||||
String osResPath, String osAssetsPath, String osOutFilePath, String configFilter) {
|
||||
IAndroidTarget target = Sdk.getCurrent().getTarget(project);
|
||||
|
||||
// Create the command line.
|
||||
ArrayList<String> commandArray = new ArrayList<String>();
|
||||
commandArray.add(AdtPlugin.getOsAbsoluteAapt());
|
||||
commandArray.add(target.getPath(IAndroidTarget.AAPT));
|
||||
commandArray.add("package"); //$NON-NLS-1$
|
||||
commandArray.add("-f");//$NON-NLS-1$
|
||||
if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
|
||||
commandArray.add("-v"); //$NON-NLS-1$
|
||||
}
|
||||
if (configFilter != null) {
|
||||
commandArray.add("-c"); //$NON-NLS-1$
|
||||
commandArray.add(configFilter);
|
||||
}
|
||||
commandArray.add("-M"); //$NON-NLS-1$
|
||||
commandArray.add(osManifestPath);
|
||||
commandArray.add("-S"); //$NON-NLS-1$
|
||||
@@ -497,8 +580,7 @@ public class ApkBuilder extends BaseBuilder {
|
||||
commandArray.add(osAssetsPath);
|
||||
}
|
||||
commandArray.add("-I"); //$NON-NLS-1$
|
||||
commandArray.add(
|
||||
Sdk.getCurrent().getTarget(project).getPath(IAndroidTarget.ANDROID_JAR));
|
||||
commandArray.add(target.getPath(IAndroidTarget.ANDROID_JAR));
|
||||
commandArray.add("-F"); //$NON-NLS-1$
|
||||
commandArray.add(osOutFilePath);
|
||||
|
||||
@@ -576,14 +658,19 @@ public class ApkBuilder extends BaseBuilder {
|
||||
*/
|
||||
private boolean executeDx(IJavaProject javaProject, String osBinPath, String osOutFilePath,
|
||||
IJavaProject[] referencedJavaProjects) throws CoreException {
|
||||
IAndroidTarget target = Sdk.getCurrent().getTarget(javaProject.getProject());
|
||||
AndroidTargetData targetData = Sdk.getCurrent().getTargetData(target);
|
||||
if (targetData == null) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
|
||||
Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
|
||||
}
|
||||
|
||||
// get the dex wrapper
|
||||
DexWrapper wrapper = DexWrapper.getWrapper();
|
||||
DexWrapper wrapper = targetData.getDexWrapper();
|
||||
|
||||
if (wrapper == null) {
|
||||
if (DexWrapper.getStatus() == LoadStatus.FAILED) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
|
||||
Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
|
||||
}
|
||||
throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
|
||||
Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
|
||||
}
|
||||
|
||||
// make sure dx use the proper output streams.
|
||||
@@ -1003,6 +1090,19 @@ public class ApkBuilder extends BaseBuilder {
|
||||
|
||||
return list.toArray(new IJavaProject[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the apk filename for the given project
|
||||
* @param project The project.
|
||||
* @param config An optional config name. Can be null.
|
||||
*/
|
||||
private static String getFileName(IProject project, String config) {
|
||||
if (config != null) {
|
||||
return project.getName() + "-" + config + AndroidConstants.DOT_ANDROID_PACKAGE; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a {@link IFile} to make sure it should be packaged as standard resources.
|
||||
|
||||
@@ -192,11 +192,16 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor
|
||||
IPath parentPath = path.removeLastSegments(1);
|
||||
if (mOutputPath.equals(parentPath)) {
|
||||
String resourceName = resource.getName();
|
||||
// check if classes.dex was removed
|
||||
if (resourceName.equalsIgnoreCase(AndroidConstants.FN_CLASSES_DEX)) {
|
||||
mConvertToDex = true;
|
||||
mMakeFinalPackage = true;
|
||||
} else if (resourceName.equalsIgnoreCase(
|
||||
AndroidConstants.FN_RESOURCES_AP_)) {
|
||||
AndroidConstants.FN_RESOURCES_AP_) ||
|
||||
AndroidConstants.PATTERN_RESOURCES_S_AP_.matcher(
|
||||
resourceName).matches()) {
|
||||
// or if the default resources.ap_ or a configured version
|
||||
// (resources-###.ap_) was removed.
|
||||
mPackageResources = true;
|
||||
mMakeFinalPackage = true;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.ide.eclipse.adt.build;
|
||||
|
||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
@@ -46,10 +45,6 @@ public final class DexWrapper {
|
||||
|
||||
private final static String MAIN_RUN = "run"; //$NON-NLS-1$
|
||||
|
||||
private static DexWrapper sWrapper;
|
||||
|
||||
private static LoadStatus sLoadStatus = LoadStatus.LOADING;
|
||||
|
||||
private Method mRunMethod;
|
||||
|
||||
private Constructor<?> mArgConstructor;
|
||||
@@ -67,10 +62,8 @@ public final class DexWrapper {
|
||||
* @param osFilepath the location of the dex.jar file.
|
||||
* @return an IStatus indicating the result of the load.
|
||||
*/
|
||||
public static synchronized IStatus loadDex(String osFilepath) {
|
||||
public synchronized IStatus loadDex(String osFilepath) {
|
||||
try {
|
||||
sWrapper = null;
|
||||
|
||||
File f = new File(osFilepath);
|
||||
if (f.isFile() == false) {
|
||||
return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, String.format(
|
||||
@@ -86,44 +79,38 @@ public final class DexWrapper {
|
||||
Class<?> consoleClass = loader.loadClass(DEX_CONSOLE);
|
||||
Class<?> argClass = loader.loadClass(DEX_ARGS);
|
||||
|
||||
sWrapper = new DexWrapper(mainClass, argClass, consoleClass);
|
||||
|
||||
try {
|
||||
// now get the fields/methods we need
|
||||
mRunMethod = mainClass.getMethod(MAIN_RUN, argClass);
|
||||
|
||||
mArgConstructor = argClass.getConstructor();
|
||||
mArgOutName = argClass.getField("outName"); //$NON-NLS-1$
|
||||
mArgJarOutput = argClass.getField("jarOutput"); //$NON-NLS-1$
|
||||
mArgFileNames = argClass.getField("fileNames"); //$NON-NLS-1$
|
||||
mArgVerbose = argClass.getField("verbose"); //$NON-NLS-1$
|
||||
|
||||
mConsoleOut = consoleClass.getField("out"); //$NON-NLS-1$
|
||||
mConsoleErr = consoleClass.getField("err"); //$NON-NLS-1$
|
||||
|
||||
} catch (SecurityException e) {
|
||||
return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_API, e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Method, e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Field, e);
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
} catch (MalformedURLException e) {
|
||||
// really this should not happen.
|
||||
return createErrorStatus(String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
|
||||
return createErrorStatus(
|
||||
String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return createErrorStatus(String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
} finally {
|
||||
if (sWrapper == null) {
|
||||
sLoadStatus = LoadStatus.FAILED;
|
||||
} else {
|
||||
sLoadStatus = LoadStatus.LOADED;
|
||||
}
|
||||
return createErrorStatus(
|
||||
String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the loaded dex wrapper.
|
||||
*/
|
||||
public static synchronized void unloadDex() {
|
||||
sWrapper = null;
|
||||
sLoadStatus = LoadStatus.LOADING;
|
||||
}
|
||||
|
||||
public static synchronized DexWrapper getWrapper() {
|
||||
return sWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link LoadStatus}.
|
||||
*/
|
||||
public static synchronized LoadStatus getStatus() {
|
||||
return sLoadStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the dex command.
|
||||
* @param osOutFilePath the OS path to the outputfile (classes.dex
|
||||
@@ -169,33 +156,6 @@ public final class DexWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private DexWrapper(Class<?> mainClass, Class<?> argClass, Class<?> consoleClass)
|
||||
throws CoreException {
|
||||
try {
|
||||
// now get the fields/methods we need
|
||||
mRunMethod = mainClass.getMethod(MAIN_RUN, argClass);
|
||||
|
||||
mArgConstructor = argClass.getConstructor();
|
||||
mArgOutName = argClass.getField("outName"); //$NON-NLS-1$
|
||||
mArgJarOutput = argClass.getField("jarOutput"); //$NON-NLS-1$
|
||||
mArgFileNames = argClass.getField("fileNames"); //$NON-NLS-1$
|
||||
mArgVerbose = argClass.getField("verbose"); //$NON-NLS-1$
|
||||
|
||||
mConsoleOut = consoleClass.getField("out"); //$NON-NLS-1$
|
||||
mConsoleErr = consoleClass.getField("err"); //$NON-NLS-1$
|
||||
|
||||
} catch (SecurityException e) {
|
||||
throw new CoreException(createErrorStatus(
|
||||
Messages.DexWrapper_SecuryEx_Unable_To_Find_API, e));
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new CoreException(createErrorStatus(
|
||||
Messages.DexWrapper_SecuryEx_Unable_To_Find_Method, e));
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new CoreException(createErrorStatus(
|
||||
Messages.DexWrapper_SecuryEx_Unable_To_Find_Field, e));
|
||||
}
|
||||
}
|
||||
|
||||
private static IStatus createErrorStatus(String message, Exception e) {
|
||||
AdtPlugin.log(e, message);
|
||||
AdtPlugin.printErrorToConsole(Messages.DexWrapper_Dex_Loader, message);
|
||||
|
||||
@@ -235,6 +235,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
// get the project objects
|
||||
IProject project = getProject();
|
||||
IJavaProject javaProject = JavaCore.create(project);
|
||||
IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
|
||||
|
||||
// now we need to get the classpath list
|
||||
ArrayList<IPath> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject);
|
||||
@@ -407,8 +408,6 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
String osResPath = resLocation.toOSString();
|
||||
String osManifestPath = manifestLocation.toOSString();
|
||||
|
||||
IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
|
||||
|
||||
// remove the aapt markers
|
||||
removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT);
|
||||
removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT);
|
||||
@@ -432,7 +431,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
|
||||
// launch aapt: create the command line
|
||||
ArrayList<String> array = new ArrayList<String>();
|
||||
array.add(AdtPlugin.getOsAbsoluteAapt());
|
||||
array.add(projectTarget.getPath(IAndroidTarget.AAPT));
|
||||
array.add("package"); //$NON-NLS-1$
|
||||
array.add("-m"); //$NON-NLS-1$
|
||||
if (AdtPlugin.getBuildVerbosity() == AdtConstants.BUILD_VERBOSE) {
|
||||
@@ -541,7 +540,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
if (projectAidl != null && projectAidl.exists()) {
|
||||
folderAidlPath = projectAidl.getLocation().toOSString();
|
||||
}
|
||||
boolean aidlStatus = handleAidl(sourceList, folderAidlPath, monitor);
|
||||
boolean aidlStatus = handleAidl(projectTarget, sourceList, folderAidlPath, monitor);
|
||||
|
||||
if (aidlStatus == false && mCompileResources == false) {
|
||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
|
||||
@@ -729,14 +728,15 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
/**
|
||||
* Compiles aidl files into java. This will also removes old java files
|
||||
* created from aidl files that are now gone.
|
||||
* @param projectTarget Target of the project
|
||||
* @param sourceFolders the list of source folders, relative to the workspace.
|
||||
* @param folderAidlPath
|
||||
* @param monitor the projess monitor
|
||||
* @returns true if it did something
|
||||
* @throws CoreException
|
||||
*/
|
||||
private boolean handleAidl(ArrayList<IPath> sourceFolders, String folderAidlPath,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
private boolean handleAidl(IAndroidTarget projectTarget, ArrayList<IPath> sourceFolders,
|
||||
String folderAidlPath, IProgressMonitor monitor) throws CoreException {
|
||||
if (mAidlToCompile.size() == 0 && mAidlToRemove.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
||||
String[] command = new String[4 + sourceFolders.size() + (folderAidlPath != null ? 1 : 0)];
|
||||
int index = 0;
|
||||
int aidlIndex;
|
||||
command[index++] = AdtPlugin.getOsAbsoluteAidl();
|
||||
command[index++] = projectTarget.getPath(IAndroidTarget.AIDL);
|
||||
command[aidlIndex = index++] = "-p"; //$NON-NLS-1$
|
||||
if (folderAidlPath != null) {
|
||||
command[index++] = "-p" + folderAidlPath; //$NON-NLS-1$
|
||||
|
||||
@@ -1519,6 +1519,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
|
||||
AdtPlugin.printErrorToConsole(launchInfo.mProject,
|
||||
String.format(message1, launchInfo.mActivity));
|
||||
}
|
||||
launchInfo.mLaunch.stopLaunch();
|
||||
}
|
||||
for (DelayedLaunchInfo launchInfo : mWaitingForDebuggerApplications) {
|
||||
if (launchInfo.mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING) {
|
||||
@@ -1527,7 +1528,11 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
|
||||
AdtPlugin.printErrorToConsole(launchInfo.mProject,
|
||||
String.format(message1, launchInfo.mActivity));
|
||||
}
|
||||
launchInfo.mLaunch.stopLaunch();
|
||||
}
|
||||
|
||||
mWaitingForReadyEmulatorList.clear();
|
||||
mWaitingForDebuggerApplications.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1573,24 +1578,31 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
|
||||
*
|
||||
* @see IDeviceChangeListener#deviceDisconnected(Device)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void deviceDisconnected(Device device) {
|
||||
// any pending launch on this device must be canceled.
|
||||
String message = "%1$s disconnected! Cancelling '%2$s' launch!";
|
||||
synchronized (sListLock) {
|
||||
for (DelayedLaunchInfo launchInfo : mWaitingForReadyEmulatorList) {
|
||||
ArrayList<DelayedLaunchInfo> copyList =
|
||||
(ArrayList<DelayedLaunchInfo>)mWaitingForReadyEmulatorList.clone();
|
||||
for (DelayedLaunchInfo launchInfo : copyList) {
|
||||
if (launchInfo.mDevice == device) {
|
||||
AdtPlugin.printErrorToConsole(launchInfo.mProject,
|
||||
String.format(message, device.getSerialNumber(), launchInfo.mActivity));
|
||||
launchInfo.mLaunch.stopLaunch();
|
||||
mWaitingForReadyEmulatorList.remove(launchInfo);
|
||||
}
|
||||
}
|
||||
for (DelayedLaunchInfo launchInfo : mWaitingForDebuggerApplications) {
|
||||
copyList = (ArrayList<DelayedLaunchInfo>)mWaitingForDebuggerApplications.clone();
|
||||
for (DelayedLaunchInfo launchInfo : copyList) {
|
||||
if (launchInfo.mDevice == device) {
|
||||
AdtPlugin.printErrorToConsole(launchInfo.mProject,
|
||||
String.format(message, device.getSerialNumber(), launchInfo.mActivity));
|
||||
launchInfo.mLaunch.stopLaunch();
|
||||
mWaitingForDebuggerApplications.remove(launchInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -310,7 +310,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
||||
top.setLayout(new GridLayout(1, true));
|
||||
|
||||
mDeviceRadioButton = new Button(top, SWT.RADIO);
|
||||
mDeviceRadioButton.setText("Choose an Android running device");
|
||||
mDeviceRadioButton.setText("Choose a running Android device");
|
||||
mDeviceRadioButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
@@ -387,7 +387,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
||||
});
|
||||
|
||||
Button radio2 = new Button(top, SWT.RADIO);
|
||||
radio2.setText("Launch a new Virtual Device");
|
||||
radio2.setText("Launch a new Android Virtual Device");
|
||||
|
||||
// offset the selector from the radio button
|
||||
offsetComp = new Composite(top, SWT.NONE);
|
||||
|
||||
@@ -172,13 +172,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
|
||||
|
||||
// if we are loaded and the target is non null, we create a valid ClassPathContainer
|
||||
if (sdkIsLoaded && target != null) {
|
||||
String targetName = null;
|
||||
if (target.isPlatform()) {
|
||||
targetName = target.getName();
|
||||
} else {
|
||||
targetName = String.format("%1$s (%2$s)", target.getName(),
|
||||
target.getApiVersionName());
|
||||
}
|
||||
String targetName = target.getFullName();
|
||||
|
||||
return new AndroidClasspathContainer(
|
||||
createClasspathEntries(iProject, target, targetName),
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.ide.eclipse.adt.sdk;
|
||||
|
||||
import com.android.ide.eclipse.adt.build.DexWrapper;
|
||||
import com.android.ide.eclipse.common.resources.IResourceRepository;
|
||||
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
|
||||
import com.android.ide.eclipse.editors.layout.descriptors.LayoutDescriptors;
|
||||
@@ -54,6 +55,8 @@ public class AndroidTargetData {
|
||||
|
||||
private final IAndroidTarget mTarget;
|
||||
|
||||
private DexWrapper mDexWrapper;
|
||||
|
||||
/**
|
||||
* mAttributeValues is a map { key => list [ values ] }.
|
||||
* The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)".
|
||||
@@ -64,27 +67,34 @@ public class AndroidTargetData {
|
||||
* This is used for attributes that do not have a unique name, but still need to be populated
|
||||
* with values in the UI. Uniquely named attributes have their values in {@link #mEnumValueMap}.
|
||||
*/
|
||||
private final Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>();
|
||||
private Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>();
|
||||
|
||||
private IResourceRepository mSystemResourceRepository;
|
||||
|
||||
private final AndroidManifestDescriptors mManifestDescriptors;
|
||||
private final LayoutDescriptors mLayoutDescriptors;
|
||||
private final MenuDescriptors mMenuDescriptors;
|
||||
private final XmlDescriptors mXmlDescriptors;
|
||||
private AndroidManifestDescriptors mManifestDescriptors;
|
||||
private LayoutDescriptors mLayoutDescriptors;
|
||||
private MenuDescriptors mMenuDescriptors;
|
||||
private XmlDescriptors mXmlDescriptors;
|
||||
|
||||
private final Map<String, Map<String, Integer>> mEnumValueMap;
|
||||
private Map<String, Map<String, Integer>> mEnumValueMap;
|
||||
|
||||
private final ProjectResources mFrameworkResources;
|
||||
private final LayoutBridge mLayoutBridge;
|
||||
private ProjectResources mFrameworkResources;
|
||||
private LayoutBridge mLayoutBridge;
|
||||
|
||||
private boolean mLayoutBridgeInit = false;
|
||||
|
||||
AndroidTargetData(IAndroidTarget androidTarget) {
|
||||
mTarget = androidTarget;
|
||||
}
|
||||
|
||||
void setDexWrapper(DexWrapper wrapper) {
|
||||
mDexWrapper = wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AndroidTargetData object.
|
||||
*/
|
||||
AndroidTargetData(IAndroidTarget androidTarget,
|
||||
IResourceRepository systemResourceRepository,
|
||||
void setExtraData(IResourceRepository systemResourceRepository,
|
||||
AndroidManifestDescriptors manifestDescriptors,
|
||||
LayoutDescriptors layoutDescriptors,
|
||||
MenuDescriptors menuDescriptors,
|
||||
@@ -98,7 +108,6 @@ public class AndroidTargetData {
|
||||
ProjectResources resources,
|
||||
LayoutBridge layoutBridge) {
|
||||
|
||||
mTarget = androidTarget;
|
||||
mSystemResourceRepository = systemResourceRepository;
|
||||
mManifestDescriptors = manifestDescriptors;
|
||||
mLayoutDescriptors = layoutDescriptors;
|
||||
@@ -113,6 +122,10 @@ public class AndroidTargetData {
|
||||
serviceIntentActionValues, intentCategoryValues);
|
||||
}
|
||||
|
||||
public DexWrapper getDexWrapper() {
|
||||
return mDexWrapper;
|
||||
}
|
||||
|
||||
public IResourceRepository getSystemResources() {
|
||||
return mSystemResourceRepository;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.ide.eclipse.adt.sdk;
|
||||
|
||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||
import com.android.ide.eclipse.adt.build.DexWrapper;
|
||||
import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
|
||||
import com.android.ide.eclipse.common.AndroidConstants;
|
||||
import com.android.ide.eclipse.common.resources.AttrsXmlParser;
|
||||
@@ -91,8 +92,25 @@ public final class AndroidTargetParser {
|
||||
try {
|
||||
SubMonitor progress = SubMonitor.convert(monitor,
|
||||
String.format("Parsing SDK %1$s", mAndroidTarget.getName()),
|
||||
120);
|
||||
200);
|
||||
|
||||
AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget);
|
||||
|
||||
// load DX.
|
||||
DexWrapper dexWrapper = new DexWrapper();
|
||||
IStatus res = dexWrapper.loadDex(mAndroidTarget.getPath(IAndroidTarget.DX_JAR));
|
||||
if (res != Status.OK_STATUS) {
|
||||
return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
|
||||
String.format("dx.jar loading failed for target '%1$s'",
|
||||
mAndroidTarget.getFullName()));
|
||||
}
|
||||
|
||||
// we have loaded dx.
|
||||
targetData.setDexWrapper(dexWrapper);
|
||||
|
||||
// parse the rest of the data.
|
||||
progress.setWorkRemaining(120);
|
||||
|
||||
AndroidJarLoader classLoader =
|
||||
new AndroidJarLoader(mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
|
||||
|
||||
@@ -229,8 +247,7 @@ public final class AndroidTargetParser {
|
||||
progress.worked(10);
|
||||
|
||||
// and finally create the PlatformData with all that we loaded.
|
||||
AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget,
|
||||
frameworkRepository,
|
||||
targetData.setExtraData(frameworkRepository,
|
||||
manifestDescriptors,
|
||||
layoutDescriptors,
|
||||
menuDescriptors,
|
||||
|
||||
@@ -18,6 +18,8 @@ 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.ide.eclipse.editors.resources.manager.ResourceMonitor;
|
||||
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
|
||||
import com.android.prefs.AndroidLocation.AndroidLocationException;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.android.sdklib.ISdkLog;
|
||||
@@ -28,6 +30,8 @@ import com.android.sdklib.project.ProjectProperties;
|
||||
import com.android.sdklib.project.ProjectProperties.PropertyType;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
@@ -38,6 +42,9 @@ import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Central point to load, manipulate and deal with the Android SDK. Only one SDK can be used
|
||||
@@ -48,18 +55,19 @@ import java.util.HashMap;
|
||||
*
|
||||
* To get the list of platforms or add-ons present in the SDK, call {@link #getTargets()}.
|
||||
*/
|
||||
public class Sdk {
|
||||
public class Sdk implements IProjectListener {
|
||||
private static Sdk sCurrentSdk = null;
|
||||
|
||||
private final SdkManager mManager;
|
||||
private final AvdManager mAvdManager;
|
||||
|
||||
private final HashMap<IProject, IAndroidTarget> mProjectMap =
|
||||
private final HashMap<IProject, IAndroidTarget> mProjectTargetMap =
|
||||
new HashMap<IProject, IAndroidTarget>();
|
||||
private final HashMap<IAndroidTarget, AndroidTargetData> mTargetMap =
|
||||
private final HashMap<IAndroidTarget, AndroidTargetData> mTargetDataMap =
|
||||
new HashMap<IAndroidTarget, AndroidTargetData>();
|
||||
private final HashMap<IProject, Map<String, String>> mProjectConfigMap =
|
||||
new HashMap<IProject, Map<String, String>>();
|
||||
private final String mDocBaseUrl;
|
||||
|
||||
|
||||
/**
|
||||
* Loads an SDK and returns an {@link Sdk} object if success.
|
||||
@@ -67,7 +75,7 @@ public class Sdk {
|
||||
*/
|
||||
public static Sdk loadSdk(String sdkLocation) {
|
||||
if (sCurrentSdk != null) {
|
||||
// manual unload?
|
||||
sCurrentSdk.dispose();
|
||||
sCurrentSdk = null;
|
||||
}
|
||||
|
||||
@@ -159,16 +167,16 @@ public class Sdk {
|
||||
* Associates an {@link IProject} and an {@link IAndroidTarget}.
|
||||
*/
|
||||
public void setProject(IProject project, IAndroidTarget target) {
|
||||
synchronized (mProjectMap) {
|
||||
synchronized (mProjectTargetMap) {
|
||||
// look for the current target of the project
|
||||
IAndroidTarget previousTarget = mProjectMap.get(project);
|
||||
IAndroidTarget previousTarget = mProjectTargetMap.get(project);
|
||||
|
||||
if (target != previousTarget) {
|
||||
// save the target hash string in the project persistent property
|
||||
setProjectTargetHashString(project, target.hashString());
|
||||
|
||||
// put it in a local map for easy access.
|
||||
mProjectMap.put(project, target);
|
||||
mProjectTargetMap.put(project, target);
|
||||
|
||||
// recompile the project if needed.
|
||||
IJavaProject javaProject = JavaCore.create(project);
|
||||
@@ -182,11 +190,11 @@ public class Sdk {
|
||||
* Returns the {@link IAndroidTarget} object associated with the given {@link IProject}.
|
||||
*/
|
||||
public IAndroidTarget getTarget(IProject project) {
|
||||
synchronized (mProjectMap) {
|
||||
IAndroidTarget target = mProjectMap.get(project);
|
||||
synchronized (mProjectTargetMap) {
|
||||
IAndroidTarget target = mProjectTargetMap.get(project);
|
||||
if (target == null) {
|
||||
// get the value from the project persistent property.
|
||||
String targetHashString = getProjectTargetHashString(project);
|
||||
String targetHashString = loadProjectProperties(project, this);
|
||||
|
||||
if (targetHashString != null) {
|
||||
target = mManager.getTargetFromHashString(targetHashString);
|
||||
@@ -197,14 +205,19 @@ public class Sdk {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash string uniquely identifying the target of a project. This methods reads
|
||||
* the string from the project persistent preferences/properties.
|
||||
* <p/>The string is equivalent to the return of {@link IAndroidTarget#hashString()}.
|
||||
* Parses the project properties and returns the hash string uniquely identifying the
|
||||
* target of the given project.
|
||||
* <p/>
|
||||
* This methods reads the content of the <code>default.properties</code> file present in
|
||||
* the root folder of the project.
|
||||
* <p/>The returned string is equivalent to the return of {@link IAndroidTarget#hashString()}.
|
||||
* @param project The project for which to return the target hash string.
|
||||
* @param storeConfigs Whether the read configuration should be stored in the map.
|
||||
* @return the hash string or null if the project does not have a target set.
|
||||
*/
|
||||
public static String getProjectTargetHashString(IProject project) {
|
||||
private static String loadProjectProperties(IProject project, Sdk storeConfigs) {
|
||||
// load the default.properties from the project folder.
|
||||
ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
|
||||
PropertyType.DEFAULT);
|
||||
@@ -214,11 +227,46 @@ public class Sdk {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (storeConfigs != null) {
|
||||
// get the list of configs.
|
||||
String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS);
|
||||
|
||||
// this is a comma separated list
|
||||
String[] configs = configList.split(","); //$NON-NLS-1$
|
||||
|
||||
// read the value of each config and store it in a map
|
||||
HashMap<String, String> configMap = new HashMap<String, String>();
|
||||
|
||||
for (String config : configs) {
|
||||
String configValue = properties.getProperty(config);
|
||||
if (configValue != null) {
|
||||
configMap.put(config, configValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (configMap.size() > 0) {
|
||||
storeConfigs.mProjectConfigMap.put(project, configMap);
|
||||
}
|
||||
}
|
||||
|
||||
return properties.getProperty(ProjectProperties.PROPERTY_TARGET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash string uniquely identifying the target of a project.
|
||||
* <p/>
|
||||
* This methods reads the content of the <code>default.properties</code> file present in
|
||||
* the root folder of the project.
|
||||
* <p/>The string is equivalent to the return of {@link IAndroidTarget#hashString()}.
|
||||
* @param project The project for which to return the target hash string.
|
||||
* @return the hash string or null if the project does not have a target set.
|
||||
*/
|
||||
public static String getProjectTargetHashString(IProject project) {
|
||||
return loadProjectProperties(project, null /*storeConfigs*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a target hash string in a project's persistent preferences/property storage.
|
||||
* Sets a target hash string in given project's <code>default.properties</code> file.
|
||||
* @param project The project in which to save the hash string.
|
||||
* @param targetHashString The target hash string to save. This must be the result from
|
||||
* {@link IAndroidTarget#hashString()}.
|
||||
@@ -249,11 +297,81 @@ public class Sdk {
|
||||
* Return the {@link AndroidTargetData} for a given {@link IAndroidTarget}.
|
||||
*/
|
||||
public AndroidTargetData getTargetData(IAndroidTarget target) {
|
||||
synchronized (mTargetMap) {
|
||||
return mTargetMap.get(target);
|
||||
synchronized (mTargetDataMap) {
|
||||
return mTargetDataMap.get(target);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration map for a given project.
|
||||
* <p/>The Map key are name to be used in the apk filename, while the values are comma separated
|
||||
* config values. The config value can be passed directly to aapt through the -c option.
|
||||
*/
|
||||
public Map<String, String> getProjectConfigs(IProject project) {
|
||||
return mProjectConfigMap.get(project);
|
||||
}
|
||||
|
||||
public void setProjectConfigs(IProject project, Map<String, String> configMap)
|
||||
throws CoreException {
|
||||
// first set the new map
|
||||
mProjectConfigMap.put(project, configMap);
|
||||
|
||||
// Now we write this in default.properties.
|
||||
// Because we don't want to erase other properties from default.properties, we first load
|
||||
// them
|
||||
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(),
|
||||
PropertyType.DEFAULT);
|
||||
}
|
||||
|
||||
// load the current configs, in order to remove the value properties for each of them
|
||||
// in case a config was removed.
|
||||
|
||||
// get the list of configs.
|
||||
String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS);
|
||||
|
||||
// this is a comma separated list
|
||||
String[] configs = configList.split(","); //$NON-NLS-1$
|
||||
|
||||
boolean hasRemovedConfig = false;
|
||||
|
||||
for (String config : configs) {
|
||||
if (configMap.containsKey(config) == false) {
|
||||
hasRemovedConfig = true;
|
||||
properties.removeProperty(config);
|
||||
}
|
||||
}
|
||||
|
||||
// now add the properties.
|
||||
Set<Entry<String, String>> entrySet = configMap.entrySet();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(entry.getKey());
|
||||
properties.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
properties.setProperty(ProjectProperties.PROPERTY_CONFIGS, sb.toString());
|
||||
|
||||
// and rewrite the file.
|
||||
try {
|
||||
properties.save();
|
||||
} catch (IOException e) {
|
||||
AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
|
||||
project.getName());
|
||||
}
|
||||
|
||||
// we're done, force a rebuild. If there was removed config, we clean instead of build
|
||||
// (to remove the obsolete ap_ and apk file from removed configs).
|
||||
project.build(hasRemovedConfig ?
|
||||
IncrementalProjectBuilder.CLEAN_BUILD : IncrementalProjectBuilder.FULL_BUILD,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could
|
||||
* be <code>null</code>.
|
||||
@@ -266,14 +384,25 @@ public class Sdk {
|
||||
mManager = manager;
|
||||
mAvdManager = avdManager;
|
||||
|
||||
// listen to projects closing
|
||||
ResourceMonitor monitor = ResourceMonitor.getMonitor();
|
||||
monitor.addProjectListener(this);
|
||||
|
||||
// pre-compute some paths
|
||||
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
|
||||
SdkConstants.OS_SDK_DOCS_FOLDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans and unloads the SDK.
|
||||
*/
|
||||
private void dispose() {
|
||||
ResourceMonitor.getMonitor().removeProjectListener(this);
|
||||
}
|
||||
|
||||
void setTargetData(IAndroidTarget target, AndroidTargetData data) {
|
||||
synchronized (mTargetMap) {
|
||||
mTargetMap.put(target, data);
|
||||
synchronized (mTargetDataMap) {
|
||||
mTargetDataMap.put(target, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +443,24 @@ public class Sdk {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void projectClosed(IProject project) {
|
||||
mProjectTargetMap.remove(project);
|
||||
mProjectConfigMap.remove(project);
|
||||
}
|
||||
|
||||
public void projectDeleted(IProject project) {
|
||||
projectClosed(project);
|
||||
}
|
||||
|
||||
public void projectOpened(IProject project) {
|
||||
// ignore this. The project will be added to the map the first time the target needs
|
||||
// to be resolved.
|
||||
}
|
||||
|
||||
public void projectOpenedWithWorkspace(IProject project) {
|
||||
// ignore this. The project will be added to the map the first time the target needs
|
||||
// to be resolved.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.ide.eclipse.common;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Constant definition class.<br>
|
||||
@@ -49,17 +50,6 @@ public class AndroidConstants {
|
||||
/** Nature of android projects */
|
||||
public final static String NATURE = "com.android.ide.eclipse.adt.AndroidNature"; //$NON-NLS-1$
|
||||
|
||||
public final static int PLATFORM_UNKNOWN = 0;
|
||||
public final static int PLATFORM_LINUX = 1;
|
||||
public final static int PLATFORM_WINDOWS = 2;
|
||||
public final static int PLATFORM_DARWIN = 3;
|
||||
|
||||
/**
|
||||
* Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
|
||||
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
|
||||
*/
|
||||
public final static int CURRENT_PLATFORM = currentPlatform();
|
||||
|
||||
/** Separator for workspace path, i.e. "/". */
|
||||
public final static String WS_SEP = "/"; //$NON-NLS-1$
|
||||
/** Separator character for workspace path, i.e. '/'. */
|
||||
@@ -99,8 +89,6 @@ public class AndroidConstants {
|
||||
public static final String FN_ANDROID_MANIFEST = "AndroidManifest.xml"; //$NON-NLS-1$
|
||||
public static final String FN_PROJECT_AIDL = "project.aidl"; //$NON-NLS-1$
|
||||
|
||||
/** dex.jar file */
|
||||
public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
|
||||
/** Name of the android sources directory */
|
||||
public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$
|
||||
|
||||
@@ -114,20 +102,21 @@ public class AndroidConstants {
|
||||
public final static String FN_CLASSES_DEX = "classes.dex"; //$NON-NLS-1$
|
||||
/** Temporary packaged resources file name, i.e. "resources.ap_" */
|
||||
public final static String FN_RESOURCES_AP_ = "resources.ap_"; //$NON-NLS-1$
|
||||
/** Temporary packaged resources file name for a specific set of configuration */
|
||||
public final static String FN_RESOURCES_S_AP_ = "resources-%s.ap_"; //$NON-NLS-1$
|
||||
public final static Pattern PATTERN_RESOURCES_S_AP_ =
|
||||
Pattern.compile("resources-.*\\.ap_", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public final static String FN_ADB = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
public final static String FN_ADB =
|
||||
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
|
||||
"adb.exe" : "adb"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
public final static String FN_AAPT = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
"aapt.exe" : "aapt"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
public final static String FN_AIDL = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
"aidl.exe" : "aidl"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
public final static String FN_EMULATOR = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
public final static String FN_EMULATOR =
|
||||
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
|
||||
"emulator.exe" : "emulator"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
public final static String FN_TRACEVIEW = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
|
||||
public final static String FN_TRACEVIEW =
|
||||
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
|
||||
"traceview.exe" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
/** Absolute path of the workspace root, i.e. "/" */
|
||||
@@ -147,11 +136,6 @@ public class AndroidConstants {
|
||||
* FIXME: remove once the NPW is fixed. */
|
||||
public final static String OS_SDK_SAMPLES_FOLDER = SdkConstants.FD_SAMPLES + File.separator;
|
||||
|
||||
/** Path of the dx.jar file relative to the sdk folder. */
|
||||
public final static String OS_SDK_LIBS_DX_JAR =
|
||||
SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + FN_DX_JAR;
|
||||
|
||||
/** Regexp for single dot */
|
||||
public final static String RE_DOT = "\\."; //$NON-NLS-1$
|
||||
/** Regexp for java extension, i.e. "\.java$" */
|
||||
public final static String RE_JAVA_EXT = "\\.java$"; //$NON-NLS-1$
|
||||
@@ -229,22 +213,4 @@ public class AndroidConstants {
|
||||
/** The base URL where to find the Android class & manifest documentation */
|
||||
public static final String CODESITE_BASE_URL = "http://code.google.com/android"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns current platform
|
||||
*
|
||||
* @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
|
||||
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
|
||||
*/
|
||||
private static int currentPlatform() {
|
||||
String os = System.getProperty("os.name"); //$NON-NLS-1$
|
||||
if (os.startsWith("Mac OS")) { //$NON-NLS-1$
|
||||
return PLATFORM_DARWIN;
|
||||
} else if (os.startsWith("Windows")) { //$NON-NLS-1$
|
||||
return PLATFORM_WINDOWS;
|
||||
} else if (os.startsWith("Linux")) { //$NON-NLS-1$
|
||||
return PLATFORM_LINUX;
|
||||
}
|
||||
|
||||
return PLATFORM_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package com.android.ide.eclipse.editors;
|
||||
|
||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||
import com.android.ide.eclipse.common.AndroidConstants;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.swt.SWT;
|
||||
@@ -231,7 +231,7 @@ public class IconFactory {
|
||||
// Text measurement varies so slightly depending on the platform
|
||||
int ofx = 0;
|
||||
int ofy = 0;
|
||||
if (AndroidConstants.CURRENT_PLATFORM == AndroidConstants.PLATFORM_WINDOWS) {
|
||||
if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) {
|
||||
ofx = +1;
|
||||
ofy = -1;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,13 @@ public class ResourceExplorerView extends ViewPart implements ISelectionListener
|
||||
// set up the resource manager to send us resource change notification
|
||||
AdtPlugin.getDefault().getResourceMonitor().addResourceEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
AdtPlugin.getDefault().getResourceMonitor().removeResourceEventListener(this);
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus() {
|
||||
|
||||
@@ -189,20 +189,15 @@ public class ResourceMonitor implements IResourceChangeListener {
|
||||
// the project is opening or closing.
|
||||
IProject project = (IProject)r;
|
||||
|
||||
// the OPEN flag represent a toggle in the open/close state of the
|
||||
// project, but this is sent before the project actually toggles
|
||||
// its state.
|
||||
// This means that if the project is closing, isOpen() will return true.
|
||||
boolean isClosing = project.isOpen();
|
||||
if (isClosing) {
|
||||
if (project.isOpen()) {
|
||||
// notify the listeners.
|
||||
for (IProjectListener pl : mProjectListeners) {
|
||||
pl.projectClosed(project);
|
||||
pl.projectOpened(project);
|
||||
}
|
||||
} else {
|
||||
// notify the listeners.
|
||||
for (IProjectListener pl : mProjectListeners) {
|
||||
pl.projectOpened(project);
|
||||
pl.projectClosed(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,6 +281,20 @@ public class ResourceMonitor implements IResourceChangeListener {
|
||||
mFolderListeners.add(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing folder listener.
|
||||
* @param listener the listener to remove.
|
||||
*/
|
||||
public synchronized void removeFolderListener(IFolderListener listener) {
|
||||
for (int i = 0 ; i < mFolderListeners.size() ; i++) {
|
||||
FolderListenerBundle bundle = mFolderListeners.get(i);
|
||||
if (bundle.listener == listener) {
|
||||
mFolderListeners.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a project listener.
|
||||
* @param listener The listener to receive the events.
|
||||
@@ -305,10 +314,30 @@ public class ResourceMonitor implements IResourceChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing project listener.
|
||||
* @param listener the listener to remove.
|
||||
*/
|
||||
public synchronized void removeProjectListener(IProjectListener listener) {
|
||||
mProjectListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource event listener.
|
||||
* @param listener The listener to receive the events.
|
||||
*/
|
||||
public synchronized void addResourceEventListener(IResourceEventListener listener) {
|
||||
mEventListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing Resource Event listener.
|
||||
* @param listener the listener to remove.
|
||||
*/
|
||||
public synchronized void removeResourceEventListener(IResourceEventListener listener) {
|
||||
mEventListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the workspace resource change events.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user