summaryrefslogtreecommitdiffstats
path: root/dx
diff options
context:
space:
mode:
authorHugo Hudson <hugohudson@google.com>2011-12-16 08:31:49 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-12-16 08:31:49 -0800
commitf8fec55f4689b0c54529b2bbf4e25b0c7cfbbe1e (patch)
tree82026400f812862a689c362fec3b6aa17dc979c9 /dx
parent95f4f019d106a2bb6f9e14e25616f865e8e821ef (diff)
parent7adb0bfc638ba2f6ce896975ee49c889e73bad44 (diff)
downloadandroid_dalvik-f8fec55f4689b0c54529b2bbf4e25b0c7cfbbe1e.tar.gz
android_dalvik-f8fec55f4689b0c54529b2bbf4e25b0c7cfbbe1e.tar.bz2
android_dalvik-f8fec55f4689b0c54529b2bbf4e25b0c7cfbbe1e.zip
Merge "DexGenerator: allow specifying dex cache dir."
Diffstat (limited to 'dx')
-rw-r--r--dx/junit-tests/HelloWorldMaker.java6
-rw-r--r--dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java17
-rw-r--r--dx/src/com/android/dx/gen/DexGenerator.java38
3 files changed, 49 insertions, 12 deletions
diff --git a/dx/junit-tests/HelloWorldMaker.java b/dx/junit-tests/HelloWorldMaker.java
index 001f31a90..038701c77 100644
--- a/dx/junit-tests/HelloWorldMaker.java
+++ b/dx/junit-tests/HelloWorldMaker.java
@@ -22,6 +22,8 @@ import com.android.dx.gen.Local;
import com.android.dx.gen.MethodId;
import com.android.dx.gen.Type;
import com.android.dx.rop.code.AccessFlags;
+
+import java.io.File;
import java.io.PrintStream;
public class HelloWorldMaker {
@@ -79,7 +81,9 @@ public class HelloWorldMaker {
generator.declare(helloWorld, "Generated.java", AccessFlags.ACC_PUBLIC, Type.OBJECT);
// load the dex
- ClassLoader loader = generator.load(HelloWorldMaker.class.getClassLoader());
+ File outputDir = new File(".");
+ ClassLoader loader = generator.load(HelloWorldMaker.class.getClassLoader(),
+ outputDir, outputDir);
Class<?> helloWorldClass = loader.loadClass("HelloWorld");
helloWorldClass.getMethod("hello").invoke(null);
}
diff --git a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java b/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
index 8b23805d7..8dc6c8db5 100644
--- a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
+++ b/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
@@ -22,6 +22,10 @@ import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
import static com.android.dx.rop.code.AccessFlags.ACC_PROTECTED;
import static com.android.dx.rop.code.AccessFlags.ACC_PUBLIC;
import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
+
+import junit.framework.TestCase;
+
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -29,7 +33,6 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
-import junit.framework.TestCase;
/**
* This generates a class named 'Generated' with one or more generated methods
@@ -1660,7 +1663,15 @@ public final class DexGeneratorTest extends TestCase {
throw new IllegalStateException("no call() method");
}
- private Class<?> loadAndGenerate() throws IOException, ClassNotFoundException {
- return generator.load(DexGeneratorTest.class.getClassLoader()).loadClass("Generated");
+ public static File getDataDirectory() throws Exception {
+ Class<?> environmentClass = Class.forName("android.os.Environment");
+ Method method = environmentClass.getMethod("getDataDirectory");
+ Object dataDirectory = method.invoke(null);
+ return (File) dataDirectory;
+ }
+
+ private Class<?> loadAndGenerate() throws Exception {
+ return generator.load(getClass().getClassLoader(),
+ getDataDirectory(), getDataDirectory()).loadClass("Generated");
}
}
diff --git a/dx/src/com/android/dx/gen/DexGenerator.java b/dx/src/com/android/dx/gen/DexGenerator.java
index 7cde9a93f..56c516b0c 100644
--- a/dx/src/com/android/dx/gen/DexGenerator.java
+++ b/dx/src/com/android/dx/gen/DexGenerator.java
@@ -16,6 +16,10 @@
package com.android.dx.gen;
+import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
+import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
+import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
+
import com.android.dx.dex.DexFormat;
import com.android.dx.dex.DexOptions;
import com.android.dx.dex.code.DalvCode;
@@ -26,12 +30,12 @@ import com.android.dx.dex.file.DexFile;
import com.android.dx.dex.file.EncodedField;
import com.android.dx.dex.file.EncodedMethod;
import com.android.dx.rop.code.AccessFlags;
-import static com.android.dx.rop.code.AccessFlags.*;
import com.android.dx.rop.code.LocalVariableInfo;
import com.android.dx.rop.code.RopMethod;
import com.android.dx.rop.cst.CstString;
import com.android.dx.rop.cst.CstType;
import com.android.dx.rop.type.StdTypeList;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -102,7 +106,9 @@ public final class DexGenerator {
* Returns a .dex formatted file.
*/
public byte[] generate() {
- DexFile outputDex = new DexFile(new DexOptions());
+ DexOptions options = new DexOptions();
+ options.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
+ DexFile outputDex = new DexFile(options);
for (TypeDeclaration typeDeclaration : types.values()) {
outputDex.add(typeDeclaration.toClassDefItem());
@@ -116,9 +122,25 @@ public final class DexGenerator {
}
/**
- * Loads the generated types into the current dalvikvm process.
+ * Loads the generated types into the current process.
+ *
+ * <p>All parameters are optional, you may pass {@code null} and suitable
+ * defaults will be used.
+ *
+ * <p>If you opt to provide your own output directories, take care to
+ * ensure that they are not world-readable, otherwise a malicious app will
+ * be able to inject code to run. A suitable parameter for these output
+ * directories would be something like this:
+ * {@code getApplicationContext().getDir("dx", Context.MODE_PRIVATE); }
+ *
+ * @param parent the parent ClassLoader to be used when loading
+ * our generated types
+ * @param dexOutputDir the destination directory wherein we will write
+ * emitted .dex files before they end up in the cache directory
+ * @param dexOptCacheDir where optimized .dex files are to be written
*/
- public ClassLoader load(ClassLoader parent) throws IOException {
+ public ClassLoader load(ClassLoader parent, File dexOutputDir, File dexOptCacheDir)
+ throws IOException {
byte[] dex = generate();
/*
@@ -128,7 +150,7 @@ public final class DexGenerator {
*
* TODO: load the dex from memory where supported.
*/
- File result = File.createTempFile("Generated", ".jar");
+ File result = File.createTempFile("Generated", ".jar", dexOutputDir);
result.deleteOnExit();
JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
@@ -136,9 +158,9 @@ public final class DexGenerator {
jarOut.closeEntry();
jarOut.close();
try {
- Class<?> pathClassLoader = Class.forName("dalvik.system.PathClassLoader");
- return (ClassLoader) pathClassLoader.getConstructor(String.class, ClassLoader.class)
- .newInstance(result.getPath(), parent);
+ return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
+ .getConstructor(String.class, String.class, String.class, ClassLoader.class)
+ .newInstance(result.getPath(), dexOptCacheDir.getAbsolutePath(), null, parent);
} catch (ClassNotFoundException e) {
throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
} catch (InvocationTargetException e) {