diff options
author | Todd Kennedy <toddke@google.com> | 2016-04-26 15:41:20 -0700 |
---|---|---|
committer | Todd Kennedy <toddke@google.com> | 2016-04-26 16:25:43 -0700 |
commit | b1072718130b998e6d25bc3358eefa62b4fa5a2d (patch) | |
tree | 863749a94ab1ebb6c023bebe932197af2a50a5ca | |
parent | 34510eb2933b98f0c8c73f9a7be5eae911a14210 (diff) |
Don't override pre-release target sdk
If a package targets a pre-release SDK [eg a letter version] it should not
be allowed to be upgraded by a release SDK [eg a number version]. If one
absolutely must upgrade to a release SDK, use the "--force-sdk" option
during install.
Bug: 28345311
Change-Id: Ic9fb209968e7c5da2c80c5ca4c0f44f5125f610a
5 files changed, 39 insertions, 3 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index a45d43204513..19cb927bd582 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -502,6 +502,9 @@ public final class Pm { sessionParams.volumeUuid = null; } break; + case "--force-sdk": + sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; + break; default: throw new IllegalArgumentException("Unknown option " + opt); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b04cbc58b166..a96da09cf67e 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -684,6 +684,14 @@ public abstract class PackageManager { public static final int INSTALL_DONT_KILL_APP = 0x00001000; /** + * Flag parameter for {@link #installPackage} to indicate that this package is an + * upgrade to a package that refers to the SDK via release letter. + * + * @hide + */ + public static final int INSTALL_FORCE_SDK = 0x00002000; + + /** * Flag parameter for * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate * that you don't want to kill the app containing the component. Be careful when you set this diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 54091db79779..8a9978778ab1 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -652,6 +652,7 @@ public class PackageParser { public final static int PARSE_TRUSTED_OVERLAY = 1<<9; public final static int PARSE_ENFORCE_CODE = 1<<10; public final static int PARSE_IS_EPHEMERAL = 1<<11; + public final static int PARSE_FORCE_SDK = 1<<12; private static final Comparator<String> sSplitNameComparator = new SplitNameComparator(); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 38144e476cca..774c7a6de6b1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -13795,9 +13795,24 @@ public class PackageManagerService extends IPackageManager.Stub { final String pkgName = pkg.packageName; final int[] allUsers; - // First find the old package info and check signatures synchronized(mPackages) { oldPackage = mPackages.get(pkgName); + if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); + + // don't allow upgrade to target a release SDK from a pre-release SDK + final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion + == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; + final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion + == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; + if (oldTargetsPreRelease + && !newTargetsPreRelease + && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { + Slog.w(TAG, "Can't install package targeting released sdk"); + res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); + return; + } + + // don't allow an upgrade from full to ephemeral final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); if (isEphemeral && !oldIsEphemeral) { // can't downgrade from full to ephemeral @@ -13805,7 +13820,8 @@ public class PackageManagerService extends IPackageManager.Stub { res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); return; } - if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); + + // verify signatures are valid final PackageSetting ps = mSettings.mPackages.get(pkgName); if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { if (!checkUpgradeKeySetLP(ps, pkg)) { @@ -14411,6 +14427,7 @@ public class PackageManagerService extends IPackageManager.Stub { final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) || (args.volumeUuid != null)); final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); + final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); boolean replace = false; int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; if (args.move != null) { @@ -14439,7 +14456,8 @@ public class PackageManagerService extends IPackageManager.Stub { | PackageParser.PARSE_ENFORCE_CODE | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) - | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); + | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) + | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); pp.setDisplayMetrics(mMetrics); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 8527fd40a858..68a19c3c3bb1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -1000,6 +1000,9 @@ class PackageManagerShellCommand extends ShellCommand { case "-g": sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; break; + case "--dont-kill": + sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP; + break; case "--originating-uri": sessionParams.originatingUri = Uri.parse(getNextArg()); break; @@ -1035,6 +1038,9 @@ class PackageManagerShellCommand extends ShellCommand { sessionParams.volumeUuid = null; } break; + case "--force-sdk": + sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; + break; default: throw new IllegalArgumentException("Unknown option " + opt); } |