diff options
| author | 2016-04-20 16:47:50 -0700 | |
|---|---|---|
| committer | 2016-04-27 14:38:02 -0700 | |
| commit | 8c57aeaa8f27423b843fa043fb86b0b57c906ead (patch) | |
| tree | 6454122ae944299266bd630731e13cc35f0d1715 | |
| parent | c6184685d8f9b08abf73f83778ca129bb5c9c51d (diff) | |
Allow any app to silently uninstall the orphan packages.
Bug: 28302564
Change-Id: If6f2111e35ec94c7eb5b80a08bbf63fd58698c27
4 files changed, 28 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 83681853898c..83af0173c514 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -866,8 +866,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub { if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); final String installerPackageName = mPm.getInstallerPackageName(packageName); - allowSilentUninstall = installerPackageName != null - && installerPackageName.equals(callerPackageName); + allowSilentUninstall = mPm.isOrphaned(packageName) || + (installerPackageName != null + && installerPackageName.equals(callerPackageName)); } // Check whether the caller is device owner, in which case we do it silently. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 43250ba9271d..051ac8dfa16f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17290,6 +17290,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } + public boolean isOrphaned(String packageName) { + // reader + synchronized (mPackages) { + return mSettings.isOrphaned(packageName); + } + } + @Override public int getApplicationEnabledSetting(String packageName, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 9d04472a63a4..851f0859753b 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -125,6 +125,8 @@ abstract class PackageSettingBase extends SettingBase { /** Package name of the app that installed this package */ String installerPackageName; + /** Indicates if the package that installed this app has been uninstalled */ + boolean isOrphaned; /** UUID of {@link VolumeInfo} hosting this app */ String volumeUuid; @@ -182,6 +184,7 @@ abstract class PackageSettingBase extends SettingBase { origPackage = base.origPackage; installerPackageName = base.installerPackageName; + isOrphaned = base.isOrphaned; volumeUuid = base.volumeUuid; keySetData = new PackageKeySetData(base.keySetData); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 7debf9b5b7fb..1abe8f1253dc 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1102,6 +1102,7 @@ final class Settings { if (installerPackageName != null && installerPackageName.equals(packageName)) { ps.setInstallerPackageName(null); + ps.isOrphaned = true; } } mInstallerPackages.remove(packageName); @@ -2632,6 +2633,9 @@ final class Settings { if (pkg.installerPackageName != null) { serializer.attribute(null, "installer", pkg.installerPackageName); } + if (pkg.isOrphaned) { + serializer.attribute(null, "isOrphaned", "true"); + } if (pkg.volumeUuid != null) { serializer.attribute(null, "volumeUuid", pkg.volumeUuid); } @@ -3507,6 +3511,7 @@ final class Settings { String cpuAbiOverrideString = null; String systemStr = null; String installerPackageName = null; + String isOrphaned = null; String volumeUuid = null; String uidError = null; int pkgFlags = 0; @@ -3548,6 +3553,7 @@ final class Settings { } } installerPackageName = parser.getAttributeValue(null, "installer"); + isOrphaned = parser.getAttributeValue(null, "isOrphaned"); volumeUuid = parser.getAttributeValue(null, "volumeUuid"); systemStr = parser.getAttributeValue(null, "publicFlags"); @@ -3698,6 +3704,7 @@ final class Settings { if (packageSetting != null) { packageSetting.uidError = "true".equals(uidError); packageSetting.installerPackageName = installerPackageName; + packageSetting.isOrphaned = "true".equals(isOrphaned); packageSetting.volumeUuid = volumeUuid; packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr; packageSetting.primaryCpuAbiString = primaryCpuAbiString; @@ -4100,6 +4107,14 @@ final class Settings { return pkg.installerPackageName; } + boolean isOrphaned(String packageName) { + final PackageSetting pkg = mPackages.get(packageName); + if (pkg == null) { + throw new IllegalArgumentException("Unknown package: " + packageName); + } + return pkg.isOrphaned; + } + int getApplicationEnabledSettingLPr(String packageName, int userId) { final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { |