Merge changes from topic "225756739_fix_run_as"
* changes: Don't persist APEX Revert "Revert "Migrate APEX package info from ApexPackageInfo to PMS""
This commit is contained in:
committed by
Android (Google) Code Review
commit
bd95a76f4a
@@ -368,7 +368,7 @@ public final class UserHandle implements Parcelable {
|
||||
@UnsupportedAppUsage
|
||||
@TestApi
|
||||
public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
|
||||
if (MU_ENABLED) {
|
||||
if (MU_ENABLED && appId >= 0) {
|
||||
return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
|
||||
} else {
|
||||
return appId;
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
@@ -271,11 +270,11 @@ class ApexPackageInfo {
|
||||
}
|
||||
}
|
||||
ipw.println("Active APEX packages:");
|
||||
dumpFromPackagesCache(getActivePackages(), packageName, ipw);
|
||||
dumpPackages(getActivePackages(), packageName, ipw);
|
||||
ipw.println("Inactive APEX packages:");
|
||||
dumpFromPackagesCache(getInactivePackages(), packageName, ipw);
|
||||
dumpPackages(getInactivePackages(), packageName, ipw);
|
||||
ipw.println("Factory APEX packages:");
|
||||
dumpFromPackagesCache(getFactoryPackages(), packageName, ipw);
|
||||
dumpPackages(getFactoryPackages(), packageName, ipw);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -370,7 +369,7 @@ class ApexPackageInfo {
|
||||
* only information about that specific package will be dumped.
|
||||
* @param ipw the {@link IndentingPrintWriter} object to send information to.
|
||||
*/
|
||||
private static void dumpFromPackagesCache(List<PackageInfo> packagesCache,
|
||||
static void dumpPackages(List<PackageInfo> packagesCache,
|
||||
@Nullable String packageName, IndentingPrintWriter ipw) {
|
||||
ipw.println();
|
||||
ipw.increaseIndent();
|
||||
|
||||
@@ -984,9 +984,15 @@ public class ComputerEngine implements Computer {
|
||||
TAG, "getApplicationInfo " + packageName
|
||||
+ ": " + p);
|
||||
}
|
||||
final boolean matchApex = (flags & MATCH_APEX) != 0;
|
||||
if (p != null) {
|
||||
PackageStateInternal ps = mSettings.getPackage(packageName);
|
||||
if (ps == null) return null;
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!matchApex && p.isApex()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1001,20 +1007,22 @@ public class ComputerEngine implements Computer {
|
||||
}
|
||||
return ai;
|
||||
}
|
||||
if ((flags & PackageManager.MATCH_APEX) != 0) {
|
||||
// For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo
|
||||
// returned from getApplicationInfo, but for APEX packages difference shouldn't be
|
||||
// very big.
|
||||
// TODO(b/155328545): generate proper application info for APEXes as well.
|
||||
int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE;
|
||||
if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
|
||||
apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
|
||||
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (matchApex) {
|
||||
// For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo
|
||||
// returned from getApplicationInfo, but for APEX packages difference shouldn't be
|
||||
// very big.
|
||||
// TODO(b/155328545): generate proper application info for APEXes as well.
|
||||
int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE;
|
||||
if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
|
||||
apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
|
||||
}
|
||||
final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
|
||||
if (pi == null) {
|
||||
return null;
|
||||
}
|
||||
return pi.applicationInfo;
|
||||
}
|
||||
final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
|
||||
if (pi == null) {
|
||||
return null;
|
||||
}
|
||||
return pi.applicationInfo;
|
||||
}
|
||||
if ("android".equals(packageName) || "system".equals(packageName)) {
|
||||
return androidApplication();
|
||||
@@ -1704,14 +1712,22 @@ public class ComputerEngine implements Computer {
|
||||
packageName = resolveInternalPackageName(packageName, versionCode);
|
||||
|
||||
final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
|
||||
final boolean matchApex = (flags & MATCH_APEX) != 0;
|
||||
if (matchFactoryOnly) {
|
||||
// Instant app filtering for APEX modules is ignored
|
||||
if ((flags & MATCH_APEX) != 0) {
|
||||
return mApexPackageInfo.getPackageInfo(packageName,
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (matchApex) {
|
||||
return mApexPackageInfo.getPackageInfo(packageName,
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
}
|
||||
}
|
||||
final PackageStateInternal ps = mSettings.getDisabledSystemPkg(packageName);
|
||||
if (ps != null) {
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!matchApex && ps.getPkg() != null && ps.getPkg().isApex()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1731,6 +1747,11 @@ public class ComputerEngine implements Computer {
|
||||
}
|
||||
if (p != null) {
|
||||
final PackageStateInternal ps = getPackageStateInternal(p.getPackageName());
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!matchApex && p.isApex()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1751,8 +1772,11 @@ public class ComputerEngine implements Computer {
|
||||
}
|
||||
return generatePackageInfo(ps, flags, userId);
|
||||
}
|
||||
if ((flags & MATCH_APEX) != 0) {
|
||||
return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (matchApex) {
|
||||
return mApexPackageInfo.getPackageInfo(packageName,
|
||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1809,6 +1833,11 @@ public class ComputerEngine implements Computer {
|
||||
ps = psDisabled;
|
||||
}
|
||||
}
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1834,6 +1863,11 @@ public class ComputerEngine implements Computer {
|
||||
ps = psDisabled;
|
||||
}
|
||||
}
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!listApex && p.isApex()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1846,11 +1880,13 @@ public class ComputerEngine implements Computer {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (listApex) {
|
||||
if (listFactory) {
|
||||
list.addAll(mApexPackageInfo.getFactoryPackages());
|
||||
} else {
|
||||
list.addAll(mApexPackageInfo.getActivePackages());
|
||||
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (listApex) {
|
||||
if (listFactory) {
|
||||
list.addAll(mApexPackageInfo.getFactoryPackages());
|
||||
} else {
|
||||
list.addAll(mApexPackageInfo.getActivePackages());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ParceledListSlice<>(list);
|
||||
@@ -3338,13 +3374,58 @@ public class ComputerEngine implements Computer {
|
||||
case DumpState.DUMP_APEX: {
|
||||
if (packageName == null || isApexPackage(packageName)) {
|
||||
mApexManager.dump(pw);
|
||||
mApexPackageInfo.dump(pw, packageName);
|
||||
dumpApex(pw, packageName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
private void generateApexPackageInfo(List<PackageInfo> activePackages,
|
||||
List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) {
|
||||
for (AndroidPackage p : mPackages.values()) {
|
||||
final String packageName = p.getPackageName();
|
||||
PackageStateInternal ps = mSettings.getPackage(packageName);
|
||||
if (!p.isApex() || ps == null) {
|
||||
continue;
|
||||
}
|
||||
PackageInfo pi = generatePackageInfo(ps, 0, 0);
|
||||
if (pi == null) {
|
||||
continue;
|
||||
}
|
||||
pi.isActiveApex = true;
|
||||
activePackages.add(pi);
|
||||
if (!ps.isUpdatedSystemApp()) {
|
||||
factoryPackages.add(pi);
|
||||
} else {
|
||||
PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName);
|
||||
pi = generatePackageInfo(psDisabled, 0, 0);
|
||||
if (pi != null) {
|
||||
factoryPackages.add(pi);
|
||||
inactivePackages.add(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpApex(PrintWriter pw, String packageName) {
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
|
||||
List<PackageInfo> activePackages = new ArrayList<>();
|
||||
List<PackageInfo> inactivePackages = new ArrayList<>();
|
||||
List<PackageInfo> factoryPackages = new ArrayList<>();
|
||||
generateApexPackageInfo(activePackages, inactivePackages, factoryPackages);
|
||||
ipw.println("Active APEX packages:");
|
||||
ApexPackageInfo.dumpPackages(activePackages, packageName, ipw);
|
||||
ipw.println("Inactive APEX packages:");
|
||||
ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw);
|
||||
ipw.println("Factory APEX packages:");
|
||||
ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw);
|
||||
} else {
|
||||
mApexPackageInfo.dump(pw, packageName);
|
||||
}
|
||||
}
|
||||
|
||||
// The body of findPreferredActivity.
|
||||
protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody(
|
||||
Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
|
||||
@@ -3721,7 +3802,12 @@ public class ComputerEngine implements Computer {
|
||||
|
||||
@Override
|
||||
public boolean isApexPackage(String packageName) {
|
||||
return mApexPackageInfo.isApexPackage(packageName);
|
||||
if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
return mApexPackageInfo.isApexPackage(packageName);
|
||||
} else {
|
||||
final AndroidPackage pkg = mPackages.get(packageName);
|
||||
return pkg != null && pkg.isApex();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4710,6 +4796,7 @@ public class ComputerEngine implements Computer {
|
||||
if (!mUserManager.exists(userId)) return Collections.emptyList();
|
||||
flags = updateFlagsForApplication(flags, userId);
|
||||
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
|
||||
final boolean listApex = (flags & MATCH_APEX) != 0;
|
||||
|
||||
enforceCrossUserPermission(
|
||||
callingUid,
|
||||
@@ -4730,6 +4817,11 @@ public class ComputerEngine implements Computer {
|
||||
effectiveFlags |= PackageManager.MATCH_ANY_USER;
|
||||
}
|
||||
if (ps.getPkg() != null) {
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!listApex && ps.getPkg().isApex()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
|
||||
continue;
|
||||
}
|
||||
@@ -4758,6 +4850,11 @@ public class ComputerEngine implements Computer {
|
||||
if (pkg == null) {
|
||||
continue;
|
||||
}
|
||||
if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
|
||||
if (!listApex && pkg.isApex()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (filterSharedLibPackage(packageState, Binder.getCallingUid(), userId, flags)) {
|
||||
continue;
|
||||
}
|
||||
@@ -5113,7 +5210,7 @@ public class ComputerEngine implements Computer {
|
||||
final PackageStateInternal ps = mSettings.getPackage(packageName);
|
||||
|
||||
// Installer info for Apex is not stored in PackageManager
|
||||
if (ps == null && mApexPackageInfo.isApexPackage(packageName)) {
|
||||
if (isApexPackage(packageName)) {
|
||||
return InstallSource.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,6 @@ final class InitAppsHelper {
|
||||
apexScanResults = mInstallPackageHelper.scanApexPackages(
|
||||
mApexManager.getAllApexInfos(), mSystemParseFlags, mSystemScanFlags,
|
||||
packageParser, mExecutorService);
|
||||
mApexPackageInfo.notifyScanResult(apexScanResults);
|
||||
} else {
|
||||
apexScanResults = mApexPackageInfo.scanApexPackages(
|
||||
mApexManager.getAllApexInfos(), packageParser, mExecutorService);
|
||||
|
||||
@@ -829,19 +829,24 @@ final class InstallPackageHelper {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
processApkInstallRequests(success, installRequests);
|
||||
}
|
||||
|
||||
private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
|
||||
if (success) {
|
||||
for (InstallRequest request : apkInstallRequests) {
|
||||
for (InstallRequest request : installRequests) {
|
||||
request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
|
||||
}
|
||||
synchronized (mPm.mInstallLock) {
|
||||
installPackagesTracedLI(apkInstallRequests);
|
||||
installPackagesTracedLI(installRequests);
|
||||
}
|
||||
for (InstallRequest request : apkInstallRequests) {
|
||||
for (InstallRequest request : installRequests) {
|
||||
request.mArgs.doPostInstall(
|
||||
request.mInstallResult.mReturnCode, request.mInstallResult.mUid);
|
||||
}
|
||||
}
|
||||
for (InstallRequest request : apkInstallRequests) {
|
||||
for (InstallRequest request : installRequests) {
|
||||
restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
|
||||
request.mInstallResult,
|
||||
new PostInstallData(request.mArgs,
|
||||
@@ -883,11 +888,15 @@ final class InstallPackageHelper {
|
||||
try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
|
||||
ApexInfo apexInfo = mApexManager.installPackage(apexes[0]);
|
||||
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());
|
||||
// APEX has been handled successfully by apexd. Let's continue the install flow
|
||||
// so it will be scanned and registered with the system.
|
||||
// TODO(b/225756739): Improve atomicity of rebootless APEX install.
|
||||
// The newly installed APEX will not be reverted even if
|
||||
// processApkInstallRequests() fails. Need a way to keep info stored in apexd
|
||||
// and PMS in sync in the face of install failures.
|
||||
request.mInstallResult.mApexInfo = apexInfo;
|
||||
mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
|
||||
return;
|
||||
} else {
|
||||
mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser);
|
||||
}
|
||||
@@ -988,7 +997,12 @@ final class InstallPackageHelper {
|
||||
+ PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
|
||||
return;
|
||||
}
|
||||
createdAppId.put(packageName, optimisticallyRegisterAppId(result));
|
||||
final boolean isApex = (result.mRequest.mScanFlags & SCAN_AS_APEX) != 0;
|
||||
if (!isApex) {
|
||||
createdAppId.put(packageName, optimisticallyRegisterAppId(result));
|
||||
} else {
|
||||
result.mPkgSetting.setAppId(Process.INVALID_UID);
|
||||
}
|
||||
versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
|
||||
mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
|
||||
} catch (PackageManagerException e) {
|
||||
@@ -1091,12 +1105,12 @@ final class InstallPackageHelper {
|
||||
private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
|
||||
throws PrepareFailure {
|
||||
final int installFlags = args.mInstallFlags;
|
||||
final File tmpPackageFile = new File(args.getCodePath());
|
||||
final boolean onExternal = args.mVolumeUuid != null;
|
||||
final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
|
||||
final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
|
||||
final boolean virtualPreload =
|
||||
((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
|
||||
final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0);
|
||||
final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
|
||||
@PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
|
||||
if (args.mMoveInfo != null) {
|
||||
@@ -1115,7 +1129,12 @@ final class InstallPackageHelper {
|
||||
if (virtualPreload) {
|
||||
scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
|
||||
}
|
||||
if (isApex) {
|
||||
scanFlags |= SCAN_AS_APEX;
|
||||
}
|
||||
|
||||
final File tmpPackageFile = new File(
|
||||
isApex ? res.mApexInfo.modulePath : args.getCodePath());
|
||||
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
|
||||
|
||||
// Validity check
|
||||
@@ -1521,16 +1540,22 @@ final class InstallPackageHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (!args.doRename(res.mReturnCode, parsedPackage)) {
|
||||
throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
|
||||
}
|
||||
if (!isApex) {
|
||||
if (!args.doRename(res.mReturnCode, parsedPackage)) {
|
||||
throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
|
||||
}
|
||||
|
||||
try {
|
||||
setUpFsVerityIfPossible(parsedPackage);
|
||||
} catch (Installer.InstallerException | IOException | DigestException
|
||||
| NoSuchAlgorithmException e) {
|
||||
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
|
||||
"Failed to set up verity: " + e);
|
||||
try {
|
||||
setUpFsVerityIfPossible(parsedPackage);
|
||||
} catch (Installer.InstallerException | IOException | DigestException
|
||||
| NoSuchAlgorithmException e) {
|
||||
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
|
||||
"Failed to set up verity: " + e);
|
||||
}
|
||||
} else {
|
||||
// Use the path returned by apexd
|
||||
parsedPackage.setPath(res.mApexInfo.modulePath);
|
||||
parsedPackage.setBaseApkPath(res.mApexInfo.modulePath);
|
||||
}
|
||||
|
||||
final PackageFreezer freezer =
|
||||
@@ -1937,6 +1962,8 @@ final class InstallPackageHelper {
|
||||
// Set the update and install times
|
||||
PackageStateInternal deletedPkgSetting = mPm.snapshotComputer()
|
||||
.getPackageStateInternal(oldPackage.getPackageName());
|
||||
// TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided
|
||||
// by apexd to be more accurate.
|
||||
reconciledPkg.mPkgSetting
|
||||
.setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers)
|
||||
.setLastUpdateTime(System.currentTimeMillis());
|
||||
@@ -2239,6 +2266,8 @@ final class InstallPackageHelper {
|
||||
for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
|
||||
final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags
|
||||
& SCAN_AS_INSTANT_APP) != 0);
|
||||
final boolean isApex = ((reconciledPkg.mScanResult.mRequest.mScanFlags
|
||||
& SCAN_AS_APEX) != 0);
|
||||
final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg();
|
||||
final String packageName = pkg.getPackageName();
|
||||
final String codePath = pkg.getPath();
|
||||
@@ -2326,7 +2355,8 @@ final class InstallPackageHelper {
|
||||
android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
|
||||
&& !pkg.isDebuggable()
|
||||
&& (!onIncremental)
|
||||
&& dexoptOptions.isCompilationEnabled();
|
||||
&& dexoptOptions.isCompilationEnabled()
|
||||
&& !isApex;
|
||||
|
||||
if (performDexopt) {
|
||||
// Compile the layout resources.
|
||||
@@ -3295,6 +3325,10 @@ final class InstallPackageHelper {
|
||||
final PackageSetting disabledPs =
|
||||
mPm.mSettings.getDisabledSystemPkgLPr(packageName);
|
||||
if (scannedPkg != null) {
|
||||
if (scannedPkg.isApex()) {
|
||||
// APEX on /data has been scanned. No need to expect better.
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If the system app is both scanned and in the
|
||||
* disabled packages list, then it must have been
|
||||
@@ -3394,6 +3428,18 @@ final class InstallPackageHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans APEX packages and registers them with the system.
|
||||
*
|
||||
* apexd has its own policy to decide which APEX to activate and which not. The policy might
|
||||
* conflicts that of PMS. The APEX package info stored in PMS is a mirror of that managed by
|
||||
* apexd. To keep things simple and keep activation status in sync for both apexd and PMS, we
|
||||
* don't persist APEX in settings and always scan APEX from scratch during boot. However, some
|
||||
* data like lastUpdateTime will be lost if PackageSetting is not persisted for APEX.
|
||||
*
|
||||
* TODO(b/225756739): Read lastUpdateTime from ApexInfoList to populate PackageSetting correctly
|
||||
*/
|
||||
@GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
|
||||
public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags,
|
||||
int scanFlags, PackageParser2 packageParser, ExecutorService executorService) {
|
||||
if (allPackages == null) {
|
||||
@@ -3411,18 +3457,39 @@ final class InstallPackageHelper {
|
||||
parsingApexInfo.put(apexFile, ai);
|
||||
}
|
||||
|
||||
// Process results one by one
|
||||
List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size());
|
||||
List<ParallelPackageParser.ParseResult> parseResults =
|
||||
new ArrayList<>(parsingApexInfo.size());
|
||||
for (int i = 0; i < parsingApexInfo.size(); i++) {
|
||||
ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
|
||||
parseResults.add(parseResult);
|
||||
}
|
||||
// Sort the list to ensure we always process factory packages first
|
||||
Collections.sort(parseResults, (a, b) -> {
|
||||
ApexInfo ai = parsingApexInfo.get(a.scanFile);
|
||||
return ai.isFactory ? -1 : 1;
|
||||
});
|
||||
|
||||
|
||||
// Process results one by one
|
||||
List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size());
|
||||
for (int i = 0; i < parseResults.size(); i++) {
|
||||
ParallelPackageParser.ParseResult parseResult = parseResults.get(i);
|
||||
Throwable throwable = parseResult.throwable;
|
||||
ApexInfo ai = parsingApexInfo.get(parseResult.scanFile);
|
||||
int newParseFlags = parseFlags;
|
||||
int newScanFlags = scanFlags | SCAN_AS_APEX;
|
||||
if (!ai.isFactory) {
|
||||
newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
|
||||
newScanFlags |= SCAN_NEW_INSTALL;
|
||||
}
|
||||
|
||||
if (throwable == null) {
|
||||
try {
|
||||
scanSystemPackageLI(parseResult.parsedPackage, parseFlags, newScanFlags, null);
|
||||
AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal();
|
||||
AndroidPackage pkg = addForInitLI(
|
||||
parseResult.parsedPackage, newParseFlags, newScanFlags, null);
|
||||
if (ai.isFactory && !ai.isActive) {
|
||||
disableSystemPackageLPw(pkg);
|
||||
}
|
||||
results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName()));
|
||||
} catch (PackageManagerException e) {
|
||||
throw new IllegalStateException("Failed to scan: " + ai.modulePath, e);
|
||||
@@ -3641,7 +3708,11 @@ final class InstallPackageHelper {
|
||||
ReconcilePackageUtils.reconcilePackages(reconcileRequest,
|
||||
mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
|
||||
mPm.mSettings);
|
||||
appIdCreated = optimisticallyRegisterAppId(scanResult);
|
||||
if ((scanFlags & SCAN_AS_APEX) == 0) {
|
||||
appIdCreated = optimisticallyRegisterAppId(scanResult);
|
||||
} else {
|
||||
scanResult.mPkgSetting.setAppId(Process.INVALID_UID);
|
||||
}
|
||||
commitReconciledScanResultLocked(reconcileResult.get(pkgName),
|
||||
mPm.mUserManager.getUserIds());
|
||||
} catch (PackageManagerException e) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.pm;
|
||||
|
||||
import static com.android.server.pm.PackageManagerService.TAG;
|
||||
|
||||
import android.apex.ApexInfo;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -45,6 +46,9 @@ final class PackageInstalledInfo {
|
||||
String mOrigPackage;
|
||||
String mOrigPermission;
|
||||
|
||||
// The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
|
||||
ApexInfo mApexInfo;
|
||||
|
||||
PackageInstalledInfo(int currentStatus) {
|
||||
mReturnCode = currentStatus;
|
||||
mUid = -1;
|
||||
|
||||
@@ -2468,10 +2468,18 @@ public final class Settings implements Watchable, Snappable {
|
||||
serializer.endTag(null, "permissions");
|
||||
|
||||
for (final PackageSetting pkg : mPackages.values()) {
|
||||
if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
|
||||
// Don't persist APEX which doesn't have a valid app id and will fail to load
|
||||
continue;
|
||||
}
|
||||
writePackageLPr(serializer, pkg);
|
||||
}
|
||||
|
||||
for (final PackageSetting pkg : mDisabledSysPackages.values()) {
|
||||
if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
|
||||
// Don't persist APEX which doesn't have a valid app id and will fail to load
|
||||
continue;
|
||||
}
|
||||
writeDisabledSysPackageLPr(serializer, pkg);
|
||||
}
|
||||
|
||||
@@ -2691,6 +2699,11 @@ public final class Settings implements Watchable, Snappable {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (pkg.getPkg().isApex()) {
|
||||
// Don't persist APEX which doesn't have a valid app id and will cause parsing
|
||||
// error in libpackagelistparser
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean isDebug = pkg.getPkg().isDebuggable();
|
||||
final IntArray gids = new IntArray();
|
||||
@@ -4968,6 +4981,10 @@ public final class Settings implements Watchable, Snappable {
|
||||
&& !packageName.equals(ps.getPackageName())) {
|
||||
continue;
|
||||
}
|
||||
if (ps.getPkg() != null && ps.getPkg().isApex()) {
|
||||
// Filter APEX packages which will be dumped in the APEX section
|
||||
continue;
|
||||
}
|
||||
final LegacyPermissionState permissionsState =
|
||||
mPermissionDataProvider.getLegacyPermissionState(ps.getAppId());
|
||||
if (permissionNames != null
|
||||
@@ -5020,6 +5037,10 @@ public final class Settings implements Watchable, Snappable {
|
||||
&& !packageName.equals(ps.getPackageName())) {
|
||||
continue;
|
||||
}
|
||||
if (ps.getPkg() != null && ps.getPkg().isApex()) {
|
||||
// Filter APEX packages which will be dumped in the APEX section
|
||||
continue;
|
||||
}
|
||||
if (!checkin && !printedSomething) {
|
||||
if (dumpState.onTitlePrinted())
|
||||
pw.println();
|
||||
|
||||
Reference in New Issue
Block a user