Set system packages as stopped

Apps preloaded on the system partition will be scanned with
an initial state of "stopped=true".

Packages can be added to an allowlist to skip setting them initially as
stopped.

Bug: 249514169
Test: atest PackageManagerServiceServerTests:PackageManagerSettingsTest CtsContentTestCases:SystemPackageDefaultStoppedStateTest

Change-Id: I4d89dab65c01a21c4a74e61a1bfe35141b2fe954
This commit is contained in:
Sumedh Sen
2023-01-24 10:49:58 -08:00
parent 61542bed24
commit f9a03e8104
6 changed files with 88 additions and 4 deletions

View File

@@ -70,6 +70,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_STOPPED_SYSTEM_APP;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR;
@@ -4215,6 +4216,18 @@ final class InstallPackageHelper {
}
}
// A new application appeared on /system, and we are seeing it for the first time.
// Its also not updated as we don't have a copy of it on /data. So, scan it in a
// STOPPED state. Ignore if it's an APEX package since stopped state does not affect them.
final boolean isApexPkg = (scanFlags & SCAN_AS_APEX) != 0;
if (mPm.mShouldStopSystemPackagesByDefault && scanSystemPartition
&& !pkgAlreadyExists && !isApexPkg) {
String packageName = parsedPackage.getPackageName();
if (!mPm.mInitialNonStoppedSystemPackages.contains(packageName)) {
scanFlags |= SCAN_AS_STOPPED_SYSTEM_APP;
}
}
final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags,
scanFlags | SCAN_UPDATE_SIGNATURE, 0 /* currentTime */, user, null);
return new Pair<>(scanResult, shouldHideSystemApp);

View File

