From 35fdbc570b4e905bcaa7892b70bd074894384cc5 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Wed, 17 Apr 2019 17:55:48 -0700 Subject: [PATCH] Load the default graphics driver in USAPs. This patch causes unspecialized app processes to load the OpenGL driver after they are forked. The ZygoteProcess code will then take an application's driver preference into account when selecting how to launch it. Test: m & boot & launch & inspect traces for driver loading Bug: 130029351 Change-Id: If6fa02f9c387596162e75a685b04208b45a5c86b Merged-In: If6fa02f9c387596162e75a685b04208b45a5c86b (cherry picked from commit 301a1c46da930bb927bd86227c6e1d44c70c349d) --- core/java/android/os/Process.java | 74 ++++++++++--------- core/java/android/os/ZygoteProcess.java | 16 ++-- core/java/com/android/internal/os/Zygote.java | 3 + .../com/android/internal/os/ZygoteInit.java | 13 +++- .../com/android/server/am/ProcessList.java | 14 ++-- 5 files changed, 68 insertions(+), 52 deletions(-) diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index fb35db11027ba..b82b5ef3f0bab 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -512,57 +512,59 @@ public class Process { * @param invokeWith null-ok the command to invoke with. * @param packageName null-ok the name of the package this process belongs to. * @param packagesForUid null-ok all the packages with the same uid as this process. - * @param zygoteArgs Additional arguments to supply to the zygote process. * @param useSystemGraphicsDriver whether the process uses system graphics driver. - * + * + * @param zygoteArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws RuntimeException on fatal start failure * * {@hide} */ - public static final ProcessStartResult start(@NonNull final String processClass, - @Nullable final String niceName, - int uid, int gid, @Nullable int[] gids, - int runtimeFlags, int mountExternal, - int targetSdkVersion, - @Nullable String seInfo, - @NonNull String abi, - @Nullable String instructionSet, - @Nullable String appDataDir, - @Nullable String invokeWith, - @Nullable String packageName, - @Nullable String[] packagesForUid, - @Nullable String sandboxId, - @Nullable String[] zygoteArgs, - boolean useSystemGraphicsDriver) { + public static ProcessStartResult start(@NonNull final String processClass, + @Nullable final String niceName, + int uid, int gid, @Nullable int[] gids, + int runtimeFlags, + int mountExternal, + int targetSdkVersion, + @Nullable String seInfo, + @NonNull String abi, + @Nullable String instructionSet, + @Nullable String appDataDir, + @Nullable String invokeWith, + @Nullable String packageName, + @Nullable String[] packagesForUid, + @Nullable String sandboxId, + boolean useSystemGraphicsDriver, + @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - packagesForUid, sandboxId, /*useUnspecializedAppProcessPool=*/ true, - zygoteArgs, useSystemGraphicsDriver); + packagesForUid, sandboxId, /*useUsapPool=*/ true, + useSystemGraphicsDriver, zygoteArgs); } /** @hide */ - public static final ProcessStartResult startWebView(@NonNull final String processClass, - @Nullable final String niceName, - int uid, int gid, @Nullable int[] gids, - int runtimeFlags, int mountExternal, - int targetSdkVersion, - @Nullable String seInfo, - @NonNull String abi, - @Nullable String instructionSet, - @Nullable String appDataDir, - @Nullable String invokeWith, - @Nullable String packageName, - @Nullable String[] packagesForUid, - @Nullable String sandboxId, - @Nullable String[] zygoteArgs, - boolean useSystemGraphicsDriver) { + public static ProcessStartResult startWebView(@NonNull final String processClass, + @Nullable final String niceName, + int uid, int gid, @Nullable int[] gids, + int runtimeFlags, + int mountExternal, + int targetSdkVersion, + @Nullable String seInfo, + @NonNull String abi, + @Nullable String instructionSet, + @Nullable String appDataDir, + @Nullable String invokeWith, + @Nullable String packageName, + @Nullable String[] packagesForUid, + @Nullable String sandboxId, + boolean useSystemGraphicsDriver, + @Nullable String[] zygoteArgs) { return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - packagesForUid, sandboxId, /*useUnspecializedAppProcessPool=*/ false, - zygoteArgs, useSystemGraphicsDriver); + packagesForUid, sandboxId, /*useUsapPool=*/ false, + useSystemGraphicsDriver, zygoteArgs); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index b7789c0c28572..db7c22937ceb2 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -327,8 +327,8 @@ public class ZygoteProcess { @Nullable String[] packagesForUid, @Nullable String sandboxId, boolean useUsapPool, - @Nullable String[] zygoteArgs, - boolean useSystemGraphicsDriver) { + boolean useSystemGraphicsDriver, + @Nullable String[] zygoteArgs) { // TODO (chriswailes): Is there a better place to check this value? if (fetchUsapPoolEnabledPropWithMinInterval()) { informZygotesOfUsapPoolStatus(); @@ -339,7 +339,7 @@ public class ZygoteProcess { runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false, packageName, packagesForUid, sandboxId, - useUsapPool, zygoteArgs); + useUsapPool, useSystemGraphicsDriver, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -548,7 +548,8 @@ public class ZygoteProcess { @Nullable String packageName, @Nullable String[] packagesForUid, @Nullable String sandboxId, - boolean useUnspecializedAppProcessPool, + boolean useUsapPool, + boolean useSystemGraphicsDriver, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { ArrayList argsForZygote = new ArrayList<>(); @@ -635,8 +636,10 @@ public class ZygoteProcess { } synchronized(mLock) { + // The USAP pool can not be used if the application will not use the systems graphics + // driver. If that driver is requested use the Zygote application start path. return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), - useUnspecializedAppProcessPool, + useUsapPool && useSystemGraphicsDriver, argsForZygote); } } @@ -1141,7 +1144,8 @@ public class ZygoteProcess { abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, null /* packageName */, null /* packagesForUid */, null /* sandboxId */, - false /* useUsapPool */, extraArgs); + false /* useUsapPool */, false /*useSystemGraphicsDriver*/, + extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index a295bd21b20fb..46d9aac24d4f5 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -517,6 +517,9 @@ public final class Zygote { Credentials peerCredentials = null; ZygoteArguments args = null; + // Load resources + ZygoteInit.nativePreloadOpenGL(); + while (true) { try { sessionSocket = usapPoolSocket.accept(); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index bb7b09ab4df36..e19eb998849b5 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -150,7 +150,7 @@ public class ZygoteInit { nativePreloadAppProcessHALs(); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL"); - preloadOpenGL(); + maybePreloadOpenGL(); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); preloadSharedLibraries(); preloadTextResources(); @@ -192,9 +192,16 @@ public class ZygoteInit { native private static void nativePreloadAppProcessHALs(); - native private static void nativePreloadOpenGL(); + /** + * This call loads the graphics driver by attempting to make an OpenGL call. If the driver is + * not currently in memory it will load and initialize it. The OpenGL call itself is relatively + * cheap and pure. This means that it is a low overhead on the initial call, and is safe and + * cheap to call later. Calls after the initial invocation will effectively be no-ops for the + * system. + */ + static native void nativePreloadOpenGL(); - private static void preloadOpenGL() { + private static void maybePreloadOpenGL() { String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) && (driverPackageName == null || driverPackageName.isEmpty())) { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index a93f2187db082..32516b1c46189 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1827,8 +1827,8 @@ public final class ProcessList { app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, packageNames, sandboxId, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}, - useSystemGraphicsDriver); + useSystemGraphicsDriver, + new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } else if (hostingRecord.usesAppZygote()) { final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); @@ -1836,17 +1836,17 @@ public final class ProcessList { app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, - packageNames, sandboxId, /*useUnspecializedAppProcessPool=*/ false, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}, - useSystemGraphicsDriver); + packageNames, sandboxId, /*useUsapPool=*/ false, + useSystemGraphicsDriver, + new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, app.info.packageName, packageNames, sandboxId, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}, - useSystemGraphicsDriver); + useSystemGraphicsDriver, + new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } checkSlow(startTime, "startProcess: returned from zygote!"); return startResult;