Loading services/core/java/com/android/server/pm/ApexManager.java +10 −15 Original line number Diff line number Diff line Loading @@ -104,11 +104,11 @@ public abstract class ApexManager { static class ScanResult { public final ApexInfo apexInfo; public final ParsedPackage parsedPackage; public final AndroidPackage pkg; public final String packageName; ScanResult(ApexInfo apexInfo, ParsedPackage parsedPackage, String packageName) { ScanResult(ApexInfo apexInfo, AndroidPackage pkg, String packageName) { this.apexInfo = apexInfo; this.parsedPackage = parsedPackage; this.pkg = pkg; this.packageName = packageName; } } Loading Loading @@ -357,8 +357,10 @@ public abstract class ApexManager { /** * Performs a non-staged install of the given {@code apexFile}. * * @return {@code ApeInfo} about the newly installed APEX package. */ abstract void installPackage(File apexFile, PackageParser2 packageParser, abstract ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) throws PackageManagerException; /** Loading Loading @@ -470,7 +472,7 @@ public abstract class ApexManager { ApexInfo ai = scanResult.apexInfo; String packageName = scanResult.packageName; for (ParsedApexSystemService service : scanResult.parsedPackage.getApexSystemServices()) { scanResult.pkg.getApexSystemServices()) { String minSdkVersion = service.getMinSdkVersion(); if (minSdkVersion != null && !UnboundedSdkLevel.isAtLeast(minSdkVersion)) { Slog.d(TAG, String.format( Loading Loading @@ -896,7 +898,7 @@ public abstract class ApexManager { } @Override void installPackage(File apexFile, PackageParser2 packageParser, ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) throws PackageManagerException { try { Loading @@ -919,14 +921,7 @@ public abstract class ApexManager { "It is forbidden to install new APEX packages"); } checkApexSignature(existingApexPkg, newApexPkg); ApexInfo apexInfo = waitForApexService().installAndActivatePackage( apexFile.getAbsolutePath()); final ParsedPackage parsedPackage2 = packageParser.parsePackage( new File(apexInfo.modulePath), flags, /* useCaches= */ false); final PackageInfo finalApexPkg = PackageInfoWithoutStateUtils.generate( parsedPackage2, apexInfo, flags); // Installation was successful, time to update cached PackageInfo apexPackageInfo.notifyPackageInstalled(existingApexPkg, finalApexPkg); return waitForApexService().installAndActivatePackage(apexFile.getAbsolutePath()); } catch (RemoteException e) { throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, "apexservice not available"); Loading Loading @@ -1166,7 +1161,7 @@ public abstract class ApexManager { } @Override void installPackage(File apexFile, PackageParser2 packageParser, ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) { throw new UnsupportedOperationException("APEX updates are not supported"); } Loading services/core/java/com/android/server/pm/ApexPackageInfo.java +31 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils; import com.android.server.pm.pkg.parsing.ParsingPackageUtils; Loading @@ -50,6 +52,8 @@ import java.util.concurrent.ExecutorService; * including both APK and APEX. This class will no longer be needed when the migration is done. */ class ApexPackageInfo { public static final boolean ENABLE_FEATURE_SCAN_APEX = true; private static final String TAG = "ApexManager"; private static final String VNDK_APEX_MODULE_NAME_PREFIX = "com.android.vndk."; Loading Loading @@ -83,6 +87,12 @@ class ApexPackageInfo { } } void notifyScanResult(List<ApexManager.ScanResult> scanResults) { synchronized (mLock) { notifyScanResultLocked(scanResults); } } /** * Retrieves information about an APEX package. * Loading Loading @@ -200,12 +210,29 @@ class ApexPackageInfo { } /** * Called by ApexManager to update cached PackageInfo when installing rebootless APEX. * Called to update cached PackageInfo when installing rebootless APEX. */ void notifyPackageInstalled(PackageInfo oldApexPkg, PackageInfo newApexPkg) { void notifyPackageInstalled(ApexInfo apexInfo, PackageParser2 packageParser) throws PackageManagerException { final int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; final ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), flags, /* useCaches= */ false); notifyPackageInstalled(apexInfo, parsedPackage.hideAsFinal()); } void notifyPackageInstalled(ApexInfo apexInfo, AndroidPackage pkg) { final int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; final PackageInfo newApexPkg = PackageInfoWithoutStateUtils.generate( pkg, apexInfo, flags); final String packageName = newApexPkg.packageName; synchronized (mLock) { for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) { if (mAllPackagesCache.get(i).equals(oldApexPkg)) { PackageInfo oldApexPkg = mAllPackagesCache.get(i); if (oldApexPkg.isActiveApex && oldApexPkg.packageName.equals(packageName)) { if (isFactory(oldApexPkg)) { oldApexPkg.isActiveApex = false; mAllPackagesCache.add(newApexPkg); Loading Loading @@ -264,7 +291,7 @@ class ApexPackageInfo { ApexInfo ai = result.apexInfo; final PackageInfo packageInfo = PackageInfoWithoutStateUtils.generate( result.parsedPackage, ai, flags); result.pkg, ai, flags); if (packageInfo == null) { throw new IllegalStateException("Unable to generate package info: " + ai.modulePath); Loading services/core/java/com/android/server/pm/InitAppsHelper.java +12 −2 Original line number Diff line number Diff line Loading @@ -185,9 +185,19 @@ final class InitAppsHelper { @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) private List<ApexManager.ScanResult> scanApexPackagesTraced(PackageParser2 packageParser) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanApexPackages"); try { return mApexPackageInfo.scanApexPackages( final List<ApexManager.ScanResult> apexScanResults; if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { apexScanResults = mInstallPackageHelper.scanApexPackages( mApexManager.getAllApexInfos(), mSystemParseFlags, mSystemScanFlags, packageParser, mExecutorService); mApexPackageInfo.notifyScanResult(apexScanResults); } else { apexScanResults = mApexPackageInfo.scanApexPackages( mApexManager.getAllApexInfos(), packageParser, mExecutorService); } return apexScanResults; } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +68 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.POST_INSTALL; import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS; import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX; import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX; import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY; import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; Loading Loading @@ -92,6 +93,7 @@ import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.apex.ApexInfo; import android.app.AppOpsManager; import android.app.ApplicationPackageManager; import android.app.backup.IBackupManager; Loading Loading @@ -870,7 +872,17 @@ final class InstallPackageHelper { + " got: " + apexes.length); } try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) { mApexManager.installPackage(apexes[0], packageParser, mPm.mApexPackageInfo); ApexInfo apexInfo = mApexManager.installPackage( apexes[0], packageParser, mPm.mApexPackageInfo); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), 0, /* useCaches= */ false); scanSystemPackageLI(parsedPackage, 0, SCAN_AS_APEX, null); mPm.mApexPackageInfo.notifyPackageInstalled( apexInfo, parsedPackage.hideAsFinal()); } else { mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser); } } } catch (PackageManagerException e) { request.mInstallResult.setError("APEX installation failed", e); Loading Loading @@ -3378,6 +3390,56 @@ final class InstallPackageHelper { } } public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { if (allPackages == null) { return Collections.EMPTY_LIST; } ParallelPackageParser parallelPackageParser = new ParallelPackageParser(packageParser, executorService); // Submit files for parsing in parallel ArrayMap<File, ApexInfo> parsingApexInfo = new ArrayMap<>(); for (ApexInfo ai : allPackages) { File apexFile = new File(ai.modulePath); parallelPackageParser.submit(apexFile, parseFlags); parsingApexInfo.put(apexFile, ai); } // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parsingApexInfo.size(); i++) { ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); Throwable throwable = parseResult.throwable; ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); int newScanFlags = scanFlags | SCAN_AS_APEX; if (throwable == null) { try { scanSystemPackageLI(parseResult.parsedPackage, parseFlags, newScanFlags, null); AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal(); results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName())); } catch (PackageManagerException e) { throw new IllegalStateException("Failed to scan: " + ai.modulePath, e); } } else if (throwable instanceof PackageManagerException) { final PackageManagerException e = (PackageManagerException) throwable; // Skip parsing non-coreApp apex file if system is in minimal boot state. if (e.error == PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED) { Slog.w(TAG, "Scan apex failed, not a coreApp:" + ai.modulePath); continue; } throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable); } else { throw new IllegalStateException("Unexpected exception occurred while parsing " + ai.modulePath, throwable); } } return results; } @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags, int scanFlags, PackageParser2 packageParser, Loading Loading @@ -4079,8 +4141,12 @@ final class InstallPackageHelper { // after OTA. final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; // It is allowed to install a new APEX with the same name. But there shouldn't be // conflicting names between APK and APEX. final boolean installApex = (scanFlags & SCAN_AS_APEX) != 0; if ((isUserInstall || isFirstBootOrUpgrade) && mPm.mApexPackageInfo.isApexPackage(pkg.getPackageName())) { && mPm.mApexPackageInfo.isApexPackage(pkg.getPackageName()) && !installApex) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, pkg.getPackageName() + " is an APEX package and can't be installed as an APK."); Loading services/core/java/com/android/server/pm/PackageManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int SCAN_AS_ODM = 1 << 22; static final int SCAN_AS_APK_IN_APEX = 1 << 23; static final int SCAN_AS_FACTORY = 1 << 24; static final int SCAN_AS_APEX = 1 << 25; @IntDef(flag = true, prefix = { "SCAN_" }, value = { SCAN_NO_DEX, Loading Loading
services/core/java/com/android/server/pm/ApexManager.java +10 −15 Original line number Diff line number Diff line Loading @@ -104,11 +104,11 @@ public abstract class ApexManager { static class ScanResult { public final ApexInfo apexInfo; public final ParsedPackage parsedPackage; public final AndroidPackage pkg; public final String packageName; ScanResult(ApexInfo apexInfo, ParsedPackage parsedPackage, String packageName) { ScanResult(ApexInfo apexInfo, AndroidPackage pkg, String packageName) { this.apexInfo = apexInfo; this.parsedPackage = parsedPackage; this.pkg = pkg; this.packageName = packageName; } } Loading Loading @@ -357,8 +357,10 @@ public abstract class ApexManager { /** * Performs a non-staged install of the given {@code apexFile}. * * @return {@code ApeInfo} about the newly installed APEX package. */ abstract void installPackage(File apexFile, PackageParser2 packageParser, abstract ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) throws PackageManagerException; /** Loading Loading @@ -470,7 +472,7 @@ public abstract class ApexManager { ApexInfo ai = scanResult.apexInfo; String packageName = scanResult.packageName; for (ParsedApexSystemService service : scanResult.parsedPackage.getApexSystemServices()) { scanResult.pkg.getApexSystemServices()) { String minSdkVersion = service.getMinSdkVersion(); if (minSdkVersion != null && !UnboundedSdkLevel.isAtLeast(minSdkVersion)) { Slog.d(TAG, String.format( Loading Loading @@ -896,7 +898,7 @@ public abstract class ApexManager { } @Override void installPackage(File apexFile, PackageParser2 packageParser, ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) throws PackageManagerException { try { Loading @@ -919,14 +921,7 @@ public abstract class ApexManager { "It is forbidden to install new APEX packages"); } checkApexSignature(existingApexPkg, newApexPkg); ApexInfo apexInfo = waitForApexService().installAndActivatePackage( apexFile.getAbsolutePath()); final ParsedPackage parsedPackage2 = packageParser.parsePackage( new File(apexInfo.modulePath), flags, /* useCaches= */ false); final PackageInfo finalApexPkg = PackageInfoWithoutStateUtils.generate( parsedPackage2, apexInfo, flags); // Installation was successful, time to update cached PackageInfo apexPackageInfo.notifyPackageInstalled(existingApexPkg, finalApexPkg); return waitForApexService().installAndActivatePackage(apexFile.getAbsolutePath()); } catch (RemoteException e) { throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, "apexservice not available"); Loading Loading @@ -1166,7 +1161,7 @@ public abstract class ApexManager { } @Override void installPackage(File apexFile, PackageParser2 packageParser, ApexInfo installPackage(File apexFile, PackageParser2 packageParser, ApexPackageInfo apexPackageInfo) { throw new UnsupportedOperationException("APEX updates are not supported"); } Loading
services/core/java/com/android/server/pm/ApexPackageInfo.java +31 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils; import com.android.server.pm.pkg.parsing.ParsingPackageUtils; Loading @@ -50,6 +52,8 @@ import java.util.concurrent.ExecutorService; * including both APK and APEX. This class will no longer be needed when the migration is done. */ class ApexPackageInfo { public static final boolean ENABLE_FEATURE_SCAN_APEX = true; private static final String TAG = "ApexManager"; private static final String VNDK_APEX_MODULE_NAME_PREFIX = "com.android.vndk."; Loading Loading @@ -83,6 +87,12 @@ class ApexPackageInfo { } } void notifyScanResult(List<ApexManager.ScanResult> scanResults) { synchronized (mLock) { notifyScanResultLocked(scanResults); } } /** * Retrieves information about an APEX package. * Loading Loading @@ -200,12 +210,29 @@ class ApexPackageInfo { } /** * Called by ApexManager to update cached PackageInfo when installing rebootless APEX. * Called to update cached PackageInfo when installing rebootless APEX. */ void notifyPackageInstalled(PackageInfo oldApexPkg, PackageInfo newApexPkg) { void notifyPackageInstalled(ApexInfo apexInfo, PackageParser2 packageParser) throws PackageManagerException { final int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; final ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), flags, /* useCaches= */ false); notifyPackageInstalled(apexInfo, parsedPackage.hideAsFinal()); } void notifyPackageInstalled(ApexInfo apexInfo, AndroidPackage pkg) { final int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; final PackageInfo newApexPkg = PackageInfoWithoutStateUtils.generate( pkg, apexInfo, flags); final String packageName = newApexPkg.packageName; synchronized (mLock) { for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) { if (mAllPackagesCache.get(i).equals(oldApexPkg)) { PackageInfo oldApexPkg = mAllPackagesCache.get(i); if (oldApexPkg.isActiveApex && oldApexPkg.packageName.equals(packageName)) { if (isFactory(oldApexPkg)) { oldApexPkg.isActiveApex = false; mAllPackagesCache.add(newApexPkg); Loading Loading @@ -264,7 +291,7 @@ class ApexPackageInfo { ApexInfo ai = result.apexInfo; final PackageInfo packageInfo = PackageInfoWithoutStateUtils.generate( result.parsedPackage, ai, flags); result.pkg, ai, flags); if (packageInfo == null) { throw new IllegalStateException("Unable to generate package info: " + ai.modulePath); Loading
services/core/java/com/android/server/pm/InitAppsHelper.java +12 −2 Original line number Diff line number Diff line Loading @@ -185,9 +185,19 @@ final class InitAppsHelper { @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) private List<ApexManager.ScanResult> scanApexPackagesTraced(PackageParser2 packageParser) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanApexPackages"); try { return mApexPackageInfo.scanApexPackages( final List<ApexManager.ScanResult> apexScanResults; if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { apexScanResults = mInstallPackageHelper.scanApexPackages( mApexManager.getAllApexInfos(), mSystemParseFlags, mSystemScanFlags, packageParser, mExecutorService); mApexPackageInfo.notifyScanResult(apexScanResults); } else { apexScanResults = mApexPackageInfo.scanApexPackages( mApexManager.getAllApexInfos(), packageParser, mExecutorService); } return apexScanResults; } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +68 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.POST_INSTALL; import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS; import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX; import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX; import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY; import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; Loading Loading @@ -92,6 +93,7 @@ import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.apex.ApexInfo; import android.app.AppOpsManager; import android.app.ApplicationPackageManager; import android.app.backup.IBackupManager; Loading Loading @@ -870,7 +872,17 @@ final class InstallPackageHelper { + " got: " + apexes.length); } try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) { mApexManager.installPackage(apexes[0], packageParser, mPm.mApexPackageInfo); ApexInfo apexInfo = mApexManager.installPackage( apexes[0], packageParser, mPm.mApexPackageInfo); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), 0, /* useCaches= */ false); scanSystemPackageLI(parsedPackage, 0, SCAN_AS_APEX, null); mPm.mApexPackageInfo.notifyPackageInstalled( apexInfo, parsedPackage.hideAsFinal()); } else { mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser); } } } catch (PackageManagerException e) { request.mInstallResult.setError("APEX installation failed", e); Loading Loading @@ -3378,6 +3390,56 @@ final class InstallPackageHelper { } } public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { if (allPackages == null) { return Collections.EMPTY_LIST; } ParallelPackageParser parallelPackageParser = new ParallelPackageParser(packageParser, executorService); // Submit files for parsing in parallel ArrayMap<File, ApexInfo> parsingApexInfo = new ArrayMap<>(); for (ApexInfo ai : allPackages) { File apexFile = new File(ai.modulePath); parallelPackageParser.submit(apexFile, parseFlags); parsingApexInfo.put(apexFile, ai); } // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parsingApexInfo.size(); i++) { ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); Throwable throwable = parseResult.throwable; ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); int newScanFlags = scanFlags | SCAN_AS_APEX; if (throwable == null) { try { scanSystemPackageLI(parseResult.parsedPackage, parseFlags, newScanFlags, null); AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal(); results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName())); } catch (PackageManagerException e) { throw new IllegalStateException("Failed to scan: " + ai.modulePath, e); } } else if (throwable instanceof PackageManagerException) { final PackageManagerException e = (PackageManagerException) throwable; // Skip parsing non-coreApp apex file if system is in minimal boot state. if (e.error == PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED) { Slog.w(TAG, "Scan apex failed, not a coreApp:" + ai.modulePath); continue; } throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable); } else { throw new IllegalStateException("Unexpected exception occurred while parsing " + ai.modulePath, throwable); } } return results; } @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags, int scanFlags, PackageParser2 packageParser, Loading Loading @@ -4079,8 +4141,12 @@ final class InstallPackageHelper { // after OTA. final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; // It is allowed to install a new APEX with the same name. But there shouldn't be // conflicting names between APK and APEX. final boolean installApex = (scanFlags & SCAN_AS_APEX) != 0; if ((isUserInstall || isFirstBootOrUpgrade) && mPm.mApexPackageInfo.isApexPackage(pkg.getPackageName())) { && mPm.mApexPackageInfo.isApexPackage(pkg.getPackageName()) && !installApex) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, pkg.getPackageName() + " is an APEX package and can't be installed as an APK."); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int SCAN_AS_ODM = 1 << 22; static final int SCAN_AS_APK_IN_APEX = 1 << 23; static final int SCAN_AS_FACTORY = 1 << 24; static final int SCAN_AS_APEX = 1 << 25; @IntDef(flag = true, prefix = { "SCAN_" }, value = { SCAN_NO_DEX, Loading