Move preloaded-classes out of framework.jar.
Instead we install preloaded-classes as a standalone configuration file
/system/etc/preloaded-classes, so we can configure different file per product.
Bug: 18305157
Change-Id: I22f1a1dd44f90268d02532bf18405768523c0b1b
diff --git a/Android.mk b/Android.mk
index 22cc27b..7cd6635 100644
--- a/Android.mk
+++ b/Android.mk
@@ -400,9 +400,6 @@
LOCAL_RMTYPEDEFS := true
-# List of classes and interfaces which should be loaded by the Zygote.
-LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
-
include $(BUILD_JAVA_LIBRARY)
framework_module := $(LOCAL_INSTALLED_MODULE)
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 46850da..62088fa 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -45,6 +45,8 @@
import java.io.BufferedReader;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -91,9 +93,9 @@
private static Resources mResources;
/**
- * The name of a resource file that contains classes to preload.
+ * The path of a file that contains classes to preload.
*/
- private static final String PRELOADED_CLASSES = "preloaded-classes";
+ private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
/** Controls whether we should preload resources during zygote init. */
private static final boolean PRELOAD_RESOURCES = true;
@@ -278,74 +280,76 @@
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
- InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(
- PRELOADED_CLASSES);
- if (is == null) {
+ InputStream is;
+ try {
+ is = new FileInputStream(PRELOADED_CLASSES);
+ } catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
- } else {
- Log.i(TAG, "Preloading classes...");
- long startTime = SystemClock.uptimeMillis();
+ return;
+ }
- // Drop root perms while running static initializers.
- setEffectiveGroup(UNPRIVILEGED_GID);
- setEffectiveUser(UNPRIVILEGED_UID);
+ Log.i(TAG, "Preloading classes...");
+ long startTime = SystemClock.uptimeMillis();
- // Alter the target heap utilization. With explicit GCs this
- // is not likely to have any effect.
- float defaultUtilization = runtime.getTargetHeapUtilization();
- runtime.setTargetHeapUtilization(0.8f);
+ // Drop root perms while running static initializers.
+ setEffectiveGroup(UNPRIVILEGED_GID);
+ setEffectiveUser(UNPRIVILEGED_UID);
- try {
- BufferedReader br
- = new BufferedReader(new InputStreamReader(is), 256);
+ // Alter the target heap utilization. With explicit GCs this
+ // is not likely to have any effect.
+ float defaultUtilization = runtime.getTargetHeapUtilization();
+ runtime.setTargetHeapUtilization(0.8f);
- int count = 0;
- String line;
- while ((line = br.readLine()) != null) {
- // Skip comments and blank lines.
- line = line.trim();
- if (line.startsWith("#") || line.equals("")) {
- continue;
- }
+ try {
+ BufferedReader br
+ = new BufferedReader(new InputStreamReader(is), 256);
- try {
- if (false) {
- Log.v(TAG, "Preloading " + line + "...");
- }
- Class.forName(line);
- count++;
- } catch (ClassNotFoundException e) {
- Log.w(TAG, "Class not found for preloading: " + line);
- } catch (UnsatisfiedLinkError e) {
- Log.w(TAG, "Problem preloading " + line + ": " + e);
- } catch (Throwable t) {
- Log.e(TAG, "Error preloading " + line + ".", t);
- if (t instanceof Error) {
- throw (Error) t;
- }
- if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- }
- throw new RuntimeException(t);
- }
+ int count = 0;
+ String line;
+ while ((line = br.readLine()) != null) {
+ // Skip comments and blank lines.
+ line = line.trim();
+ if (line.startsWith("#") || line.equals("")) {
+ continue;
}
- Log.i(TAG, "...preloaded " + count + " classes in "
- + (SystemClock.uptimeMillis()-startTime) + "ms.");
- } catch (IOException e) {
- Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
- } finally {
- IoUtils.closeQuietly(is);
- // Restore default.
- runtime.setTargetHeapUtilization(defaultUtilization);
-
- // Fill in dex caches with classes, fields, and methods brought in by preloading.
- runtime.preloadDexCaches();
-
- // Bring back root. We'll need it later.
- setEffectiveUser(ROOT_UID);
- setEffectiveGroup(ROOT_GID);
+ try {
+ if (false) {
+ Log.v(TAG, "Preloading " + line + "...");
+ }
+ Class.forName(line);
+ count++;
+ } catch (ClassNotFoundException e) {
+ Log.w(TAG, "Class not found for preloading: " + line);
+ } catch (UnsatisfiedLinkError e) {
+ Log.w(TAG, "Problem preloading " + line + ": " + e);
+ } catch (Throwable t) {
+ Log.e(TAG, "Error preloading " + line + ".", t);
+ if (t instanceof Error) {
+ throw (Error) t;
+ }
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ }
+ throw new RuntimeException(t);
+ }
}
+
+ Log.i(TAG, "...preloaded " + count + " classes in "
+ + (SystemClock.uptimeMillis()-startTime) + "ms.");
+ } catch (IOException e) {
+ Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
+ } finally {
+ IoUtils.closeQuietly(is);
+ // Restore default.
+ runtime.setTargetHeapUtilization(defaultUtilization);
+
+ // Fill in dex caches with classes, fields, and methods brought in by preloading.
+ runtime.preloadDexCaches();
+
+ // Bring back root. We'll need it later.
+ setEffectiveUser(ROOT_UID);
+ setEffectiveGroup(ROOT_GID);
}
}