diff options
Diffstat (limited to 'core/java/android/os/ZygoteProcess.java')
| -rw-r--r-- | core/java/android/os/ZygoteProcess.java | 110 |
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); } |
