summaryrefslogtreecommitdiff
path: root/core/java/android/os/ZygoteProcess.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os/ZygoteProcess.java')
-rw-r--r--core/java/android/os/ZygoteProcess.java110
1 files changed, 89 insertions, 21 deletions
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index f71f98a45284..e39e22ee632c 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -26,6 +26,7 @@ import android.content.pm.ApplicationInfo;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -42,6 +43,7 @@ import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
/*package*/ class ZygoteStartFailedEx extends Exception {
@@ -329,6 +331,13 @@ public class ZygoteProcess {
* @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 pkgDataInfoMap Map from related package names to private data directory
+ * volume UUID and inode number.
+ * @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
+ * volume UUID and inode number.
+ * @param bindMountAppsData whether zygote needs to mount CE and DE data.
+ * @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
+ *
* @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
@@ -347,6 +356,12 @@ public class ZygoteProcess {
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
+ @Nullable Map<String, Pair<String, Long>>
+ pkgDataInfoMap,
+ @Nullable Map<String, Pair<String, Long>>
+ whitelistedDataInfoMap,
+ boolean bindMountAppsData,
+ boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
// TODO (chriswailes): Is there a better place to check this value?
if (fetchUsapPoolEnabledPropWithMinInterval()) {
@@ -357,7 +372,9 @@ public class ZygoteProcess {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
- packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges, zygoteArgs);
+ packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
+ pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
+ bindMountAppStorageDirs, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -566,9 +583,7 @@ public class ZygoteProcess {
}
if (flag.startsWith("--nice-name=")) {
// Check if the wrap property is set, usap would ignore it.
- String niceName = flag.substring(12);
- String property_value = SystemProperties.get("wrap." + niceName);
- if (property_value != null && property_value.length() != 0) {
+ if (Zygote.getWrapProperty(flag.substring(12)) != null) {
return false;
}
}
@@ -598,6 +613,12 @@ public class ZygoteProcess {
* @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 pkgDataInfoMap Map from related package names to private data directory volume UUID
+ * and inode number.
+ * @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
+ * volume UUID and inode number.
+ * @param bindMountAppsData whether zygote needs to mount CE and DE data.
+ * @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -618,6 +639,12 @@ public class ZygoteProcess {
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
+ @Nullable Map<String, Pair<String, Long>>
+ pkgDataInfoMap,
+ @Nullable Map<String, Pair<String, Long>>
+ whitelistedDataInfoMap,
+ boolean bindMountAppsData,
+ boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<>();
@@ -640,16 +667,20 @@ public class ZygoteProcess {
argsForZygote.add("--mount-external-installer");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
argsForZygote.add("--mount-external-legacy");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
+ argsForZygote.add("--mount-external-pass-through");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
+ argsForZygote.add("--mount-external-android-writable");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
// --setgroups is a comma-separated list
if (gids != null && gids.length > 0) {
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");
- int sz = gids.length;
+ final int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
@@ -692,12 +723,56 @@ public class ZygoteProcess {
if (isTopApp) {
argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
}
+ if (pkgDataInfoMap != null && pkgDataInfoMap.size() > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(Zygote.PKG_DATA_INFO_MAP);
+ sb.append("=");
+ boolean started = false;
+ for (Map.Entry<String, Pair<String, Long>> entry : pkgDataInfoMap.entrySet()) {
+ if (started) {
+ sb.append(',');
+ }
+ started = true;
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue().first);
+ sb.append(',');
+ sb.append(entry.getValue().second);
+ }
+ argsForZygote.add(sb.toString());
+ }
+ if (whitelistedDataInfoMap != null && whitelistedDataInfoMap.size() > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(Zygote.WHITELISTED_DATA_INFO_MAP);
+ sb.append("=");
+ boolean started = false;
+ for (Map.Entry<String, Pair<String, Long>> entry : whitelistedDataInfoMap.entrySet()) {
+ if (started) {
+ sb.append(',');
+ }
+ started = true;
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue().first);
+ sb.append(',');
+ sb.append(entry.getValue().second);
+ }
+ argsForZygote.add(sb.toString());
+ }
+
+ if (bindMountAppStorageDirs) {
+ argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
+ }
+
+ if (bindMountAppsData) {
+ argsForZygote.add(Zygote.BIND_MOUNT_APP_DATA_DIRS);
+ }
if (disabledCompatChanges != null && disabledCompatChanges.length > 0) {
- final StringBuilder sb = new StringBuilder();
+ StringBuilder sb = new StringBuilder();
sb.append("--disabled-compat-changes=");
- final int sz = disabledCompatChanges.length;
+ int sz = disabledCompatChanges.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
@@ -754,16 +829,6 @@ public class ZygoteProcess {
final long currentTimestamp = SystemClock.elapsedRealtime();
- if (SystemProperties.get("dalvik.vm.boot-image", "").endsWith("apex.art")) {
- // TODO(b/119800099): In jitzygote mode, we want to start using USAP processes
- // only once the boot classpath has been compiled. There is currently no callback
- // from the runtime to notify the zygote about end of compilation, so for now just
- // arbitrarily start USAP processes 15 seconds after boot.
- if (currentTimestamp <= 15000) {
- return false;
- }
- }
-
if (mIsFirstPropCheck
|| (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL)) {
mIsFirstPropCheck = false;
@@ -991,7 +1056,6 @@ public class ZygoteProcess {
maybeSetApiDenylistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
- maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
}
}
@@ -1007,7 +1071,6 @@ public class ZygoteProcess {
maybeSetApiDenylistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
- maybeSetHiddenApiAccessStatslogSampleRate(secondaryZygoteState);
}
}
@@ -1255,12 +1318,17 @@ public class ZygoteProcess {
Process.ProcessStartResult result;
try {
+ // We will bind mount app data dirs so app zygote can't access /data/data, while
+ // we don't need to bind mount storage dirs as /storage won't be mounted.
result = startViaZygote(processClass, niceName, uid, gid,
gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
true /* startChildZygote */, null /* packageName */,
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
- null /* disabledCompatChanges */, extraArgs);
+ null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
+ null /* whitelistedDataInfoMap */, true /* bindMountAppsData*/,
+ /* bindMountAppStorageDirs */ false, extraArgs);
+
} catch (ZygoteStartFailedEx ex) {
throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
}