Loading core/java/android/os/Environment.java +14 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ public class Environment { private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT"; private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT"; private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT"; private static final String ENV_APEX_ROOT = "APEX_ROOT"; /** {@hide} */ public static final String DIR_ANDROID = "Android"; Loading @@ -79,6 +80,8 @@ public class Environment { private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product"); private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT, "/system_ext"); private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT, "/apex"); @UnsupportedAppUsage private static UserEnvironment sCurrentUser; Loading Loading @@ -245,6 +248,16 @@ public class Environment { return DIR_SYSTEM_EXT_ROOT; } /** * Return root directory of the apex mount point, where all the apex modules are made available * to the rest of the system. * * @hide */ public static @NonNull File getApexDirectory() { return DIR_APEX_ROOT; } /** * Return the system directory for a user. This is for use by system * services to store files relating to the user. This directory will be Loading services/core/java/com/android/server/pm/ApexManager.java +74 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.os.Environment; import android.os.RemoteException; import android.os.ServiceManager; import android.sysprop.ApexProperties; Loading @@ -47,6 +48,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; Loading @@ -64,9 +66,9 @@ abstract class ApexManager { static final int MATCH_FACTORY_PACKAGE = 1 << 1; /** * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerNoOp} depending * on whenever this device supports APEX, i.e. {@link ApexProperties#updatable()} evaluates to * {@code true}. * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerFlattenedApex} * depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()} * evaluates to {@code true}. */ static ApexManager create(Context systemContext) { if (ApexProperties.updatable().orElse(false)) { Loading @@ -77,10 +79,28 @@ abstract class ApexManager { throw new IllegalStateException("Required service apexservice not available"); } } else { return new ApexManagerNoOp(); return new ApexManagerFlattenedApex(); } } /** * Minimal information about APEX mount points and the original APEX package they refer to. */ static class ActiveApexInfo { public final File apexDirectory; public final File preinstalledApexPath; private ActiveApexInfo(File apexDirectory, File preinstalledApexPath) { this.apexDirectory = apexDirectory; this.preinstalledApexPath = preinstalledApexPath; } } /** * Returns {@link ActiveApexInfo} records relative to all active APEX packages. */ abstract List<ActiveApexInfo> getActiveApexInfos(); abstract void systemReady(); /** Loading Loading @@ -258,6 +278,22 @@ abstract class ApexManager { return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @Override List<ActiveApexInfo> getActiveApexInfos() { try { return Arrays.stream(mApexService.getActivePackages()) .map(apexInfo -> new ActiveApexInfo( new File( Environment.getApexDirectory() + File.separator + apexInfo.moduleName), new File(apexInfo.modulePath))).collect( Collectors.toList()); } catch (RemoteException e) { Slog.e(TAG, "Unable to retrieve packages from apexservice", e); } return Collections.emptyList(); } @Override void systemReady() { mContext.registerReceiver(new BroadcastReceiver() { Loading Loading @@ -549,7 +585,40 @@ abstract class ApexManager { * An implementation of {@link ApexManager} that should be used in case device does not support * updating APEX packages. */ private static final class ApexManagerNoOp extends ApexManager { private static final class ApexManagerFlattenedApex extends ApexManager { @Override List<ActiveApexInfo> getActiveApexInfos() { // There is no apexd running in case of flattened apex // We look up the /apex directory and identify the active APEX modules from there. // As "preinstalled" path, we just report /system since in the case of flattened APEX // the /apex directory is just a symlink to /system/apex. List<ActiveApexInfo> result = new ArrayList<>(); File apexDir = Environment.getApexDirectory(); // In flattened configuration, init special-case the art directory and bind-mounts // com.android.art.{release|debug} to com.android.art. At the time of writing, these // directories are copied from the kArtApexDirNames variable in // system/core/init/mount_namespace.cpp. String[] skipDirs = {"com.android.art.release", "com.android.art.debug"}; if (apexDir.isDirectory()) { File[] files = apexDir.listFiles(); // listFiles might be null if system server doesn't have permission to read // a directory. if (files != null) { for (File file : files) { if (file.isDirectory() && !file.getName().contains("@")) { for (String skipDir : skipDirs) { if (file.getName().equals(skipDir)) { continue; } } result.add(new ActiveApexInfo(file, Environment.getRootDirectory())); } } } } return result; } @Override void systemReady() { Loading services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +9 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,15 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { codeRoot = Environment.getSystemExtDirectory(); } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { codeRoot = Environment.getOdmDirectory(); } else if (FileUtils.contains(Environment.getApexDirectory(), codePath)) { String fullPath = codePath.getAbsolutePath(); String[] parts = fullPath.split(File.separator); if (parts.length > 2) { codeRoot = new File(parts[1] + File.separator + parts[2]); } else { Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath); codeRoot = Environment.getApexDirectory(); } } else { // Unrecognized code path; take its top real segment as the apk root: // e.g. /something/app/blah.apk => /something Loading services/core/java/com/android/server/pm/PackageManagerService.java +159 −375 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/pm/Settings.java +1 −1 Original line number Diff line number Diff line Loading @@ -3510,7 +3510,7 @@ public final class Settings { int pkgFlags = 0; int pkgPrivateFlags = 0; pkgFlags |= ApplicationInfo.FLAG_SYSTEM; if (PackageManagerService.locationIsPrivileged(codePathStr)) { if (codePathStr.contains("/priv-app/")) { pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; } PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), Loading Loading
core/java/android/os/Environment.java +14 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ public class Environment { private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT"; private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT"; private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT"; private static final String ENV_APEX_ROOT = "APEX_ROOT"; /** {@hide} */ public static final String DIR_ANDROID = "Android"; Loading @@ -79,6 +80,8 @@ public class Environment { private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product"); private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT, "/system_ext"); private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT, "/apex"); @UnsupportedAppUsage private static UserEnvironment sCurrentUser; Loading Loading @@ -245,6 +248,16 @@ public class Environment { return DIR_SYSTEM_EXT_ROOT; } /** * Return root directory of the apex mount point, where all the apex modules are made available * to the rest of the system. * * @hide */ public static @NonNull File getApexDirectory() { return DIR_APEX_ROOT; } /** * Return the system directory for a user. This is for use by system * services to store files relating to the user. This directory will be Loading
services/core/java/com/android/server/pm/ApexManager.java +74 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.os.Environment; import android.os.RemoteException; import android.os.ServiceManager; import android.sysprop.ApexProperties; Loading @@ -47,6 +48,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; Loading @@ -64,9 +66,9 @@ abstract class ApexManager { static final int MATCH_FACTORY_PACKAGE = 1 << 1; /** * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerNoOp} depending * on whenever this device supports APEX, i.e. {@link ApexProperties#updatable()} evaluates to * {@code true}. * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerFlattenedApex} * depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()} * evaluates to {@code true}. */ static ApexManager create(Context systemContext) { if (ApexProperties.updatable().orElse(false)) { Loading @@ -77,10 +79,28 @@ abstract class ApexManager { throw new IllegalStateException("Required service apexservice not available"); } } else { return new ApexManagerNoOp(); return new ApexManagerFlattenedApex(); } } /** * Minimal information about APEX mount points and the original APEX package they refer to. */ static class ActiveApexInfo { public final File apexDirectory; public final File preinstalledApexPath; private ActiveApexInfo(File apexDirectory, File preinstalledApexPath) { this.apexDirectory = apexDirectory; this.preinstalledApexPath = preinstalledApexPath; } } /** * Returns {@link ActiveApexInfo} records relative to all active APEX packages. */ abstract List<ActiveApexInfo> getActiveApexInfos(); abstract void systemReady(); /** Loading Loading @@ -258,6 +278,22 @@ abstract class ApexManager { return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @Override List<ActiveApexInfo> getActiveApexInfos() { try { return Arrays.stream(mApexService.getActivePackages()) .map(apexInfo -> new ActiveApexInfo( new File( Environment.getApexDirectory() + File.separator + apexInfo.moduleName), new File(apexInfo.modulePath))).collect( Collectors.toList()); } catch (RemoteException e) { Slog.e(TAG, "Unable to retrieve packages from apexservice", e); } return Collections.emptyList(); } @Override void systemReady() { mContext.registerReceiver(new BroadcastReceiver() { Loading Loading @@ -549,7 +585,40 @@ abstract class ApexManager { * An implementation of {@link ApexManager} that should be used in case device does not support * updating APEX packages. */ private static final class ApexManagerNoOp extends ApexManager { private static final class ApexManagerFlattenedApex extends ApexManager { @Override List<ActiveApexInfo> getActiveApexInfos() { // There is no apexd running in case of flattened apex // We look up the /apex directory and identify the active APEX modules from there. // As "preinstalled" path, we just report /system since in the case of flattened APEX // the /apex directory is just a symlink to /system/apex. List<ActiveApexInfo> result = new ArrayList<>(); File apexDir = Environment.getApexDirectory(); // In flattened configuration, init special-case the art directory and bind-mounts // com.android.art.{release|debug} to com.android.art. At the time of writing, these // directories are copied from the kArtApexDirNames variable in // system/core/init/mount_namespace.cpp. String[] skipDirs = {"com.android.art.release", "com.android.art.debug"}; if (apexDir.isDirectory()) { File[] files = apexDir.listFiles(); // listFiles might be null if system server doesn't have permission to read // a directory. if (files != null) { for (File file : files) { if (file.isDirectory() && !file.getName().contains("@")) { for (String skipDir : skipDirs) { if (file.getName().equals(skipDir)) { continue; } } result.add(new ActiveApexInfo(file, Environment.getRootDirectory())); } } } } return result; } @Override void systemReady() { Loading
services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +9 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,15 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { codeRoot = Environment.getSystemExtDirectory(); } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { codeRoot = Environment.getOdmDirectory(); } else if (FileUtils.contains(Environment.getApexDirectory(), codePath)) { String fullPath = codePath.getAbsolutePath(); String[] parts = fullPath.split(File.separator); if (parts.length > 2) { codeRoot = new File(parts[1] + File.separator + parts[2]); } else { Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath); codeRoot = Environment.getApexDirectory(); } } else { // Unrecognized code path; take its top real segment as the apk root: // e.g. /something/app/blah.apk => /something Loading
services/core/java/com/android/server/pm/PackageManagerService.java +159 −375 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/pm/Settings.java +1 −1 Original line number Diff line number Diff line Loading @@ -3510,7 +3510,7 @@ public final class Settings { int pkgFlags = 0; int pkgPrivateFlags = 0; pkgFlags |= ApplicationInfo.FLAG_SYSTEM; if (PackageManagerService.locationIsPrivileged(codePathStr)) { if (codePathStr.contains("/priv-app/")) { pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; } PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), Loading