Merge "Preload WindowManager Extensions to improve startup performance" into udc-dev

This commit is contained in:
Andrii Kulian
2023-03-30 15:13:26 +00:00
committed by Android (Google) Code Review
3 changed files with 52 additions and 31 deletions

View File

@@ -157,15 +157,15 @@ public class ApplicationLoaders {
* All libraries in the closure of libraries to be loaded must be in libs. A library can
* only depend on libraries that come before it in the list.
*/
public void createAndCacheNonBootclasspathSystemClassLoaders(SharedLibraryInfo[] libs) {
public void createAndCacheNonBootclasspathSystemClassLoaders(List<SharedLibraryInfo> libs) {
if (mSystemLibsCacheMap != null) {
throw new IllegalStateException("Already cached.");
}
mSystemLibsCacheMap = new HashMap<String, CachedClassLoader>();
mSystemLibsCacheMap = new HashMap<>();
for (SharedLibraryInfo lib : libs) {
createAndCacheNonBootclasspathSystemClassLoader(lib);
for (int i = 0; i < libs.size(); i++) {
createAndCacheNonBootclasspathSystemClassLoader(libs.get(i));
}
}

View File

@@ -51,6 +51,7 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.TimingsTraceLog;
import android.view.WindowManager;
import android.webkit.WebViewFactory;
import android.widget.TextView;
@@ -72,6 +73,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
/**
* Startup class for the zygote process.
@@ -384,33 +387,49 @@ public class ZygoteInit {
* classpath.
*/
private static void cacheNonBootClasspathClassLoaders() {
// Ordered dependencies first
final List<SharedLibraryInfo> libs = new ArrayList<>();
// These libraries used to be part of the bootclasspath, but had to be removed.
// Old system applications still get them for backwards compatibility reasons,
// so they are cached here in order to preserve performance characteristics.
SharedLibraryInfo hidlBase = new SharedLibraryInfo(
libs.add(new SharedLibraryInfo(
"/system/framework/android.hidl.base-V1.0-java.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
false /*isNative*/);
SharedLibraryInfo hidlManager = new SharedLibraryInfo(
false /*isNative*/));
libs.add(new SharedLibraryInfo(
"/system/framework/android.hidl.manager-V1.0-java.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
false /*isNative*/);
false /*isNative*/));
SharedLibraryInfo androidTestBase = new SharedLibraryInfo(
libs.add(new SharedLibraryInfo(
"/system/framework/android.test.base.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
false /*isNative*/);
false /*isNative*/));
ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(
new SharedLibraryInfo[]{
// ordered dependencies first
hidlBase,
hidlManager,
androidTestBase,
});
// WindowManager Extensions is an optional shared library that is required for WindowManager
// Jetpack to fully function. Since it is a widely used library, preload it to improve apps
// startup performance.
if (WindowManager.hasWindowExtensionsEnabled()) {
final String systemExtFrameworkPath =
new File(Environment.getSystemExtDirectory(), "framework").getPath();
libs.add(new SharedLibraryInfo(
systemExtFrameworkPath + "/androidx.window.extensions.jar",
"androidx.window.extensions", null /*codePaths*/,
"androidx.window.extensions", SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
libs.add(new SharedLibraryInfo(
systemExtFrameworkPath + "/androidx.window.sidecar.jar",
"androidx.window.sidecar", null /*codePaths*/,
"androidx.window.sidecar", SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
}
ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(libs);
}
/**

View File

@@ -16,14 +16,17 @@
package android.app;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import android.content.pm.SharedLibraryInfo;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.google.android.collect.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -48,7 +51,7 @@ public class ApplicationLoadersTest {
@Test
public void testGetNonExistantLib() {
ApplicationLoaders loaders = new ApplicationLoaders();
assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNull(loaders.getCachedNonBootclasspathSystemLib(
"/system/framework/nonexistantlib.jar", null, null, null));
}
@@ -57,9 +60,9 @@ public class ApplicationLoadersTest {
ApplicationLoaders loaders = new ApplicationLoaders();
SharedLibraryInfo libA = createLib(LIB_A);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libA));
assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNotNull(loaders.getCachedNonBootclasspathSystemLib(
LIB_A, null, null, null));
}
@@ -71,9 +74,9 @@ public class ApplicationLoadersTest {
ClassLoader parent = ClassLoader.getSystemClassLoader();
assertNotEquals(null, parent);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libA));
assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNull(loaders.getCachedNonBootclasspathSystemLib(
LIB_A, parent, null, null));
}
@@ -82,9 +85,9 @@ public class ApplicationLoadersTest {
ApplicationLoaders loaders = new ApplicationLoaders();
SharedLibraryInfo libA = createLib(LIB_A);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libA));
assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNull(loaders.getCachedNonBootclasspathSystemLib(
LIB_A, null, "other classloader", null));
}
@@ -98,9 +101,9 @@ public class ApplicationLoadersTest {
ArrayList<ClassLoader> sharedLibraries = new ArrayList<>();
sharedLibraries.add(dep);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(new SharedLibraryInfo[]{libA});
loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libA));
assertEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNull(loaders.getCachedNonBootclasspathSystemLib(
LIB_A, null, null, sharedLibraries));
}
@@ -112,7 +115,7 @@ public class ApplicationLoadersTest {
libB.addDependency(libA);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(
new SharedLibraryInfo[]{libA, libB});
Lists.newArrayList(libA, libB));
ClassLoader loadA = loaders.getCachedNonBootclasspathSystemLib(
LIB_A, null, null, null);
@@ -121,7 +124,7 @@ public class ApplicationLoadersTest {
ArrayList<ClassLoader> sharedLibraries = new ArrayList<>();
sharedLibraries.add(loadA);
assertNotEquals(null, loaders.getCachedNonBootclasspathSystemLib(
assertNotNull(loaders.getCachedNonBootclasspathSystemLib(
LIB_DEP_A, null, null, sharedLibraries));
}
@@ -132,7 +135,6 @@ public class ApplicationLoadersTest {
SharedLibraryInfo libB = createLib(LIB_DEP_A);
libB.addDependency(libA);
loaders.createAndCacheNonBootclasspathSystemClassLoaders(
new SharedLibraryInfo[]{libB, libA});
loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libB, libA));
}
}