summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2020-03-06 13:34:33 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-03-06 13:34:33 +0000
commit335db814a5a1408b8715ab815c8151fc8eecb892 (patch)
tree0867b9531b0fe8a31287f7586416e7bf292e4a2d /core/java
parenta90348248b0ef87945be220fcac9410f73fbfea8 (diff)
parentd0b322c5d2d834263841ccf90c4a892f89ca93a5 (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.java41
-rw-r--r--core/java/android/os/ZygoteProcess.java85
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);