From dc362ffcc76de2a493b2435472ac0ea67260e1cf Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Feb 2022 14:26:07 -0800 Subject: [PATCH] Add PackageManager feature strings for EROFS. This adds two feature strings for EROFS, one for the legacy staging version present in 4.19 kernels, and another for the official mainline version present in later kernels. Bug: 215725871 Test: manual test Change-Id: Ic36424b578f985ef5a826c3a89c243720fecd0a6 Signed-off-by: David Anderson (cherry picked from commit 035cfec7d6b1811c8f55d07f9d5d0114fb66f174) --- core/api/system-current.txt | 2 + .../android/content/pm/PackageManager.java | 22 +++++++++++ .../java/com/android/server/SystemConfig.java | 37 +++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index d094f4bad5117..a0a703fcec701 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3413,6 +3413,8 @@ package android.content.pm { field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; field public static final String FEATURE_CONTEXT_HUB = "android.hardware.context_hub"; + field public static final String FEATURE_EROFS = "android.software.erofs"; + field public static final String FEATURE_EROFS_LEGACY = "android.software.erofs_legacy"; field public static final String FEATURE_GAME_SERVICE = "android.software.game_service"; field public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery"; field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 81c941eedef0b..c91ee13956877 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4086,6 +4086,28 @@ public abstract class PackageManager { public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery"; + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device + * has the requisite kernel support for the EROFS filesystem present in 4.19 kernels as a + * staging driver, which lacks 0padding and big pcluster support. + * + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_EROFS_LEGACY = "android.software.erofs_legacy"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device + * has the requisite kernel support for the EROFS filesystem present in 5.10 kernels, which + * has 0padding, big pcluster, and chunked index support. + * + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_EROFS = "android.software.erofs"; + /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: * The device has tuner hardware to support tuner operations. diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index e281853d31bf5..db41d333e1d44 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -31,6 +31,7 @@ import android.os.FileUtils; import android.os.Process; import android.os.SystemProperties; import android.os.Trace; +import android.os.VintfRuntimeInfo; import android.os.incremental.IncrementalManager; import android.os.storage.StorageManager; import android.permission.PermissionManager.SplitPermissionInfo; @@ -57,7 +58,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -1447,6 +1451,14 @@ public class SystemConfig { addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0); } + if (isFilesystemSupported("erofs")) { + if (isKernelVersionAtLeast(5, 10)) { + addFeature(PackageManager.FEATURE_EROFS, 0); + } else if (isKernelVersionAtLeast(4, 19)) { + addFeature(PackageManager.FEATURE_EROFS_LEGACY, 0); + } + } + for (String featureName : mUnavailableFeatures) { removeFeature(featureName); } @@ -1816,4 +1828,29 @@ public class SystemConfig { private static boolean isSystemProcess() { return Process.myUid() == Process.SYSTEM_UID; } + + private static boolean isFilesystemSupported(String fs) { + try { + final byte[] fsTableData = Files.readAllBytes(Paths.get("/proc/filesystems")); + final String fsTable = new String(fsTableData, StandardCharsets.UTF_8); + return fsTable.contains("\t" + fs + "\n"); + } catch (Exception e) { + return false; + } + } + + private static boolean isKernelVersionAtLeast(int major, int minor) { + final String kernelVersion = VintfRuntimeInfo.getKernelVersion(); + final String[] parts = kernelVersion.split("\\."); + if (parts.length < 2) { + return false; + } + try { + final int majorVersion = Integer.parseInt(parts[0]); + final int minorVersion = Integer.parseInt(parts[1]); + return majorVersion > major || (majorVersion == major && minorVersion >= minor); + } catch (NumberFormatException e) { + return false; + } + } }