@@ -386,6 +386,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
static final int SCAN_DROP_CACHE = 1 << 24;
static final int SCAN_AS_FACTORY = 1 << 25;
static final int SCAN_AS_APEX = 1 << 26;
static final int SCAN_AS_STOPPED_SYSTEM_APP = 1 << 27;
@IntDef(flag = true, prefix = { "SCAN_" }, value = {
SCAN_NO_DEX,
@@ -402,6 +403,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
SCAN_AS_INSTANT_APP,
SCAN_AS_FULL_APP,
SCAN_AS_VIRTUAL_PRELOAD,
SCAN_AS_STOPPED_SYSTEM_APP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ScanFlags {}
@@ -963,6 +965,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final @Nullable String mRecentsPackage;
final @Nullable String mAmbientContextDetectionPackage;
final @Nullable String mWearableSensingPackage;
final @NonNull Set<String> mInitialNonStoppedSystemPackages;
final boolean mShouldStopSystemPackagesByDefault;
private final @NonNull String mRequiredSdkSandboxPackage;
@GuardedBy("mLock")
@@ -1770,6 +1774,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
mResolveComponentName = testParams.resolveComponentName;
mRequiredSdkSandboxPackage = testParams.requiredSdkSandboxPackage;
mInitialNonStoppedSystemPackages = testParams.initialNonStoppedSystemPackages;
mShouldStopSystemPackagesByDefault = testParams.shouldStopSystemPackagesByDefault;
mLiveComputer = createLiveComputer();
mSnapshotStatistics = null;
@@ -2096,6 +2102,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mCacheDir = PackageManagerServiceUtils.preparePackageParserCache(
mIsEngBuild, mIsUserDebugBuild, mIncrementalVersion);
mInitialNonStoppedSystemPackages = mInjector.getSystemConfig()
.getInitialNonStoppedSystemPackages();
mShouldStopSystemPackagesByDefault = mContext.getResources()
.getBoolean(R.bool.config_stopSystemPackagesByDefault);
final int[] userIds = mUserManager.getUserIds();
PackageParser2 packageParser = mInjector.getScanningCachingPackageParser();
mOverlayConfig = mInitAppsHelper.initSystemApps(packageParser, packageSettings, userIds,

View File

@@ -26,6 +26,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.incremental.IncrementalManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import com.android.internal.annotations.VisibleForTesting;
@@ -40,6 +41,7 @@ import com.android.server.pm.pkg.AndroidPackage;
import java.io.File;
import java.util.List;
import java.util.Set;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public final class PackageManagerServiceTestParams {
@@ -119,4 +121,6 @@ public final class PackageManagerServiceTestParams {
public SuspendPackageHelper suspendPackageHelper;
public DistractingPackageHelper distractingPackageHelper;
public StorageEventHelper storageEventHelper;
public Set<String> initialNonStoppedSystemPackages = new ArraySet<>();
public boolean shouldStopSystemPackagesByDefault;
}

View File

@@ -31,6 +31,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_STOPPED_SYSTEM_APP;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR;
@@ -198,6 +199,7 @@ final class ScanPackageUtils {
if (createNewPackage) {
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
final boolean isStoppedSystemApp = (scanFlags & SCAN_AS_STOPPED_SYSTEM_APP) != 0;
// Flags contain system values stored in the server variant of AndroidPackage,
// and so the server-side PackageInfoUtils is still called, even without a
@@ -212,7 +214,7 @@ final class ScanPackageUtils {
AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user,
true /*allowInstall*/, instantApp, virtualPreload,
true /*allowInstall*/, instantApp, virtualPreload, isStoppedSystemApp,
UserManagerService.getInstance(), usesSdkLibraries,
parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries,
parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),

View File

@@ -1041,7 +1041,7 @@ public final class Settings implements Watchable, Snappable {
File codePath, String legacyNativeLibraryPath, String primaryCpuAbi,
String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags,
UserHandle installUser, boolean allowInstall, boolean instantApp,
boolean virtualPreload, UserManagerService userManager,
boolean virtualPreload, boolean isStoppedSystemApp, UserManagerService userManager,
String[] usesSdkLibraries, long[] usesSdkLibrariesVersions,
String[] usesStaticLibraries, long[] usesStaticLibrariesVersions,
Set<String> mimeGroupNames, @NonNull UUID domainSetId) {
@@ -1068,6 +1068,9 @@ public final class Settings implements Watchable, Snappable {
pkgSetting.setFlags(pkgFlags)
.setPrivateFlags(pkgPrivateFlags);
} else {
int installUserId = installUser != null ? installUser.getIdentifier()
: UserHandle.USER_SYSTEM;
pkgSetting = new PackageSetting(pkgName, realPkgName, codePath,
legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags,
@@ -1086,8 +1089,6 @@ public final class Settings implements Watchable, Snappable {
Slog.i(PackageManagerService.TAG, "Stopping package " + pkgName, e);
}
List<UserInfo> users = getAllUsers(userManager);
int installUserId = installUser != null ? installUser.getIdentifier()
: UserHandle.USER_SYSTEM;
if (users != null && allowInstall) {
for (UserInfo user : users) {
// By default we consider this app to be installed
@@ -1126,6 +1127,13 @@ public final class Settings implements Watchable, Snappable {
);
}
}
} else if (isStoppedSystemApp) {
if (DEBUG_STOPPED) {
RuntimeException e = new RuntimeException("here");
e.fillInStackTrace();
Slog.i(PackageManagerService.TAG, "Stopping system package " + pkgName, e);
}
pkgSetting.setStopped(true, installUserId);
}
if (sharedUser != null) {
pkgSetting.setAppId(sharedUser.mAppId);

View File

@@ -1112,6 +1112,7 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
false /* stopped */,
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
@@ -1156,6 +1157,7 @@ public class PackageManagerSettingsTests {
true /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
false /* stopped */,
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
@@ -1200,6 +1202,7 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
false /* stopped */,
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
@@ -1245,6 +1248,7 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
false /* stopped */,
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
@@ -1267,6 +1271,48 @@ public class PackageManagerSettingsTests {
verifyUserState(userState, false /*notLaunched*/, false /*stopped*/, true /*installed*/);
}
/** Create a new stopped system PackageSetting */
@Test
public void testCreateNewSetting05() {
final PackageSetting testPkgSetting01 = Settings.createNewSetting(
PACKAGE_NAME,
null /*originalPkg*/,
null /*disabledPkg*/,
null /*realPkgName*/,
null /*sharedUser*/,
UPDATED_CODE_PATH /*codePath*/,
null /*legacyNativeLibraryPath*/,
"arm64-v8a" /*primaryCpuAbi*/,
"armeabi" /*secondaryCpuAbi*/,
UPDATED_VERSION_CODE /*versionCode*/,
ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
UserHandle.SYSTEM /*installUser*/,
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
true /* stopped */,
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
UUID.randomUUID());
assertThat(testPkgSetting01.getAppId(), is(0));
assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH));
assertThat(testPkgSetting01.getPackageName(), is(PACKAGE_NAME));
assertThat(testPkgSetting01.getFlags(), is(ApplicationInfo.FLAG_SYSTEM));
assertThat(testPkgSetting01.getPrivateFlags(), is(0));
assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("arm64-v8a"));
assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("armeabi"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("armeabi"));
assertThat(testPkgSetting01.getVersionCode(), is(UPDATED_VERSION_CODE));
final PackageUserState userState = testPkgSetting01.readUserState(0);
verifyUserState(userState, false /*notLaunched*/, true /*stopped*/, true /*installed*/);
}
@Test
public void testSetPkgStateLibraryFiles_addNewFiles() {
final PackageSetting packageSetting = createPackageSetting("com.foo");