diff options
| author | Treehugger Robot <treehugger-gerrit@google.com> | 2020-03-06 13:34:33 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-03-06 13:34:33 +0000 |
| commit | 335db814a5a1408b8715ab815c8151fc8eecb892 (patch) | |
| tree | 0867b9531b0fe8a31287f7586416e7bf292e4a2d /core/java | |
| parent | a90348248b0ef87945be220fcac9410f73fbfea8 (diff) | |
| parent | d0b322c5d2d834263841ccf90c4a892f89ca93a5 (diff) | |
Merge "Adds Zygote policy flags to control how applications are launched"
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/os/Process.java | 41 | ||||
| -rw-r--r-- | core/java/android/os/ZygoteProcess.java | 85 |
2 files changed, 112 insertions, 14 deletions
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 1c0f0f42a5dc..994ed2148baa 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -487,6 +487,40 @@ public class Process { private static long sStartUptimeMillis; /** + * Value used to indicate that there is no special information about an application launch. App + * launches with this policy will occur through the primary or secondary Zygote with no special + * treatment. + * + * @hide + */ + public static final int ZYGOTE_POLICY_FLAG_EMPTY = 0; + + /** + * Flag used to indicate that an application launch is user-visible and latency sensitive. Any + * launch with this policy will use a Unspecialized App Process Pool if the target Zygote + * supports it. + * + * @hide + */ + public static final int ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE = 1 << 0; + + /** + * Flag used to indicate that the launch is one in a series of app launches that will be + * performed in quick succession. For future use. + * + * @hide + */ + public static final int ZYGOTE_POLICY_FLAG_BATCH_LAUNCH = 1 << 1; + + /** + * Flag used to indicate that the current launch event is for a system process. All system + * processes are equally important, so none of them should be prioritized over the others. + * + * @hide + */ + public static final int ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS = 1 << 2; + + /** * State associated with the zygote process. * @hide */ @@ -525,6 +559,7 @@ public class Process { * @param appDataDir null-ok the data directory of the app. * @param invokeWith null-ok the command to invoke with. * @param packageName null-ok the name of the package this process belongs to. + * @param zygotePolicyFlags Flags used to determine how to launch the application * @param isTopApp whether the process starts for high priority application. * @param disabledCompatChanges null-ok list of disabled compat changes for the process being * started. @@ -546,13 +581,14 @@ public class Process { @Nullable String appDataDir, @Nullable String invokeWith, @Nullable String packageName, + int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - /*useUsapPool=*/ true, isTopApp, disabledCompatChanges, zygoteArgs); + zygotePolicyFlags, isTopApp, disabledCompatChanges, zygoteArgs); } /** @hide */ @@ -573,7 +609,8 @@ public class Process { return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - /*useUsapPool=*/ false, /*isTopApp=*/ false, disabledCompatChanges, zygoteArgs); + /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, /*isTopApp=*/ false, + disabledCompatChanges, zygoteArgs); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 32df0529a41c..6334e7bf9c5a 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -16,6 +16,9 @@ package android.os; +import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE; +import static android.os.Process.ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS; + import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -117,6 +120,10 @@ public class ZygoteProcess { mUsapPoolSecondarySocketAddress = new LocalSocketAddress(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); + + // This constructor is used to create the primary and secondary Zygotes, which can support + // Unspecialized App Process Pools. + mUsapPoolSupported = true; } public ZygoteProcess(LocalSocketAddress primarySocketAddress, @@ -126,6 +133,10 @@ public class ZygoteProcess { mUsapPoolSocketAddress = null; mUsapPoolSecondarySocketAddress = null; + + // This constructor is used to create the primary and secondary Zygotes, which CAN NOT + // support Unspecialized App Process Pools. + mUsapPoolSupported = false; } public LocalSocketAddress getPrimarySocketAddress() { @@ -265,6 +276,14 @@ public class ZygoteProcess { private ZygoteState secondaryZygoteState; /** + * If this Zygote supports the creation and maintenance of a USAP pool. + * + * Currently only the primary and secondary Zygotes support USAP pools. Any + * child Zygotes will be unable to create or use a USAP pool. + */ + private final boolean mUsapPoolSupported; + + /** * If the USAP pool should be created and used to start applications. * * Setting this value to false will disable the creation, maintenance, and use of the USAP @@ -306,11 +325,11 @@ public class ZygoteProcess { * @param appDataDir null-ok the data directory of the app. * @param invokeWith null-ok the command to invoke with. * @param packageName null-ok the name of the package this process belongs to. + * @param zygotePolicyFlags Flags used to determine how to launch the application. + * @param isTopApp Whether the process starts for high priority application. * @param disabledCompatChanges null-ok list of disabled compat changes for the process being * started. - * @param zygoteArgs Additional arguments to supply to the zygote process. - * @param isTopApp Whether the process starts for high priority application. - * + * @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 */ @@ -325,7 +344,7 @@ public class ZygoteProcess { @Nullable String appDataDir, @Nullable String invokeWith, @Nullable String packageName, - boolean useUsapPool, + int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable String[] zygoteArgs) { @@ -338,7 +357,7 @@ public class ZygoteProcess { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false, - packageName, useUsapPool, isTopApp, disabledCompatChanges, zygoteArgs); + packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -384,7 +403,7 @@ public class ZygoteProcess { */ @GuardedBy("mLock") private Process.ProcessStartResult zygoteSendArgsAndGetResult( - ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args) + ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args) throws ZygoteStartFailedEx { // Throw early if any of the arguments are malformed. This means we can // avoid writing a partial response to the zygote. @@ -410,7 +429,7 @@ public class ZygoteProcess { */ String msgStr = args.size() + "\n" + String.join("\n", args) + "\n"; - if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) { + if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) { try { return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); } catch (IOException ex) { @@ -481,7 +500,43 @@ public class ZygoteProcess { } /** - * Flags that may not be passed to a USAP. + * Test various member properties and parameters to determine if a launch event should be + * handled using an Unspecialized App Process Pool or not. + * + * @param zygotePolicyFlags Policy flags indicating special behavioral observations about the + * Zygote command + * @param args Arguments that will be passed to the Zygote + * @return If the command should be sent to a USAP Pool member or an actual Zygote + */ + private boolean shouldAttemptUsapLaunch(int zygotePolicyFlags, ArrayList<String> args) { + return mUsapPoolSupported + && mUsapPoolEnabled + && policySpecifiesUsapPoolLaunch(zygotePolicyFlags) + && commandSupportedByUsap(args); + } + + /** + * Tests a Zygote policy flag set for various properties that determine if it is eligible for + * being handled by an Unspecialized App Process Pool. + * + * @param zygotePolicyFlags Policy flags indicating special behavioral observations about the + * Zygote command + * @return If the policy allows for use of a USAP pool + */ + private static boolean policySpecifiesUsapPoolLaunch(int zygotePolicyFlags) { + /* + * Zygote USAP Pool Policy: Launch the new process from the USAP Pool iff the launch event + * is latency sensitive but *NOT* a system process. All system processes are equally + * important so we don't want to prioritize one over another. + */ + return (zygotePolicyFlags + & (ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS | ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE)) + == ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE; + } + + /** + * Flags that may not be passed to a USAP. These may appear as prefixes to individual Zygote + * arguments. */ private static final String[] INVALID_USAP_FLAGS = { "--query-abi-list", @@ -498,10 +553,11 @@ public class ZygoteProcess { /** * Tests a command list to see if it is valid to send to a USAP. + * * @param args Zygote/USAP command arguments * @return True if the command can be passed to a USAP; false otherwise */ - private static boolean canAttemptUsap(ArrayList<String> args) { + private static boolean commandSupportedByUsap(ArrayList<String> args) { for (String flag : args) { for (String badFlag : INVALID_USAP_FLAGS) { if (flag.startsWith(badFlag)) { @@ -539,6 +595,7 @@ public class ZygoteProcess { * @param startChildZygote Start a sub-zygote. This creates a new zygote process * that has its state cloned from this zygote process. * @param packageName null-ok the name of the package this process belongs to. + * @param zygotePolicyFlags Flags used to determine how to launch the application. * @param isTopApp Whether the process starts for high priority application. * @param disabledCompatChanges a list of disabled compat changes for the process being started. * @param extraArgs Additional arguments to supply to the zygote process. @@ -558,7 +615,7 @@ public class ZygoteProcess { @Nullable String invokeWith, boolean startChildZygote, @Nullable String packageName, - boolean useUsapPool, + int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable String[] extraArgs) @@ -661,7 +718,7 @@ public class ZygoteProcess { // 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), - useUsapPool, + zygotePolicyFlags, argsForZygote); } } @@ -691,6 +748,10 @@ public class ZygoteProcess { private long mLastPropCheckTimestamp = 0; private boolean fetchUsapPoolEnabledPropWithMinInterval() { + // If this Zygote doesn't support USAPs there is no need to fetch any + // properties. + if (!mUsapPoolSupported) return false; + final long currentTimestamp = SystemClock.elapsedRealtime(); if (SystemProperties.get("dalvik.vm.boot-image", "").endsWith("apex.art")) { @@ -1198,7 +1259,7 @@ public class ZygoteProcess { gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo, abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, null /* packageName */, - false /* useUsapPool */, false /* isTopApp */, + ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */, null /* disabledCompatChanges */, extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); |
