Support privileged apps installed in APEX. am: 787471af48
am: 3fad35fa15
Change-Id: Idc501a4c77d6d3f13e7b416d98815d9b944c9202
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index c237222..7a131e5 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -55,6 +55,7 @@
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";
@@ -78,7 +79,9 @@
private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
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");
+ "/system_ext");
+ private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT,
+ "/apex");
@UnsupportedAppUsage
private static UserEnvironment sCurrentUser;
@@ -246,6 +249,16 @@
}
/**
+ * 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
* automatically deleted when the user is removed.
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index fd44cbb..12e8069 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -32,6 +32,7 @@
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;
@@ -47,6 +48,7 @@
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;
@@ -64,9 +66,9 @@
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)) {
@@ -77,10 +79,28 @@
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();
/**
@@ -259,6 +279,22 @@
}
@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() {
@Override
@@ -549,7 +585,40 @@
* 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() {
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 1d3d24c..259200b 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -67,6 +67,15 @@
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
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e72dea5..65c5236 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -91,6 +91,7 @@
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
@@ -376,6 +377,7 @@
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* Keep track of all those APKs everywhere.
@@ -590,16 +592,6 @@
private static final String PACKAGE_SCHEME = "package";
- private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
-
- private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
-
- private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
-
- private static final String ODM_OVERLAY_DIR = "/odm/overlay";
-
- private static final String OEM_OVERLAY_DIR = "/oem/overlay";
-
/** Canonical intent used to identify what counts as a "web browser" app */
private static final Intent sBrowserIntent;
static {
@@ -759,7 +751,31 @@
private final Injector mInjector;
/**
- * Unit tests will instantiate and / or extend to mock dependencies / behaviors.
+ * The list of all system partitions that may contain packages in ascending order of
+ * specificity (the more generic, the earlier in the list a partition appears).
+ */
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ static final List<SystemPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
+ Arrays.asList(
+ new SystemPartition(Environment.getRootDirectory(), 0 /* scanFlag */,
+ false /* hasOverlays */),
+ new SystemPartition(Environment.getVendorDirectory(), SCAN_AS_VENDOR,
+ true /* hasOverlays */),
+ new SystemPartition(Environment.getOdmDirectory(), SCAN_AS_ODM,
+ true /* hasOverlays */),
+ new SystemPartition(Environment.getOemDirectory(), SCAN_AS_OEM,
+ true /* hasOverlays */),
+ new SystemPartition(Environment.getProductDirectory(), SCAN_AS_PRODUCT,
+ true /* hasOverlays */),
+ new SystemPartition(Environment.getSystemExtDirectory(), SCAN_AS_SYSTEM_EXT,
+ true /* hasOverlays */)));
+
+ private final List<SystemPartition> mDirsToScanAsSystem;
+
+ /**
+ * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
+ *
+ * NOTE: All getters should return the same instance for every call.
*/
@VisibleForTesting
static class Injector {
@@ -2426,9 +2442,70 @@
}
}
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ static class SystemPartition {
+ public final File folder;
+ public final int scanFlag;
+ public final File appFolder;
+ @Nullable
+ public final File privAppFolder;
+ @Nullable
+ public final File overlayFolder;
+
+
+ private static boolean shouldScanPrivApps(@ScanFlags int scanFlags) {
+ if ((scanFlags & SCAN_AS_OEM) != 0) {
+ return false;
+ }
+ if (scanFlags == 0) { // /system partition
+ return true;
+ }
+ if ((scanFlags
+ & (SCAN_AS_VENDOR | SCAN_AS_ODM | SCAN_AS_PRODUCT | SCAN_AS_SYSTEM_EXT)) != 0) {
+ return true;
+ }
+ return false;
+ }
+
+ private SystemPartition(File folder, int scanFlag, boolean hasOverlays) {
+ this.folder = folder;
+ this.scanFlag = scanFlag;
+ this.appFolder = toCanonical(new File(folder, "app"));
+ this.privAppFolder = shouldScanPrivApps(scanFlag)
+ ? toCanonical(new File(folder, "priv-app"))
+ : null;
+ this.overlayFolder = hasOverlays ? toCanonical(new File(folder, "overlay")) : null;
+ }
+
+ public boolean containsPrivApp(File scanFile) {
+ return FileUtils.contains(privAppFolder, scanFile);
+ }
+
+ public boolean containsApp(File scanFile) {
+ return FileUtils.contains(appFolder, scanFile);
+ }
+
+ public boolean containsPath(String path) {
+ return path.startsWith(folder.getPath() + "/");
+ }
+
+ public boolean containsPrivPath(String path) {
+ return privAppFolder != null && path.startsWith(privAppFolder.getPath() + "/");
+ }
+
+ private static File toCanonical(File dir) {
+ try {
+ return dir.getCanonicalFile();
+ } catch (IOException e) {
+ // failed to look up canonical path, continue with original one
+ return dir;
+ }
+ }
+ }
+
public PackageManagerService(Context context, Installer installer,
- boolean factoryTest, boolean onlyCore) {
- LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
+ boolean factoryTest, boolean onlyCore) {
+ LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
@@ -2521,7 +2598,18 @@
mProtectedPackages = new ProtectedPackages(mContext);
- mApexManager = ApexManager.create(context);
+ mApexManager = ApexManager.create(mContext);
+
+ mDirsToScanAsSystem = new ArrayList<>();
+ mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
+ mDirsToScanAsSystem.addAll(mApexManager.getActiveApexInfos().stream()
+ .map(ai -> resolveApexToSystemPartition(ai))
+ .filter(Objects::nonNull).collect(Collectors.toList()));
+ Slog.d(TAG,
+ "Directories scanned as system partitions: [" + mDirsToScanAsSystem.stream().map(
+ d -> (d.folder.getAbsolutePath() + ":" + d.scanFlag))
+ .collect(Collectors.joining(",")) + "]");
+
// CHECKSTYLE:OFF IndentationCheck
synchronized (mInstallLock) {
// writer
@@ -2656,215 +2744,35 @@
// any apps.)
// For security and version matching reason, only consider overlay packages if they
// reside in the right directory.
- scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR,
- 0);
- scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT,
- 0);
- scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_SYSTEM_EXT,
- 0);
- scanDirTracedLI(new File(ODM_OVERLAY_DIR),
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_ODM,
- 0);
- scanDirTracedLI(new File(OEM_OVERLAY_DIR),
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_OEM,
- 0);
+ final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
+ final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
+ for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
+ final SystemPartition partition = mDirsToScanAsSystem.get(i);
+ if (partition.overlayFolder == null) {
+ continue;
+ }
+ scanDirTracedLI(partition.overlayFolder, systemParseFlags,
+ systemScanFlags | partition.scanFlag, 0);
+ }
mParallelPackageParserCallback.findStaticOverlayPackages();
- // Find base frameworks (resource packages without code).
- scanDirTracedLI(frameworkDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_NO_DEX
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRIVILEGED,
- 0);
+ scanDirTracedLI(frameworkDir, systemParseFlags,
+ systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0);
if (!mPackages.containsKey("android")) {
throw new IllegalStateException(
"Failed to load frameworks package; check log for warnings");
}
-
- // Collect privileged system packages.
- final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
- scanDirTracedLI(privilegedAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRIVILEGED,
- 0);
-
- // Collect ordinary system packages.
- final File systemAppDir = new File(Environment.getRootDirectory(), "app");
- scanDirTracedLI(systemAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM,
- 0);
-
- // Collect privileged vendor packages.
- File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
- try {
- privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
+ for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
+ final SystemPartition partition = mDirsToScanAsSystem.get(i);
+ if (partition.privAppFolder != null) {
+ scanDirTracedLI(partition.privAppFolder, systemParseFlags,
+ systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0);
+ }
+ scanDirTracedLI(partition.appFolder, systemParseFlags,
+ systemScanFlags | partition.scanFlag, 0);
}
- scanDirTracedLI(privilegedVendorAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR
- | SCAN_AS_PRIVILEGED,
- 0);
- // Collect ordinary vendor packages.
- File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
- try {
- vendorAppDir = vendorAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(vendorAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR,
- 0);
-
- // Collect privileged odm packages. /odm is another vendor partition
- // other than /vendor.
- File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
- "priv-app");
- try {
- privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(privilegedOdmAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR
- | SCAN_AS_PRIVILEGED,
- 0);
-
- // Collect ordinary odm packages. /odm is another vendor partition
- // other than /vendor.
- File odmAppDir = new File(Environment.getOdmDirectory(), "app");
- try {
- odmAppDir = odmAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(odmAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR,
- 0);
-
- // Collect all OEM packages.
- final File oemAppDir = new File(Environment.getOemDirectory(), "app");
- scanDirTracedLI(oemAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_OEM,
- 0);
-
- // Collected privileged /product packages.
- File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
- try {
- privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(privilegedProductAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT
- | SCAN_AS_PRIVILEGED,
- 0);
-
- // Collect ordinary /product packages.
- File productAppDir = new File(Environment.getProductDirectory(), "app");
- try {
- productAppDir = productAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(productAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT,
- 0);
-
- // Collected privileged /system_ext packages.
- File privilegedSystemExtAppDir =
- new File(Environment.getSystemExtDirectory(), "priv-app");
- try {
- privilegedSystemExtAppDir =
- privilegedSystemExtAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(privilegedSystemExtAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_SYSTEM_EXT
- | SCAN_AS_PRIVILEGED,
- 0);
-
- // Collect ordinary /system_ext packages.
- File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
- try {
- systemExtAppDir = systemExtAppDir.getCanonicalFile();
- } catch (IOException e) {
- // failed to look up canonical path, continue with original one
- }
- scanDirTracedLI(systemExtAppDir,
- mDefParseFlags
- | PackageParser.PARSE_IS_SYSTEM_DIR,
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_SYSTEM_EXT,
- 0);
// Prune any system packages that no longer exist.
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
@@ -3032,89 +2940,26 @@
logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");
- final @ParseFlags int reparseFlags;
- final @ScanFlags int rescanFlags;
- if (FileUtils.contains(privilegedAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRIVILEGED;
- } else if (FileUtils.contains(systemAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM;
- } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
- || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR
- | SCAN_AS_PRIVILEGED;
- } else if (FileUtils.contains(vendorAppDir, scanFile)
- || FileUtils.contains(odmAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_VENDOR;
- } else if (FileUtils.contains(oemAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_OEM;
- } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT
- | SCAN_AS_PRIVILEGED;
- } else if (FileUtils.contains(productAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_PRODUCT;
- } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_SYSTEM_EXT
- | SCAN_AS_PRIVILEGED;
- } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
- reparseFlags =
- mDefParseFlags |
- PackageParser.PARSE_IS_SYSTEM_DIR;
- rescanFlags =
- scanFlags
- | SCAN_AS_SYSTEM
- | SCAN_AS_SYSTEM_EXT;
- } else {
+ @ParseFlags int reparseFlags = 0;
+ @ScanFlags int rescanFlags = 0;
+ for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
+ SystemPartition partition = mDirsToScanAsSystem.get(i1);
+ if (partition.containsPrivApp(scanFile)) {
+ reparseFlags = systemParseFlags;
+ rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
+ | partition.scanFlag;
+ break;
+ }
+ if (partition.containsApp(scanFile)) {
+ reparseFlags = systemParseFlags;
+ rescanFlags = systemScanFlags | partition.scanFlag;
+ break;
+ }
+ }
+ if (rescanFlags == 0) {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
}
-
mSettings.enableSystemPackageLPw(packageName);
try {
@@ -18587,70 +18432,17 @@
}
}
- static boolean locationIsPrivileged(String path) {
- try {
- final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
- final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
- final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
- final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
- final File privilegedSystemExtAppDir =
- new File(Environment.getSystemExtDirectory(), "priv-app");
- return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
- || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
- || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
- || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
- || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
+ private static @Nullable SystemPartition resolveApexToSystemPartition(
+ ApexManager.ActiveApexInfo apexInfo) {
+ for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
+ SystemPartition sp = SYSTEM_PARTITIONS.get(i);
+ if (apexInfo.preinstalledApexPath.getAbsolutePath().startsWith(
+ sp.folder.getAbsolutePath())) {
+ return new SystemPartition(apexInfo.apexDirectory, sp.scanFlag,
+ false /* hasOverlays */);
+ }
}
- return false;
- }
-
- static boolean locationIsOem(String path) {
- try {
- return path.startsWith(Environment.getOemDirectory().getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
- }
- return false;
- }
-
- static boolean locationIsVendor(String path) {
- try {
- return path.startsWith(Environment.getVendorDirectory().getCanonicalPath() + "/")
- || path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
- }
- return false;
- }
-
- static boolean locationIsProduct(String path) {
- try {
- return path.startsWith(Environment.getProductDirectory().getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
- }
- return false;
- }
-
- static boolean locationIsSystemExt(String path) {
- try {
- return path.startsWith(
- Environment.getSystemExtDirectory().getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
- }
- return false;
- }
-
- static boolean locationIsOdm(String path) {
- try {
- return path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
- } catch (IOException e) {
- Slog.e(TAG, "Unable to access code path " + path);
- }
- return false;
+ return null;
}
/*
@@ -18762,23 +18554,15 @@
| PackageParser.PARSE_MUST_BE_APK
| PackageParser.PARSE_IS_SYSTEM_DIR;
@ScanFlags int scanFlags = SCAN_AS_SYSTEM;
- if (locationIsPrivileged(codePathString)) {
- scanFlags |= SCAN_AS_PRIVILEGED;
- }
- if (locationIsOem(codePathString)) {
- scanFlags |= SCAN_AS_OEM;
- }
- if (locationIsVendor(codePathString)) {
- scanFlags |= SCAN_AS_VENDOR;
- }
- if (locationIsProduct(codePathString)) {
- scanFlags |= SCAN_AS_PRODUCT;
- }
- if (locationIsSystemExt(codePathString)) {
- scanFlags |= SCAN_AS_SYSTEM_EXT;
- }
- if (locationIsOdm(codePathString)) {
- scanFlags |= SCAN_AS_ODM;
+ for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
+ SystemPartition partition = mDirsToScanAsSystem.get(i);
+ if (partition.containsPath(codePathString)) {
+ scanFlags |= partition.scanFlag;
+ if (partition.containsPrivPath(codePathString)) {
+ scanFlags |= SCAN_AS_PRIVILEGED;
+ }
+ break;
+ }
}
final File codePath = new File(codePathString);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 0c582ca..994fca8 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3510,7 +3510,7 @@
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),
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index fc7cfec..0a310d1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -118,17 +118,20 @@
String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
String[] appdir = { "app", "priv-app" };
for (int i = 0; i < partitions.length; i++) {
+ final PackageManagerService.SystemPartition systemPartition =
+ PackageManagerService.SYSTEM_PARTITIONS.get(i);
for (int j = 0; j < appdir.length; j++) {
String canonical = new File("/" + partitions[i]).getCanonicalPath();
String path = String.format("%s/%s/A.apk", canonical, appdir[j]);
- Assert.assertEquals(j == 1 && i != 3,
- PackageManagerService.locationIsPrivileged(path));
+ Assert.assertEquals(j == 1 && i != 3, systemPartition.containsPrivPath(path));
- Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
- Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
- Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
- Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
+ final int scanFlag = systemPartition.scanFlag;
+ Assert.assertEquals(i == 1, scanFlag == PackageManagerService.SCAN_AS_VENDOR);
+ Assert.assertEquals(i == 2, scanFlag == PackageManagerService.SCAN_AS_ODM);
+ Assert.assertEquals(i == 3, scanFlag == PackageManagerService.SCAN_AS_OEM);
+ Assert.assertEquals(i == 4, scanFlag == PackageManagerService.SCAN_AS_PRODUCT);
+ Assert.assertEquals(i == 5, scanFlag == PackageManagerService.SCAN_AS_SYSTEM_EXT);
}
}
}