Merge changes from topic "stopped-sys-apps"
* changes: Set system packages as stopped on user creation Set system packages as stopped Allowlist for exempting packages from being marked as stopped by default Feature flag for toggling stop system packages default behavior
This commit is contained in:
@@ -6230,4 +6230,27 @@
|
||||
trusted certificate using the SHA-256 digest algorithm. -->
|
||||
<string-array name="config_healthConnectMigrationKnownSigners">
|
||||
</string-array>
|
||||
|
||||
<!-- The Universal Stylus Initiative (USI) protocol version supported by each display.
|
||||
(@see https://universalstylus.org/).
|
||||
|
||||
The i-th value in this array corresponds to the supported USI version of the i-th display
|
||||
listed in config_displayUniqueIdArray. On a single-display device, the
|
||||
config_displayUniqueIdArray may be empty, in which case the only value in this array should
|
||||
be the USI version for the main built-in display.
|
||||
|
||||
If the display does not support USI, the version value should be an empty string. If the
|
||||
display supports USI, the version must be in the following format:
|
||||
"<major-version>.<minor-version>"
|
||||
|
||||
For example, "", "1.0", and "2.0" are valid values. -->
|
||||
<string-array name="config_displayUsiVersionArray" translatable="false">
|
||||
<item>""</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Whether system apps should be scanned in the stopped state during initial boot.
|
||||
Packages can be added by OEMs in an allowlist, to prevent them from being scanned as
|
||||
"stopped" during initial boot of a device, or after an OTA update. Stopped state of
|
||||
an app is not changed during subsequent reboots. -->
|
||||
<bool name="config_stopSystemPackagesByDefault">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -4909,4 +4909,6 @@
|
||||
<java-symbol type="string" name="config_mainDisplayShape"/>
|
||||
<java-symbol type="string" name="config_secondaryDisplayShape"/>
|
||||
<java-symbol type="array" name="config_displayShapeArray" />
|
||||
|
||||
<java-symbol type="bool" name="config_stopSystemPackagesByDefault"/>
|
||||
</resources>
|
||||
|
||||
@@ -35,6 +35,12 @@ prebuilt_etc {
|
||||
src: "preinstalled-packages-platform.xml",
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "initial-package-stopped-states.xml",
|
||||
sub_dir: "sysconfig",
|
||||
src: "initial-package-stopped-states.xml",
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "preinstalled-packages-platform-overlays.xml",
|
||||
product_specific: true,
|
||||
|
||||
38
data/etc/initial-package-stopped-states.xml
Normal file
38
data/etc/initial-package-stopped-states.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This XML defines an allowlist for packages that should not be scanned in a "stopped" state.
|
||||
When this feature is turned on (indicated by the config config_stopSystemPackagesByDefault in
|
||||
core/res/res/values/config.xml) packages on the system partition that are encountered by
|
||||
the PackageManagerService for the first time are scanned in the "stopped" state. This allowlist
|
||||
is also considered while creating new users on the device. Stopped state is not set during
|
||||
subsequent reboots.
|
||||
|
||||
Example usage
|
||||
1. <initial-package-state package="com.example.app" stopped="false"/>
|
||||
Indicates that a system package - com.example.app's initial stopped state should not be set
|
||||
by the Package Manager. By default, system apps are marked as stopped.
|
||||
2. <initial-package-state package="com.example.app" stopped="true"/>
|
||||
Indicates that a system package - com.example.app's initial state should be set by the
|
||||
Package Manager to "stopped=true". It will have the same effect on the
|
||||
package's stopped state even if this package was not included in the allow list.
|
||||
3. <initial-package-state package="com.example.app"/>
|
||||
Invalid usage.
|
||||
-->
|
||||
|
||||
<config></config>
|
||||
@@ -333,6 +333,11 @@ public class SystemConfig {
|
||||
// Update ownership for system applications and the installers eligible to update them.
|
||||
private final ArrayMap<String, String> mUpdateOwnersForSystemApps = new ArrayMap<>();
|
||||
|
||||
// Set of package names that should not be marked as "stopped" during initial device boot
|
||||
// or when adding a new user. A new package not contained in this set will be
|
||||
// marked as stopped by the system
|
||||
@NonNull private final Set<String> mInitialNonStoppedSystemPackages = new ArraySet<>();
|
||||
|
||||
/**
|
||||
* Map of system pre-defined, uniquely named actors; keys are namespace,
|
||||
* value maps actor name to package name.
|
||||
@@ -527,6 +532,10 @@ public class SystemConfig {
|
||||
? null : mOverlayConfigSignaturePackage;
|
||||
}
|
||||
|
||||
public Set<String> getInitialNonStoppedSystemPackages() {
|
||||
return mInitialNonStoppedSystemPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use for testing. Do NOT use in production code.
|
||||
* @param readPermissions false to create an empty SystemConfig; true to read the permissions.
|
||||
@@ -1445,6 +1454,19 @@ public class SystemConfig {
|
||||
}
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
} break;
|
||||
case "initial-package-state": {
|
||||
String pkgName = parser.getAttributeValue(null, "package");
|
||||
String stopped = parser.getAttributeValue(null, "stopped");
|
||||
if (TextUtils.isEmpty(pkgName)) {
|
||||
Slog.w(TAG, "<" + name + "> without package in " + permFile
|
||||
+ " at " + parser.getPositionDescription());
|
||||
} else if (TextUtils.isEmpty(stopped)) {
|
||||
Slog.w(TAG, "<" + name + "> without stopped in " + permFile
|
||||
+ " at " + parser.getPositionDescription());
|
||||
} else if (!Boolean.parseBoolean(stopped)) {
|
||||
mInitialNonStoppedSystemPackages.add(pkgName);
|
||||
}
|
||||
}
|
||||
default: {
|
||||
Slog.w(TAG, "Tag " + name + " is unknown in "
|
||||
+ permFile + " at " + parser.getPositionDescription());
|
||||
|
||||
@@ -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;
|
||||
@@ -4237,6 +4238,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);
|
||||
|
||||
@@ -387,6 +387,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,
|
||||
@@ -403,6 +404,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 {}
|
||||
@@ -964,6 +966,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")
|
||||
@@ -1771,6 +1775,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;
|
||||
@@ -2097,6 +2103,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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
@@ -4422,6 +4430,15 @@ public final class Settings implements Watchable, Snappable {
|
||||
ps.getPackageName()));
|
||||
// Only system apps are initially installed.
|
||||
ps.setInstalled(shouldReallyInstall, userHandle);
|
||||
|
||||
// Non-Apex system apps, that are not included in the allowlist in
|
||||
// initialNonStoppedSystemPackages, should be marked as stopped by default.
|
||||
final boolean shouldBeStopped = service.mShouldStopSystemPackagesByDefault
|
||||
&& ps.isSystem()
|
||||
&& !ps.isApex()
|
||||
&& !service.mInitialNonStoppedSystemPackages.contains(ps.getPackageName());
|
||||
ps.setStopped(shouldBeStopped, userHandle);
|
||||
|
||||
// If userTypeInstallablePackages is the *only* reason why we're not installing,
|
||||
// then uninstallReason is USER_TYPE. If there's a different reason, or if we
|
||||
// actually are installing, put UNKNOWN.
|
||||
|
||||
@@ -1129,6 +1129,7 @@ public class PackageManagerSettingsTests {
|
||||
false /*allowInstall*/,
|
||||
false /*instantApp*/,
|
||||
false /*virtualPreload*/,
|
||||
false /* stopped */,
|
||||
UserManagerService.getInstance(),
|
||||
null /*usesSdkLibraries*/,
|
||||
null /*usesSdkLibrariesVersions*/,
|
||||
@@ -1173,6 +1174,7 @@ public class PackageManagerSettingsTests {
|
||||
true /*allowInstall*/,
|
||||
false /*instantApp*/,
|
||||
false /*virtualPreload*/,
|
||||
false /* stopped */,
|
||||
UserManagerService.getInstance(),
|
||||
null /*usesSdkLibraries*/,
|
||||
null /*usesSdkLibrariesVersions*/,
|
||||
@@ -1217,6 +1219,7 @@ public class PackageManagerSettingsTests {
|
||||
false /*allowInstall*/,
|
||||
false /*instantApp*/,
|
||||
false /*virtualPreload*/,
|
||||
false /* stopped */,
|
||||
UserManagerService.getInstance(),
|
||||
null /*usesSdkLibraries*/,
|
||||
null /*usesSdkLibrariesVersions*/,
|
||||
@@ -1262,6 +1265,7 @@ public class PackageManagerSettingsTests {
|
||||
false /*allowInstall*/,
|
||||
false /*instantApp*/,
|
||||
false /*virtualPreload*/,
|
||||
false /* stopped */,
|
||||
UserManagerService.getInstance(),
|
||||
null /*usesSdkLibraries*/,
|
||||
null /*usesSdkLibrariesVersions*/,
|
||||
@@ -1284,6 +1288,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");
|
||||
|
||||
Reference in New Issue
Block a user