summaryrefslogtreecommitdiffstats
path: root/dalvik
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:03:55 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:03:55 -0800
commitdd828f42a5c83b4270d4fbf6fce2da1878f1e84a (patch)
treefdd4b68fa1020f2b6426034c94823419a7236200 /dalvik
parentfdb2704414a9ed92394ada0d1395e4db86889465 (diff)
downloadlibcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.zip
libcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.tar.gz
libcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'dalvik')
-rw-r--r--dalvik/src/main/java/dalvik/annotation/AndroidOnly.java39
-rw-r--r--dalvik/src/main/java/dalvik/annotation/BrokenTest.java38
-rw-r--r--dalvik/src/main/java/dalvik/annotation/HostController.java39
-rw-r--r--dalvik/src/main/java/dalvik/annotation/KnownFailure.java40
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestInfo.java13
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestLevel.java86
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestTarget.java16
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestTargetClass.java11
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestTargetNew.java66
-rw-r--r--dalvik/src/main/java/dalvik/annotation/TestTargets.java43
-rw-r--r--dalvik/src/main/java/dalvik/annotation/ToBeFixed.java45
-rw-r--r--dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java59
-rw-r--r--dalvik/src/main/java/dalvik/annotation/package.html9
-rw-r--r--dalvik/src/main/java/dalvik/bytecode/package.html8
-rw-r--r--dalvik/src/main/java/dalvik/system/AllocationLimitError.java10
-rw-r--r--dalvik/src/main/java/dalvik/system/DexClassLoader.java362
-rw-r--r--dalvik/src/main/java/dalvik/system/DexFile.java172
-rw-r--r--dalvik/src/main/java/dalvik/system/PathClassLoader.java223
-rw-r--r--dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java10
-rw-r--r--dalvik/src/main/java/dalvik/system/StaleDexCacheError.java10
-rw-r--r--dalvik/src/main/java/dalvik/system/TemporaryDirectory.java2
-rw-r--r--dalvik/src/main/java/dalvik/system/TouchDex.java20
-rw-r--r--dalvik/src/main/java/dalvik/system/VMDebug.java99
-rw-r--r--dalvik/src/main/java/dalvik/system/VMRuntime.java4
-rw-r--r--dalvik/src/main/java/dalvik/system/VMStack.java25
-rw-r--r--dalvik/src/main/java/dalvik/system/Zygote.java69
-rw-r--r--dalvik/src/main/java/dalvik/system/package.html8
27 files changed, 1362 insertions, 164 deletions
diff --git a/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java b/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java
new file mode 100644
index 0000000..d55991b
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test-case as Android-only, that is, it should not be executed on
+ * other systems.
+ *
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface AndroidOnly {
+
+ /**
+ * Plain text reason for adding this annotation.
+ */
+ String value();
+
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/BrokenTest.java b/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
new file mode 100644
index 0000000..961de41
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test case as broken. This means the test case should be fixed.
+ *
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+public @interface BrokenTest {
+
+ /**
+ * Plain text reason for adding this annotation.
+ */
+ String value();
+
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/HostController.java b/dalvik/src/main/java/dalvik/annotation/HostController.java
new file mode 100644
index 0000000..2ccc292
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/HostController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Record the host side controller information for a test method,
+ * so that the CTS host can locate correspond host side unit while running it.
+ * {@hide pending API Council approval}
+ *
+ * @since Android 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+public @interface HostController {
+
+ /**
+ * The host controller method name.
+ */
+ String name() default "";
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/KnownFailure.java b/dalvik/src/main/java/dalvik/annotation/KnownFailure.java
new file mode 100644
index 0000000..f5040bb
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/KnownFailure.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test case as a known failure. This means the underlying
+ * implementation should be fixed. Seems to be similar to @code{@ToBeFixed}, so
+ * maybe the two can be merged at some point.
+ *
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+public @interface KnownFailure {
+
+ /**
+ * Plain text reason for adding this annotation.
+ */
+ String value();
+
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestInfo.java b/dalvik/src/main/java/dalvik/annotation/TestInfo.java
index e9c2128..876e0bf 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestInfo.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestInfo.java
@@ -43,6 +43,19 @@ public @interface TestInfo {
String notes() default "";
/**
+ * Specifies the current level of coverage the test has.
+ */
+ TestLevel level() default TestLevel.PARTIAL;
+
+ /**
+ * Specifies the purpose (either if it is noteworth to mention such as if
+ * it is testing a specific parameter combination) or the covered test
+ * aspects (exceptions, normal cases, border edge cases, etc.) in
+ * case the level is Level.PARTIAL
+ */
+ String purpose() default "";
+
+ /**
* Specifies an array of target methods.
*/
TestTarget[] targets();
diff --git a/dalvik/src/main/java/dalvik/annotation/TestLevel.java b/dalvik/src/main/java/dalvik/annotation/TestLevel.java
new file mode 100644
index 0000000..ff9ddb3
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/TestLevel.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+/**
+ * Defines an enumeration of possible states a test case can be in.
+ *
+ * @since Android 1.0
+ * @hide
+ */
+public enum TestLevel {
+
+ /**
+ * Indicates that a test method completely tests its target API method.
+ */
+ COMPLETE,
+
+ /**
+ * Indicates that a test method partially tests its target API method and
+ * that together with all other {@code PARTIAL_COMPLETE} tests for the same
+ * method it is sufficient.
+ */
+ PARTIAL_COMPLETE,
+
+ /**
+ * Just for compatibility purposes, will be removed later.
+ */
+ PARTIAL_OK,
+
+ /**
+ * Indicates that a test method partially tests its target API method. It
+ * needs a second review phase to find out if the sum of all partial tests
+ * is sufficient for completely testing the target API method. If yes, the
+ * level has to be changed to {@code PARTIAL_COMPLETE}.
+ */
+ PARTIAL,
+
+ /**
+ * Indicates that a test method is known to not completely test an API
+ * method but the missing test steps are too complex and costly to
+ * implement. This level is positioned somewhere between {@code PARTIAL}
+ * and {@code COMPLETE}.
+ */
+ SUFFICIENT,
+
+ /**
+ * Indicates that a test method provides additional testing for an API
+ * method for which there already exists one {@code COMPLETE} or a set of
+ * {@code PARTIAL_COMPLETE} tests. This level may also be used for test
+ * methods that test a concept which can not be directly attributed to
+ * the specification of an API method or class.
+ */
+ ADDITIONAL,
+
+ /**
+ * Indicates that there is nothing to test in an API method, for example if
+ * the specification states that a method does nothing.
+ */
+ NOT_NECESSARY,
+
+ /**
+ * Indicates that it is very hard or impossible to test an API method.
+ */
+ NOT_FEASIBLE,
+
+ /**
+ * Indicates that the tests is either insufficient or wrong. Something needs
+ * to be done about it.
+ */
+ TODO,
+
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTarget.java b/dalvik/src/main/java/dalvik/annotation/TestTarget.java
index feefa05..7cbddca 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTarget.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTarget.java
@@ -25,6 +25,8 @@ import java.lang.annotation.Target;
* Defines an annotation used be used within the TestInfo annotation. It
* specifies a single method target for the test (but can be used multiple
* times).
+ *
+ * @since Android 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.ANNOTATION_TYPE })
@@ -33,7 +35,19 @@ public @interface TestTarget {
/**
* Specifies the name of the method that is being tested.
*/
- String methodName();
+ String methodName() default "";
+
+ /**
+ * Specifies the name of a concept being tested. Use this if
+ * {@code methodName} is not accurate enough. E.g. for
+ * {@link java.util.regex.Pattern#compile(String)} {@code methodName} is not
+ * sufficient since the String contains a pattern with its own syntax which
+ * has to be tested with different aspects. Areas concerned are e.g. JDBC
+ * (SELECT, INSERT, UPDATE, DELETE, ...), regex (character sets,
+ * operators,...), formatters (DecimalFormat, DateFormat, ChoiceFormat,
+ * ...), ...
+ */
+ String conceptName() default "";
/**
* Specifies the signature of the method that is being tested, in terms of
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
index 59d104a..acbc1f1 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
@@ -21,11 +21,15 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import dalvik.annotation.TestTargetNew;
+
/**
* Defines an annotation for test classes that allows to link them to the class
* that is being tested. The current assumption is that the test are somewhat
* organized according to the API classes they test. Might be too strict for
* some cases.
+ *
+ * @since Android 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@@ -36,4 +40,9 @@ public @interface TestTargetClass {
*/
Class<?> value();
-}
+ /**
+ * Option to specify untested methods for the class.
+ * @hide
+ */
+ TestTargetNew[] untestedMethods() default {};
+} \ No newline at end of file
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java b/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
new file mode 100644
index 0000000..b8be0cb
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Defines an annotation used be used within the TestInfo annotation. It
+ * specifies a single method target for the test (but can be used multiple
+ * times).
+ *
+ * @since Android 1.0
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
+public @interface TestTargetNew {
+
+ /**
+ * Specifies the name of the API method that is being tested. This field
+ * may be left empty if the test target is a concept implemented in a
+ * class rather than a concrete API method.
+ */
+ String method() default "";
+
+ /**
+ * Specifies the signature of the API method that is being tested, in terms
+ * of Java classes.
+ */
+ Class<?>[] args() default {};
+
+ /**
+ * Specifies the class to which the tested method belongs. If this value is
+ * not provided, the class identified in @TestTargetClass is used by the
+ * test progress doclet.
+ */
+ Class<?> clazz(); // default void.class;
+
+ /**
+ * Specifies the level of coverage the tested API method has.
+ */
+ TestLevel level();
+
+ /**
+ * Specifies noteworthy plain-text information about the test, for example
+ * if something is NOT covered by the test method.
+ */
+ String notes() default "";
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargets.java b/dalvik/src/main/java/dalvik/annotation/TestTargets.java
new file mode 100644
index 0000000..ead6149
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargets.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import dalvik.annotation.TestTargetNew;
+
+/**
+ * Defines an annotation for test classes that allows to link them to the class
+ * that is being tested. The current assumption is that the test are somewhat
+ * organized according to the API classes they test. Might be too strict for
+ * some cases.
+ *
+ * @since Android 1.0
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+public @interface TestTargets {
+
+ /**
+ * Specifies the API methods that are tested by the annotated test method.
+ */
+ TestTargetNew[] value();
+} \ No newline at end of file
diff --git a/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java b/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
new file mode 100644
index 0000000..6985929
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Defines an annotation for test methods that indicate the test method
+ * need to be fixed in future.
+ * {@hide pending API Council approval}
+ *
+ * @since Android 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+public @interface ToBeFixed {
+
+ /**
+ * Specifies the related bug number on CTS bug tracking system.
+ */
+ String bug() default "";
+
+ /**
+ * Specifies why this method need to be fixed. If we think it's a bug, explain
+ * the expectation and the actual result.
+ */
+ String explanation() default "";
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java b/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java
new file mode 100644
index 0000000..019e4b0
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for "virtual" implementation classes. These are classes that have
+ * the following attributes:
+ * <ul>
+ * <li>they implement a public interface or are a concrete implementation of a
+ * public abstract class,</li>
+ * <li>they are not public,</li>
+ * <li>instances can only be retrieved through some kind of factory method.</li>
+ * </ul>
+ * <p>
+ * Example: {@code MessageDigest} is an abstract class. Concrete implementations
+ * of message digest algorithms such as MD5 and SHA-1 can only be retrieved
+ * through one of the static {@code getInstance} methods of
+ * {@code MessageDigest}, which accept the desired algorithm as a string
+ * parameter and return an implementation accordingly.
+ * </p>
+ * <p>
+ * Even though the concrete implementation class for a message digest algorithm
+ * is not known, we need to be able to indicate that such a class exists and
+ * that it must be tested. This is done by defining corresponding classes and
+ * annotating them with {@code @VirtualTestTarget}. This class can then be
+ * used in the {@code @TestTargetClass} annotation with which we annotate
+ * {@code TestCase} subclasses.
+ *
+ * @since Android 1.0
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+public @interface VirtualTestTarget {
+
+ /**
+ * Field for comments.
+ */
+ String value() default "";
+} \ No newline at end of file
diff --git a/dalvik/src/main/java/dalvik/annotation/package.html b/dalvik/src/main/java/dalvik/annotation/package.html
new file mode 100644
index 0000000..fc7cf07
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/package.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <p>
+ Defines some annotations that are used within the Android system, either
+ for the core libraries or for testing purposes.
+ </p>
+ @since Android 1.0
+ </body>
+</html>
diff --git a/dalvik/src/main/java/dalvik/bytecode/package.html b/dalvik/src/main/java/dalvik/bytecode/package.html
new file mode 100644
index 0000000..1a6d7c4
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/bytecode/package.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <p>
+ Provides classes surrounding the Dalvik bytecode.
+ </p>
+ @since Android 1.0
+ </body>
+</html>
diff --git a/dalvik/src/main/java/dalvik/system/AllocationLimitError.java b/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
index 9747578..85f7de6 100644
--- a/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
+++ b/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
@@ -17,18 +17,22 @@
package dalvik.system;
/**
- * This is thrown when an allocation limit is exceeded.
+ * Is thrown when an allocation limit is exceeded.
+ *
+ * @since Android 1.0
*/
public class AllocationLimitError extends VirtualMachineError {
/**
- * Initialize exception with default values.
+ * Creates a new exception instance and initializes it with default values.
*/
public AllocationLimitError() {
super();
}
/**
- * Initialize exception with the supplied message string.
+ * Creates a new exception instance and initializes it with a given message.
+ *
+ * @param detailMessage the error message
*/
public AllocationLimitError(String detailMessage) {
super(detailMessage);
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
new file mode 100644
index 0000000..cb2f76d
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.zip.ZipFile;
+import java.net.MalformedURLException;
+
+import dalvik.system.DexFile;
+
+/**
+ * Provides a simple {@link ClassLoader} implementation that operates on a
+ * list of jar/apk files with classes.dex entries. The directory that
+ * holds the optimized form of the files is specified explicitly. This
+ * can be used to execute code not installed as part of an application.
+ *
+ * The best place to put the optimized DEX files is in app-specific
+ * storage, so that removal of the app will automatically remove the
+ * optimized DEX files. If other storage is used (e.g. /sdcard), the
+ * app may not have an opportunity to remove them.
+ */
+public class DexClassLoader extends ClassLoader {
+
+ private static final boolean VERBOSE_DEBUG = false;
+
+ /* constructor args, held for init */
+ private final String mRawDexPath;
+ private final String mRawLibPath;
+ private final String mDexOutputPath;
+
+ private boolean mInitialized;
+
+ /*
+ * Parallel arrays for jar/apk files.
+ *
+ * (could stuff these into an object and have a single array;
+ * improves clarity but adds overhead)
+ */
+ private File[] mFiles; // source file Files, for rsrc URLs
+ private ZipFile[] mZips; // source zip files, with resources
+ private DexFile[] mDexs; // opened, prepped DEX files
+
+ /*
+ * Native library path.
+ */
+ private String[] mLibPaths;
+
+
+ /**
+ * Creates a {@code DexClassLoader} that finds interpreted and native
+ * code. Interpreted classes are found in a set of DEX files contained
+ * in Jar or APK files.
+ *
+ * The path lists are separated using the character specified by
+ * the "path.separator" system property, which defaults to ":".
+ *
+ * @param dexPath
+ * the list of jar/apk files containing classes and resources
+ * @param dexOutputDir
+ * directory where optimized DEX files should be written
+ * @param libPath
+ * the list of directories containing native libraries; may be null
+ * @param parent
+ * the parent class loader
+ */
+ public DexClassLoader(String dexPath, String dexOutputDir, String libPath,
+ ClassLoader parent) {
+
+ super(parent);
+
+ if (dexPath == null || dexOutputDir == null)
+ throw new NullPointerException();
+
+ mRawDexPath = dexPath;
+ mDexOutputPath = dexOutputDir;
+ mRawLibPath = libPath;
+ }
+
+ /**
+ * Complete initialization on first use of the class loader.
+ */
+ private void ensureInit() {
+ if (mInitialized) {
+ return;
+ }
+
+ String[] dexPathList;
+
+ mInitialized = true;
+
+ dexPathList = mRawDexPath.split(":");
+ int length = dexPathList.length;
+
+ //System.out.println("DexClassLoader: " + dexPathList);
+ mFiles = new File[length];
+ mZips = new ZipFile[length];
+ mDexs = new DexFile[length];
+
+ /* open all Zip and DEX files up front */
+ for (int i = 0; i < length; i++) {
+ System.out.println("My path is: " + dexPathList[i]);
+ File pathFile = new File(dexPathList[i]);
+ mFiles[i] = pathFile;
+
+ if (pathFile.isFile()) {
+ try {
+ mZips[i] = new ZipFile(pathFile);
+ } catch (IOException ioex) {
+ // expecting IOException and ZipException
+ System.out.println("Failed opening '" + pathFile
+ + "': " + ioex);
+ //ioex.printStackTrace();
+ }
+
+ /* we need both DEX and Zip, because dex has no resources */
+ try {
+ String outputName =
+ generateOutputName(dexPathList[i], mDexOutputPath);
+ mDexs[i] = DexFile.loadDex(dexPathList[i], outputName, 0);
+ } catch (IOException ioex) {
+ // might be a resource-only zip
+ System.out.println("Failed loadDex '" + pathFile
+ + "': " + ioex);
+ }
+ } else {
+ if (VERBOSE_DEBUG)
+ System.out.println("Not found: " + pathFile.getPath());
+ }
+ }
+
+ /*
+ * Prep for native library loading.
+ */
+ String pathList = System.getProperty("java.library.path", ".");
+ String pathSep = System.getProperty("path.separator", ":");
+ String fileSep = System.getProperty("file.separator", "/");
+
+ if (mRawLibPath != null) {
+ if (pathList.length() > 0) {
+ pathList += pathSep + mRawLibPath;
+ }
+ else {
+ pathList = mRawLibPath;
+ }
+ }
+
+ mLibPaths = pathList.split(pathSep);
+ length = mLibPaths.length;
+
+ // Add a '/' to the end so we don't have to do the property lookup
+ // and concatenation later.
+ for (int i = 0; i < length; i++) {
+ if (!mLibPaths[i].endsWith(fileSep))
+ mLibPaths[i] += fileSep;
+ if (VERBOSE_DEBUG)
+ System.out.println("Native lib path " +i+ ": " + mLibPaths[i]);
+ }
+ }
+
+ /**
+ * Convert a source path name and an output directory to an output
+ * file name.
+ */
+ private static String generateOutputName(String sourcePathName,
+ String outputDir) {
+
+ StringBuilder newStr = new StringBuilder(80);
+
+ /* start with the output directory */
+ newStr.append(outputDir);
+ if (!outputDir.endsWith("/"))
+ newStr.append("/");
+
+ /* get the filename component of the path */
+ String sourceFileName;
+ int lastSlash = sourcePathName.lastIndexOf("/");
+ if (lastSlash < 0)
+ sourceFileName = sourcePathName;
+ else
+ sourceFileName = sourcePathName.substring(lastSlash+1);
+
+ /* replace ".jar", ".zip", whatever with ".odex" */
+ int lastDot = sourceFileName.lastIndexOf(".");
+ if (lastDot < 0)
+ newStr.append(sourceFileName);
+ else
+ newStr.append(sourceFileName, 0, lastDot);
+ newStr.append(".odex");
+
+ if (VERBOSE_DEBUG)
+ System.out.println("Output file will be " + newStr.toString());
+ return newStr.toString();
+ }
+
+ /**
+ * Finds a class. This method is called by {@code loadClass()} after the
+ * parent ClassLoader has failed to find a loaded class of the same name.
+ *
+ * @param name
+ * The name of the class to search for, in a human-readable form
+ * like "java.lang.String" or "java.net.URLClassLoader$3$1".
+ * @return the {@link Class} object representing the class
+ * @throws ClassNotFoundException
+ * if the class cannot be found
+ */
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ ensureInit();
+
+ if (VERBOSE_DEBUG)
+ System.out.println("DexClassLoader " + this
+ + ": findClass '" + name + "'");
+
+ byte[] data = null;
+ int length = mFiles.length;
+
+ for (int i = 0; i < length; i++) {
+ if (VERBOSE_DEBUG)
+ System.out.println(" Now searching: " + mFiles[i].getPath());
+
+ if (mDexs[i] != null) {
+ String slashName = name.replace('.', '/');
+ Class clazz = mDexs[i].loadClass(slashName, this);
+ if (clazz != null) {
+ if (VERBOSE_DEBUG)
+ System.out.println(" found");
+ return clazz;
+ }
+ }
+ }
+
+ throw new ClassNotFoundException(name + " in loader " + this);
+ }
+
+ /**
+ * Finds a resource. This method is called by {@code getResource()} after
+ * the parent ClassLoader has failed to find a loaded resource of the same
+ * name.
+ *
+ * @param name
+ * The name of the resource to find
+ * @return the location of the resource as a URL, or {@code null} if the
+ * resource is not found.
+ */
+ @Override
+ protected URL findResource(String name) {
+ ensureInit();
+
+ int length = mFiles.length;
+
+ for (int i = 0; i < length; i++) {
+ File pathFile = mFiles[i];
+ ZipFile zip = mZips[i];
+
+ if (zip.getEntry(name) != null) {
+ if (VERBOSE_DEBUG)
+ System.out.println(" found " + name + " in " + pathFile);
+ try {
+ // File.toURL() is compliant with RFC 1738 in always
+ // creating absolute path names. If we construct the
+ // URL by concatenating strings, we might end up with
+ // illegal URLs for relative names.
+ return new URL("jar:" + pathFile.toURL() + "!/" + name);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ if (VERBOSE_DEBUG)
+ System.out.println(" resource " + name + " not found");
+
+ return null;
+ }
+
+ /**
+ * Finds a native library. This method is called after the parent
+ * ClassLoader has failed to find a native library of the same name.
+ *
+ * @param libname
+ * The name of the library to find
+ * @return the complete path of the library, or {@code null} if the library
+ * is not found.
+ */
+ @Override
+ protected String findLibrary(String libname) {
+ ensureInit();
+
+ String fileName = System.mapLibraryName(libname);
+ for (int i = 0; i < mLibPaths.length; i++) {
+ String pathName = mLibPaths[i] + fileName;
+ File test = new File(pathName);
+
+ if (test.exists()) {
+ if (VERBOSE_DEBUG)
+ System.out.println(" found " + libname);
+ return pathName;
+ }
+ }
+
+ if (VERBOSE_DEBUG)
+ System.out.println(" library " + libname + " not found");
+ return null;
+ }
+
+ /**
+ * Returns package information for the given package. Unfortunately, the
+ * DexClassLoader doesn't really have this information, and as a non-secure
+ * ClassLoader, it isn't even required to, according to the spec. Yet, we
+ * want to provide it, in order to make all those hopeful callers of
+ * <code>myClass.getPackage().getName()</code> happy. Thus we construct a
+ * Package object the first time it is being requested and fill most of the
+ * fields with dummy values. The Package object is then put into the
+ * ClassLoader's Package cache, so we see the same one next time. We don't
+ * create Package objects for null arguments or for the default package.
+ * <p>
+ * There a limited chance that we end up with multiple Package objects
+ * representing the same package: It can happen when when a package is
+ * scattered across different JAR files being loaded by different
+ * ClassLoaders. Rather unlikely, and given that this whole thing is more or
+ * less a workaround, probably not worth the effort.
+ *
+ * @param name
+ * the name of the class
+ * @return the package information for the class, or {@code null} if there
+ * is not package information available for it
+ */
+ @Override
+ protected Package getPackage(String name) {
+ if (name != null && !"".equals(name)) {
+ synchronized(this) {
+ Package pack = super.getPackage(name);
+
+ if (pack == null) {
+ pack = definePackage(name, "Unknown", "0.0", "Unknown",
+ "Unknown", "0.0", "Unknown", null);
+ }
+
+ return pack;
+ }
+ }
+
+ return null;
+ }
+}
+
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 8fa1062..da51e45 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -24,80 +24,185 @@ import java.util.Enumeration;
/**
- * Manipulate DEX files. Similar in principle to java.util.zip.ZipFile.
- * Used primarily by class loaders.
- *
- * We don't directly open and read the DEX file here. They're mapped read-only
- * by the VM.
+ * Manipulates DEX files. The class is similar in principle to
+ * {@link java.util.zip.ZipFile}. It is used primarily by class loaders.
+ * <p>
+ * Note we don't directly open and read the DEX file here. They're memory-mapped
+ * read-only by the VM.
+ *
+ * @since Android 1.0
*/
public final class DexFile {
private final int mCookie;
private String mFileName;
/**
- * Open a DEX file from a File object.
+ * Opens a DEX file from a given File object. This will usually be a ZIP/JAR
+ * file with a "classes.dex" inside. The method should not be used for files
+ * inside the Dalvik cache.
+ *
+ * @cts What will happen if we refer to the Dalvik cache? Should be either
+ * specified or throw an exception...
+ *
+ * @param file
+ * the File object referencing the actual DEX file
+ *
+ * @throws IOException
+ * if an I/O error occurs, such as the file not being found or
+ * access rights missing for opening it
*/
public DexFile(File file) throws IOException {
this(file.getPath());
}
/**
- * Open a DEX file from a filename (preferrably a full path).
- *
- * This will usually be a Zip/Jar with a "classes.dex" inside. Do not
- * specify the "dalvik-cache" version directly.
+ * Opens a DEX file from a given filename. This will usually be a ZIP/JAR
+ * file with a "classes.dex" inside. The method should not be used for files
+ * inside the Dalvik cache.
+ *
+ * @cts What will happen if we refer to the Dalvik cache? Should be either
+ * specified or throw an exception...
+ *
+ * @param fileName
+ * the filename of the DEX file
+ *
+ * @throws IOException
+ * if an I/O error occurs, such as the file not being found or
+ * access rights missing for opening it
*/
public DexFile(String fileName) throws IOException {
String wantDex = System.getProperty("android.vm.dexfile", "false");
if (!wantDex.equals("true"))
throw new UnsupportedOperationException("No dex in this VM");
- mCookie = openDexFile(fileName);
+ mCookie = openDexFile(fileName, null, 0);
mFileName = fileName;
//System.out.println("DEX FILE cookie is " + mCookie);
}
/**
- * Get the name of the open file.
+ * Opens a DEX file from a given filename, using a specified file
+ * to hold the optimized data.
+ *
+ * @param sourceName
+ * Jar or APK file with "classes.dex".
+ * @param outputName
+ * File that will hold the optimized form of the DEX data.
+ * @param flags
+ * Enable optional features.
+ */
+ private DexFile(String sourceName, String outputName, int flags)
+ throws IOException {
+
+ String wantDex = System.getProperty("android.vm.dexfile", "false");
+ if (!wantDex.equals("true"))
+ throw new UnsupportedOperationException("No dex in this VM");
+
+ mCookie = openDexFile(sourceName, outputName, flags);
+ mFileName = sourceName;
+ //System.out.println("DEX FILE cookie is " + mCookie);
+ }
+
+ /**
+ * Open a DEX file, specifying the file in which the optimized DEX
+ * data should be written. If the optimized form exists and appears
+ * to be current, it will be used; if not, the VM will attempt to
+ * regenerate it.
+ *
+ * This is intended for use by applications that wish to download
+ * and execute DEX files outside the usual application installation
+ * mechanism. This function should not be called directly by an
+ * application; instead, use a class loader such as
+ * dalvik.system.DexClassLoader.
+ *
+ * @param sourcePathName
+ * Jar or APK file with "classes.dex". (May expand this to include
+ * "raw DEX" in the future.)
+ * @param outputPathName
+ * File that will hold the optimized form of the DEX data.
+ * @param flags
+ * Enable optional features. (Currently none defined.)
+ * @return
+ * A new or previously-opened DexFile.
+ * @throws IOException
+ * If unable to open the source or output file.
+ */
+ static public DexFile loadDex(String sourcePathName, String outputPathName,
+ int flags) throws IOException {
+
+ /*
+ * TODO: we may want to cache previously-opened DexFile objects.
+ * The cache would be synchronized with close(). This would help
+ * us avoid mapping the same DEX more than once when an app
+ * decided to open it multiple times. In practice this may not
+ * be a real issue.
+ */
+ return new DexFile(sourcePathName, outputPathName, flags);
+ }
+
+ /**
+ * Gets the name of the (already opened) DEX file.
+ *
+ * @return the file name
*/
public String getName() {
return mFileName;
}
/**
- * Close a DEX file.
- *
- * This may not be able to release any resources. If classes have
- * been loaded, the underlying storage can't be discarded.
+ * Closes the DEX file.
+ * <p>
+ * This may not be able to release any resources. If classes have been
+ * loaded, the underlying storage can't be discarded.
+ *
+ * @throws IOException
+ * if an I/O error occurs during closing the file, which
+ * normally should not happen
+ *
+ * @cts Second sentence is a bit cryptic.
*/
public void close() throws IOException {
closeDexFile(mCookie);
}
/**
- * Load a class. Returns the class on success, or a null reference
+ * Loads a class. Returns the class on success, or a {@code null} reference
* on failure.
- *
- * If you are not calling this from a class loader, this is most likely
- * not going to do what you want. Use Class.forName() instead.
- *
- * "name" should look like "java/lang/String".
- *
- * I'm not throwing an exception if the class isn't found because I
- * don't want to be throwing exceptions wildly every time we load a
- * class that isn't in the first DEX file we look at. This method
- * *will* throw exceptions for anything that isn't ClassNotFoundException.
+ * <p>
+ * If you are not calling this from a class loader, this is most likely not
+ * going to do what you want. Use {@link Class#forName(String)} instead.
+ * <p>
+ * The method does not throw {@link ClassNotFoundException} if the class
+ * isn't found because it isn't feasible to throw exceptions wildly every
+ * time a class is not found in the first DEX file we look at. It will
+ * throw exceptions for other failures, though.
+ *
+ * @param name
+ * the class name, which should look like "java/lang/String"
+ *
+ * @param loader
+ * the class loader that tries to load the class (in most cases
+ * the caller of the method
+ *
+ * @return the {@link Class} object representing the class, or {@code null}
+ * if the class cannot be loaded
+ *
+ * @cts Exception comment is a bit cryptic. What exception will be thrown?
*/
public Class loadClass(String name, ClassLoader loader) {
return defineClass(name, loader, mCookie,
null);
//new ProtectionDomain(name) /*DEBUG ONLY*/);
}
+
native private static Class defineClass(String name, ClassLoader loader,
int cookie, ProtectionDomain pd);
/**
* Enumerate the names of the classes in this DEX file.
+ *
+ * @return an enumeration of names of classes contained in the DEX file, in
+ * the usual internal form (like "java/lang/String").
*/
public Enumeration<String> entries() {
return new DFEnum(this);
@@ -128,7 +233,11 @@ public final class DexFile {
native private static String[] getClassNameList(int cookie);
/**
- * GC helper.
+ * Called when the class is finalized. Makes sure the DEX file is closed.
+ *
+ * @throws IOException
+ * if an I/O error occurs during closing the file, which
+ * normally should not happen
*/
protected void finalize() throws IOException {
close();
@@ -138,7 +247,12 @@ public final class DexFile {
* Open a DEX file. The value returned is a magic VM cookie. On
* failure, an IOException is thrown.
*/
- native private static int openDexFile(String fileName) throws IOException;
+ native private static int openDexFile(String sourceName, String outputName,
+ int flags) throws IOException;
+
+ /*
+ * Close DEX file.
+ */
native private static void closeDexFile(int cookie);
/**
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 4dacf3f..94edfa1 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -23,6 +23,9 @@ import java.io.InputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.net.MalformedURLException;
@@ -30,9 +33,12 @@ import java.net.MalformedURLException;
import dalvik.system.DexFile;
/**
- * Simple ClassLoader implementation.
- *
- * This loads classes from a colon-separated list.
+ * Provides a simple {@link ClassLoader} implementation that operates on a list
+ * of files and directories in the local file system, but does not attempt to
+ * load classes from the network. Android uses this class for its system class
+ * loader and for its application class loader(s).
+ *
+ * @since Android 1.0
*/
public class PathClassLoader extends ClassLoader {
@@ -48,22 +54,43 @@ public class PathClassLoader extends ClassLoader {
private String[] mLibPaths;
/**
- * Create a ClassLoader that finds files in the specified path.
+ * Creates a {@code PathClassLoader} that operates on a given list of files
+ * and directories. This method is equivalent to calling
+ * {@link #PathClassLoader(String, String, ClassLoader) with a {@code null}
+ * value for the second argument (see description there).
+ *
+ * @param path
+ * the list of files and directories
+ *
+ * @param parent
+ * the parent class loader
*/
public PathClassLoader(String path, ClassLoader parent) {
this(path, null, parent);
}
/**
- * Create a ClassLoader that finds files in the specified path.
- *
- * The path is a colon-separated list of files and directories. For
- * Dalvik, this is usually a list of .jar and .apk filenames.
- *
- * @param path A colon-separated class path.
- * @param libPath A colon-separated list of directories where native
- * libraries can be found.
- * @param parent The parent class loader.
+ * Creates a {@code PathClassLoader} that operates on two given lists of
+ * files and directories. The entries of the first list should be one of the
+ * following:
+ * <ul>
+ * <li>Directories containing classes or resources.
+ * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file.
+ * <li>"classes.dex" files.
+ * </ul>
+ * The entries of the second list should be directories containing native
+ * library files. Both lists are separated using the character specified by
+ * the "path.separator" system property, which, on Android, defaults to ":".
+ *
+ * @param path
+ * the list of files and directories containing classes and
+ * resources
+ *
+ * @param libPath
+ * the list of directories containing native libraries
+ *
+ * @param parent
+ * the parent class loader
*/
public PathClassLoader(String path, String libPath, ClassLoader parent) {
super(parent);
@@ -148,14 +175,15 @@ public class PathClassLoader extends ClassLoader {
}
/**
- * Find the class with the specified name. None of our ancestors were
- * able to find it, so it's up to us now.
- *
- * "name" is a "binary name", e.g. "java.lang.String" or
- * "java.net.URLClassLoader$3$1".
- *
- * This method will either return a valid Class object or throw an
- * exception. Does not return null.
+ * Finds a class. This method is called by {@code loadClass()} after the
+ * parent ClassLoader has failed to find a loaded class of the same name.
+ *
+ * @param name
+ * The name of the class to search for, in a human-readable form
+ * like "java.lang.String" or "java.net.URLClassLoader$3$1".
+ * @return the {@link Class} object representing the class
+ * @throws ClassNotFoundException
+ * if the class cannot be found
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException
@@ -215,10 +243,17 @@ public class PathClassLoader extends ClassLoader {
throw new ClassNotFoundException(name + " in loader " + this);
}
- /*
- * Find a resource by name. This could be in a directory or in an
- * archive.
+ /**
+ * Finds a resource. This method is called by {@code getResource()} after
+ * the parent ClassLoader has failed to find a loaded resource of the same
+ * name.
+ *
+ * @param name
+ * The name of the resource to find
+ * @return the location of the resource as a URL, or {@code null} if the
+ * resource is not found.
*/
+ @Override
protected URL findResource(String name) {
ensureInit();
@@ -227,44 +262,75 @@ public class PathClassLoader extends ClassLoader {
int length = mPaths.length;
for (int i = 0; i < length; i++) {
- File pathFile = mFiles[i];
- ZipFile zip = mZips[i];
- if (zip != null) {
- if (isInArchive(zip, name)) {
- //System.out.println(" found " + name + " in " + pathFile);
- try {
- // File.toURL() is compliant with RFC 1738 in always
- // creating absolute path names. If we construct the
- // URL by concatenating strings, we might end up with
- // illegal URLs for relative names.
- return new URL("jar:" + pathFile.toURL() + "!/" + name);
- }
- catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- } else if (pathFile.isDirectory()) {
- File dataFile = new File(mPaths[i] + "/" + name);
- if (dataFile.exists()) {
- //System.out.println(" found resource " + name);
- try {
- // Same as archive case regarding URL construction.
- return dataFile.toURL();
- }
- catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- } else if (pathFile.isFile()) {
- } else {
- System.err.println("PathClassLoader: can't find '"
- + mPaths[i] + "'");
+ URL result = findResource(name, i);
+ if(result != null) {
+ return result;
}
}
return null;
}
+ /**
+ * Finds an enumeration of URLs for the resource with the specified name.
+ *
+ * @param resName
+ * the name of the resource to find.
+ * @return an enumeration of {@code URL} objects for the requested resource.
+ * @since Android 1.0
+ */
+ @Override
+ protected Enumeration<URL> findResources(String resName) {
+ ensureInit();
+
+ int length = mPaths.length;
+ ArrayList<URL> results = new ArrayList<URL>();
+
+ for (int i = 0; i < length; i++) {
+ URL result = findResource(resName, i);
+ if(result != null) {
+ results.add(result);
+ }
+ }
+ return new EnumerateListArray<URL>(results);
+ }
+
+ private URL findResource(String name, int i) {
+ File pathFile = mFiles[i];
+ ZipFile zip = mZips[i];
+ if (zip != null) {
+ if (isInArchive(zip, name)) {
+ //System.out.println(" found " + name + " in " + pathFile);
+ try {
+ // File.toURL() is compliant with RFC 1738 in always
+ // creating absolute path names. If we construct the
+ // URL by concatenating strings, we might end up with
+ // illegal URLs for relative names.
+ return new URL("jar:" + pathFile.toURL() + "!/" + name);
+ }
+ catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ } else if (pathFile.isDirectory()) {
+ File dataFile = new File(mPaths[i] + "/" + name);
+ if (dataFile.exists()) {
+ //System.out.println(" found resource " + name);
+ try {
+ // Same as archive case regarding URL construction.
+ return dataFile.toURL();
+ }
+ catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ } else if (pathFile.isFile()) {
+ } else {
+ System.err.println("PathClassLoader: can't find '"
+ + mPaths[i] + "'");
+ }
+ return null;
+ }
/*
* Load the contents of a file from a file in a directory.
@@ -345,11 +411,14 @@ public class PathClassLoader extends ClassLoader {
return zip.getEntry(name) != null;
}
- /**
- * Find a native library.
- *
- * Return the full pathname of the first appropriate-looking file
- * we find.
+ /**
+ * Finds a native library. This method is called after the parent
+ * ClassLoader has failed to find a native library of the same name.
+ *
+ * @param libname
+ * The name of the library to find
+ * @return the complete path of the library, or {@code null} if the library
+ * is not found.
*/
protected String findLibrary(String libname) {
ensureInit();
@@ -368,9 +437,9 @@ public class PathClassLoader extends ClassLoader {
/**
* Returns package information for the given package. Unfortunately, the
- * PathClassLoader doesn't really have this information, and as a
- * non-secure ClassLoader, it isn't even required to, according to the spec.
- * Yet, we want to provide it, in order to make all those hopeful callers of
+ * PathClassLoader doesn't really have this information, and as a non-secure
+ * ClassLoader, it isn't even required to, according to the spec. Yet, we
+ * want to provide it, in order to make all those hopeful callers of
* <code>myClass.getPackage().getName()</code> happy. Thus we construct a
* Package object the first time it is being requested and fill most of the
* fields with dummy values. The Package object is then put into the
@@ -382,6 +451,11 @@ public class PathClassLoader extends ClassLoader {
* scattered across different JAR files being loaded by different
* ClassLoaders. Rather unlikely, and given that this whole thing is more or
* less a workaround, probably not worth the effort.
+ *
+ * @param name
+ * the name of the class
+ * @return the package information for the class, or {@code null} if there
+ * is not package information available for it
*/
@Override
protected Package getPackage(String name) {
@@ -400,4 +474,25 @@ public class PathClassLoader extends ClassLoader {
return null;
}
+ /*
+ * Create an Enumeration for an ArrayList.
+ */
+ private static class EnumerateListArray<T> implements Enumeration<T> {
+ private final ArrayList mList;
+ private int i = 0;
+
+ EnumerateListArray(ArrayList list) {
+ mList = list;
+ }
+
+ public boolean hasMoreElements() {
+ return i < mList.size();
+ }
+
+ public T nextElement() {
+ if (i >= mList.size())
+ throw new NoSuchElementException();
+ return (T) mList.get(i++);
+ }
+ };
}
diff --git a/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java b/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
index defa182..c85caee 100644
--- a/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
+++ b/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
@@ -17,18 +17,22 @@
package dalvik.system;
/**
- * This is thrown when the VM identifies a potential deadlock.
+ * Is thrown when the VM identifies a potential deadlock.
+ *
+ * @since Android 1.0
*/
public class PotentialDeadlockError extends VirtualMachineError {
/**
- * Initialize exception with default values.
+ * Creates a new exception instance and initializes it with default values.
*/
public PotentialDeadlockError() {
super();
}
/**
- * Initialize exception with the supplied message string.
+ * Creates a new exception instance and initializes it with a given message.
+ *
+ * @param detailMessage the error message
*/
public PotentialDeadlockError(String detailMessage) {
super(detailMessage);
diff --git a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java b/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
index a124058..44a40a5 100644
--- a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
+++ b/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
@@ -17,19 +17,21 @@
package dalvik.system;
/**
- * This is thrown when the VM determines that a dex file's cache
- * is out of date, and that there is no way to recreate it.
+ * Is thrown when the VM determines that a DEX file's cache is out of date, and
+ * that there is no way to recreate it.
*/
public class StaleDexCacheError extends VirtualMachineError {
/**
- * Initialize exception with default values.
+ * Creates a new exception instance and initializes it with default values.
*/
public StaleDexCacheError() {
super();
}
/**
- * Initialize exception with the supplied message string.
+ * Creates a new exception instance and initializes it with a given message.
+ *
+ * @param detailMessage the error message
*/
public StaleDexCacheError(String detailMessage) {
super(detailMessage);
diff --git a/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java b/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
index ae0ecb2..2f909ac 100644
--- a/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
+++ b/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
@@ -25,6 +25,8 @@ import java.util.logging.Logger;
* call into this class with an appropriate base directory during its
* startup, as a reasonably easy way to get the standard property
* <code>java.io.tmpdir</code> to point at something useful.
+ *
+ * @since Android 1.0
*/
public class TemporaryDirectory {
/** system property name for the temporary directory */
diff --git a/dalvik/src/main/java/dalvik/system/TouchDex.java b/dalvik/src/main/java/dalvik/system/TouchDex.java
index 5aedbf5..2dbc3ea 100644
--- a/dalvik/src/main/java/dalvik/system/TouchDex.java
+++ b/dalvik/src/main/java/dalvik/system/TouchDex.java
@@ -23,24 +23,30 @@ import java.io.File;
import java.io.FilenameFilter;
/**
- * Induce optimization/verification of a set of DEX files.
+ * Induces optimization/verification of a set of DEX files.
*
* TODO: This class is public, so SystemServer can access it. This is NOT
* the correct long-term solution; once we have a real installer and/or
* dalvik-cache manager, this class should be removed.
+ *
+ * @cts See to-do about removing this class...
+ *
+ * @since Android 1.0
*/
public class TouchDex {
/**
- * Fork a process, make sure the DEX files are prepped, and return
+ * Forks a process, makes sure the DEX files are prepared, and returns
* when everything is finished.
- *
+ * <p>
* The filenames must be the same as will be used when the files are
* actually opened, because the dalvik-cache filename is based upon
- * this filename. (The absolute path to the jar/apk should work.)
+ * this filename. (The absolute path to the JAR/ZIP/APK should work.)
*
- * @param dexFiles Colon-separated list of DEX files.
+ * @param dexFiles a colon-separated list of DEX files.
* @return zero on success
+ *
+ * @cts What about error cases?
*/
public static int start(String dexFiles) {
return trampoline(dexFiles, System.getProperty("java.boot.class.path"));
@@ -55,9 +61,9 @@ public class TouchDex {
native private static int trampoline(String dexFiles, String bcp);
/**
- * We continue here in the child process. args[0] can be a colon-separated
+ * The entry point for the child process. args[0] can be a colon-separated
* path list, or "-" to read from stdin.
- *
+ * <p>
* Alternatively, if we're invoked directly from the command line we
* just start here (skipping the fork/exec stuff).
*
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 64a8321..9034ac1 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -17,14 +17,20 @@
package dalvik.system;
/**
- * VM-specific debug features. Though this class and many of its members
- * are public, this class is meant to be wrapped in a more friendly way
- * for use by application developers. On the Android platform, the
+ * Provides access to some VM-specific debug features. Though this class and
+ * many of its members are public, this class is meant to be wrapped in a more
+ * friendly way for use by application developers. On the Android platform, the
* recommended way to access this functionality is through the class
* <code>android.os.Debug</code>.
+ *
+ * @cts Please complete the spec.
+ *
+ * @since Android 1.0
*/
public final class VMDebug {
- /** default method trace data file name */
+ /**
+ * Specifies the default method trace data file name.
+ */
static public final String DEFAULT_METHOD_TRACE_FILE_NAME = "/sdcard/dmtrace.trace";
/**
@@ -88,13 +94,24 @@ public final class VMDebug {
private VMDebug() {}
/**
- * Time, in msec, since the last debugger activity. -1 if debugger is
- * not connected.
+ * Returns the time since the last known debugger activity.
+ *
+ * @return the time in milliseconds, or -1 if the debugger is not connected
*/
public static native long lastDebuggerActivity();
/**
- * Determine if a debugger is currently attached.
+ * Determines if debugging is enabled in this VM. If debugging is not
+ * enabled, a debugger cannot be attached.
+ *
+ * @return true if debugging is enabled
+ */
+ public static native boolean isDebuggingEnabled();
+
+ /**
+ * Determines if a debugger is currently attached.
+ *
+ * @return true if (and only if) a debugger is connected
*/
public static native boolean isDebuggerConnected();
@@ -134,30 +151,31 @@ public final class VMDebug {
int bufferSize, int flags);
/**
- * Stop method tracing.
+ * Stops method tracing.
*/
public static native void stopMethodTracing();
/**
- * Start sending Dalvik method trace info to the emulator.
+ * Starts sending Dalvik method trace info to the emulator.
*/
public static native void startEmulatorTracing();
/**
- * Stop sending Dalvik method trace info to the emulator.
+ * Stops sending Dalvik method trace info to the emulator.
*/
public static native void stopEmulatorTracing();
/**
- * Get an indication of thread CPU usage. The value returned
- * indicates the amount of time that the current thread has spent
- * executing code or waiting for certain types of I/O.
- *
- * The time is expressed in nanoseconds, and is only meaningful
- * when compared to the result from an earlier call. Note that
- * nanosecond resolution does not imply nanosecond accuracy.
- *
- * On system which don't support this operation, the call returns -1.
+ * Get an indication of thread CPU usage. The value returned indicates the
+ * amount of time that the current thread has spent executing code or
+ * waiting for certain types of I/O.
+ * <p>
+ * The time is expressed in nanoseconds, and is only meaningful when
+ * compared to the result from an earlier call. Note that nanosecond
+ * resolution does not imply nanosecond accuracy.
+ *
+ * @return the CPU usage. A value of -1 means the system does not support
+ * this feature.
*/
public static native long threadCpuTimeNanos();
@@ -171,23 +189,34 @@ public final class VMDebug {
public static native void resetAllocCount(int kinds);
/**
- * Establish an object allocation limit in the current thread. Useful
- * for catching regressions in code that is expected to operate
- * without causing any allocations.
- *
- * Use -1 to disable the limit.
- *
- * Returns the previous limit.
+ * Establishes an object allocation limit in the current thread. Useful for
+ * catching regressions in code that is expected to operate without causing
+ * any allocations. The limit is valid from the return of this method until
+ * it is either changed or the thread terminates.
+ *
+ * @param limit
+ * the new limit. A value of 0 means not a single new object may
+ * be allocated. A value of -1 disables the limit.
+ *
+ * @return the previous limit, or -1 if no limit was set
+ *
+ * @see #setGlobalAllocationLimit(int)
*/
public static native int setAllocationLimit(int limit);
/**
- * Establish an object allocation limit for the entire VM. Very much
- * like setAllocationLimit().
- *
- * Use -1 to disable the limit.
- *
- * Returns the previous limit.
+ * Establishes an object allocation limit for the entire VM. Useful for
+ * catching regressions in code that is expected to operate without causing
+ * any allocations. The limit is valid from the return of this method until
+ * it is either changed or the thread terminates.
+ *
+ * @param limit
+ * the new limit. A value of 0 means not a single new object may
+ * be allocated. A value of -1 disables the limit.
+ *
+ * @return the previous limit, or -1 if no limit was set
+ *
+ * @see #setAllocationLimit(int)
*/
public static native int setGlobalAllocationLimit(int limit);
@@ -200,12 +229,14 @@ public final class VMDebug {
public static native void resetInstructionCount();
/**
- * Dump a list of loaded class to the log file.
+ * Dumps a list of loaded class to the log file.
*/
public static native void printLoadedClasses(int flags);
/**
- * Get the number of loaded classes.
+ * Gets the number of loaded classes.
+ *
+ * @return the number of loaded classes
*/
public static native int getLoadedClassCount();
diff --git a/dalvik/src/main/java/dalvik/system/VMRuntime.java b/dalvik/src/main/java/dalvik/system/VMRuntime.java
index 615d301..5d5e600 100644
--- a/dalvik/src/main/java/dalvik/system/VMRuntime.java
+++ b/dalvik/src/main/java/dalvik/system/VMRuntime.java
@@ -20,6 +20,8 @@ package dalvik.system;
* Provides an interface to VM-global, Dalvik-specific features.
* An application cannot create its own Runtime instance, and must obtain
* one from the getRuntime method.
+ *
+ * @since Android 1.0
*/
public final class VMRuntime {
@@ -173,6 +175,8 @@ public final class VMRuntime {
/**
* Returns the number of externally-allocated bytes being tracked by
* trackExternalAllocation/Free().
+ *
+ * @return the number of bytes
*/
public native long getExternalBytesAllocated();
}
diff --git a/dalvik/src/main/java/dalvik/system/VMStack.java b/dalvik/src/main/java/dalvik/system/VMStack.java
index 5d7a7d3..9330c68 100644
--- a/dalvik/src/main/java/dalvik/system/VMStack.java
+++ b/dalvik/src/main/java/dalvik/system/VMStack.java
@@ -17,32 +17,41 @@
package dalvik.system;
/**
- * VM-internal classes for examining a stack.
+ * Provides a limited interface to the Dalvik VM stack. This class is mostly
+ * used for implementing security checks.
+ *
+ * @since Android 1.0
*/
public final class VMStack {
/**
- * Return the defining class loader of the caller's caller.
+ * Returns the defining class loader of the caller's caller.
+ *
+ * @return the requested class loader, or {@code null} if this is the
+ * bootstrap class loader.
*/
native public static ClassLoader getCallingClassLoader();
/**
- * Return the defining class loader of the caller's caller's caller.
+ * Returns the defining class loader of the caller's caller's caller.
+ *
+ * @return the requested class loader, or {@code null} if this is the
+ * bootstrap class loader.
*/
native public static ClassLoader getCallingClassLoader2();
/**
- * Create an array of classes from the methods at the top of the stack.
+ * Creates an array of classes from the methods at the top of the stack.
* We continue until we reach the bottom of the stack or exceed the
* specified maximum depth. If stopAtPrivileged is set, the last
* element of the array will be the caller of the most-recent privileged
* method.
- *
+ * <p>
* The topmost stack frame (this method) and the one above that (the
* caller) are excluded from the array. Frames with java.lang.reflect
* classes are skipped over.
- *
+ * <p>
* The classes in the array are the defining classes of the methods.
- *
+ * <p>
* This is expected to be identical to Harmony's VMStack.getClasses.
*
* @param maxDepth
@@ -55,7 +64,7 @@ public final class VMStack {
boolean stopAtPrivileged);
/**
- * Retrieve the stack trace from the specified thread.
+ * Retrieves the stack trace from the specified thread.
*
* @param t
* thread of interest
diff --git a/dalvik/src/main/java/dalvik/system/Zygote.java b/dalvik/src/main/java/dalvik/system/Zygote.java
index 5c527ac..9d98bb2 100644
--- a/dalvik/src/main/java/dalvik/system/Zygote.java
+++ b/dalvik/src/main/java/dalvik/system/Zygote.java
@@ -1,14 +1,40 @@
-// Copyright 2006 The Android Open Source Project
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package dalvik.system;
/**
- * Interfaces for supporting the Dalvik "zygote" feature, which allows
- * a VM instance to be partially initialized and then fork()'d from
- * the partially initialized state.
+ * Provides access to the Dalvik "zygote" feature, which allows a VM instance to
+ * be partially initialized and then fork()'d from the partially initialized
+ * state.
+ *
+ * @since Android 1.0
*/
-
public class Zygote {
+ /*
+ * Bit values for "debugFlags" argument. The definitions are duplicated
+ * in the native code.
+ */
+ /** enable debugging over JDWP */
+ public static final int DEBUG_ENABLE_DEBUGGER = 1;
+ /** enable JNI checks */
+ public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1;
+ /** enable Java programming language "assert" statements */
+ public static final int DEBUG_ENABLE_ASSERT = 1 << 2;
+
private Zygote() {}
/**
@@ -24,7 +50,7 @@ public class Zygote {
/**
* Forks a new VM instance. The current VM must have been started
* with the -Xzygote flag. <b>NOTE: new instance keeps all
- * root capabilities. The new process is expected to call capset()<b>.
+ * root capabilities. The new process is expected to call capset()</b>.
*
* @param uid the UNIX uid that the new process should setuid() to after
* fork()ing and and before spawning any threads.
@@ -32,7 +58,7 @@ public class Zygote {
* fork()ing and and before spawning any threads.
* @param gids null-ok; a list of UNIX gids that the new process should
* setgroups() to after fork and before spawning any threads.
- * @param enableDebugger true if JDWP should be enabled.
+ * @param debugFlags bit flags that enable debugging features.
* @param rlimits null-ok an array of rlimit tuples, with the second
* dimension having a length of 3 and representing
* (resource, rlim_cur, rlim_max). These are set via the posix
@@ -42,7 +68,18 @@ public class Zygote {
* if this is the parent, or -1 on error.
*/
native public static int forkAndSpecialize(int uid, int gid, int[] gids,
- boolean enableDebugger, int[][] rlimits);
+ int debugFlags, int[][] rlimits);
+
+ /**
+ * Forks a new VM instance.
+ * @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
+ */
+ @Deprecated
+ public static int forkAndSpecialize(int uid, int gid, int[] gids,
+ boolean enableDebugger, int[][] rlimits) {
+ int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
+ return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
+ }
/**
* Special method to start the system server process. In addition to the
@@ -56,7 +93,7 @@ public class Zygote {
* fork()ing and and before spawning any threads.
* @param gids null-ok; a list of UNIX gids that the new process should
* setgroups() to after fork and before spawning any threads.
- * @param enableDebugger true if JDWP should be enabled.
+ * @param debugFlags bit flags that enable debugging features.
* @param rlimits null-ok an array of rlimit tuples, with the second
* dimension having a length of 3 and representing
* (resource, rlim_cur, rlim_max). These are set via the posix
@@ -66,5 +103,17 @@ public class Zygote {
* if this is the parent, or -1 on error.
*/
native public static int forkSystemServer(int uid, int gid,
- int[] gids, boolean enableDebugger, int[][] rlimits);
+ int[] gids, int debugFlags, int[][] rlimits);
+
+ /**
+ * Special method to start the system server process.
+ * @deprecated use {@link Zygote#forkSystemServer(int, int, int[], int, int[][])}
+ */
+ @Deprecated
+ public static int forkSystemServer(int uid, int gid, int[] gids,
+ boolean enableDebugger, int[][] rlimits) {
+ int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
+ return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
+ }
}
+
diff --git a/dalvik/src/main/java/dalvik/system/package.html b/dalvik/src/main/java/dalvik/system/package.html
new file mode 100644
index 0000000..215671c
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/package.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <p>
+ Provides utility and system information classes specific to the Dalvik VM.
+ </p>
+ @since Android 1.0
+ </body>
+</html>