Merge "Parse maxSdkVersion for APK in apexes" into tm-dev

This commit is contained in:
Pedro Loureiro
2022-03-10 14:41:31 +00:00
committed by Android (Google) Code Review
7 changed files with 76 additions and 3 deletions

View File

@@ -378,6 +378,30 @@ public class FrameworkParsingPackageUtils {
}
}
/**
* Computes the maxSdkVersion. If the package is not compatible with this platform, populates
* {@code outError[0]} with an error message.
* <p>
* {@code maxVers} is compared against {@code platformSdkVersion}. If {@code maxVers} is less
* than the {@code platformSdkVersion} then populates {@code outError[0]} with an error message.
* Otherwise, it returns {@code maxVers} unmodified.
*
* @param maxVers maxSdkVersion number, if specified in the application manifest, or {@code
* Integer.MAX_VALUE} otherwise
* @param platformSdkVersion platform SDK version number, typically Build.VERSION.SDK_INT
* @return the maxSdkVersion that was recognised or an error if the condition is not satisfied
*/
public static ParseResult<Integer> computeMaxSdkVersion(@IntRange(from = 0) int maxVers,
@IntRange(from = 1) int platformSdkVersion, @NonNull ParseInput input) {
if (platformSdkVersion > maxVers) {
return input.error(PackageManager.INSTALL_FAILED_NEWER_SDK,
"Requires max SDK version " + maxVers + " but is "
+ platformSdkVersion);
} else {
return input.success(maxVers);
}
}
/**
* Matches a given {@code targetCode} against a set of release codeNames. Target codes can
* either be of the form {@code [codename]}" (e.g {@code "Q"}) or of the form {@code

View File

@@ -30,6 +30,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX;
import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;
import android.annotation.Nullable;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -313,10 +314,14 @@ final class InitAndSystemPackageHelper {
@GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
final int parseFlags, int scanFlags,
int parseFlags, int scanFlags,
long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
try {
if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
// when scanning apk in apexes, we want to check the maxSdkVersion
parseFlags |= PARSE_CHECK_MAX_SDK_VERSION;
}
mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
scanFlags, currentTime, packageParser, executorService);
} finally {

View File

@@ -302,6 +302,8 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage setMinSdkVersion(int minSdkVersion);
ParsingPackage setMaxSdkVersion(int maxSdkVersion);
ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes);
ParsingPackage setNonLocalizedLabel(CharSequence nonLocalizedLabel);

View File

@@ -383,6 +383,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
@Nullable
private SparseIntArray minExtensionVersions;
private int minSdkVersion = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
private int maxSdkVersion = ParsingUtils.DEFAULT_MAX_SDK_VERSION;
private int networkSecurityConfigRes;
@Nullable
private CharSequence nonLocalizedLabel;
@@ -1306,6 +1307,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
dest.writeFloat(this.maxAspectRatio);
dest.writeFloat(this.minAspectRatio);
dest.writeInt(this.minSdkVersion);
dest.writeInt(this.maxSdkVersion);
dest.writeInt(this.networkSecurityConfigRes);
dest.writeCharSequence(this.nonLocalizedLabel);
dest.writeString(this.permission);
@@ -1454,6 +1456,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
this.maxAspectRatio = in.readFloat();
this.minAspectRatio = in.readFloat();
this.minSdkVersion = in.readInt();
this.maxSdkVersion = in.readInt();
this.networkSecurityConfigRes = in.readInt();
this.nonLocalizedLabel = in.readCharSequence();
this.permission = in.readString();
@@ -2067,6 +2070,11 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
return minSdkVersion;
}
@Override
public int getMaxSdkVersion() {
return maxSdkVersion;
}
@Override
public int getNetworkSecurityConfigRes() {
return networkSecurityConfigRes;
@@ -2591,6 +2599,12 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden,
return this;
}
@Override
public ParsingPackageImpl setMaxSdkVersion(int value) {
maxSdkVersion = value;
return this;
}
@Override
public ParsingPackageImpl setNetworkSecurityConfigRes(int value) {
networkSecurityConfigRes = value;

View File

@@ -209,6 +209,8 @@ public class ParsingPackageUtils {
public static final int SDK_VERSION = Build.VERSION.SDK_INT;
public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
public static final String[] PREVIOUS_CODENAMES =
Build.VERSION.KNOWN_CODENAMES.toArray(new String[]{});
public static boolean sCompatibilityModeEnabled = true;
public static boolean sUseRoundIcon = false;
@@ -236,6 +238,7 @@ public class ParsingPackageUtils {
*/
public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
public static final int PARSE_FRAMEWORK_RES_SPLITS = 1 << 8;
public static final int PARSE_CHECK_MAX_SDK_VERSION = 1 << 9;
public static final int PARSE_CHATTY = 1 << 31;
@@ -1002,7 +1005,7 @@ public class ParsingPackageUtils {
case TAG_FEATURE_GROUP:
return parseFeatureGroup(input, pkg, res, parser);
case TAG_USES_SDK:
return parseUsesSdk(input, pkg, res, parser);
return parseUsesSdk(input, pkg, res, parser, flags);
case TAG_SUPPORT_SCREENS:
return parseSupportScreens(input, pkg, res, parser);
case TAG_PROTECTED_BROADCAST:
@@ -1514,15 +1517,17 @@ public class ParsingPackageUtils {
}
private static ParseResult<ParsingPackage> parseUsesSdk(ParseInput input,
ParsingPackage pkg, Resources res, XmlResourceParser parser)
ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
throws IOException, XmlPullParserException {
if (SDK_VERSION > 0) {
final boolean checkMaxSdkVersion = (flags & PARSE_CHECK_MAX_SDK_VERSION) != 0;
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
try {
int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
String minCode = null;
int targetVers = ParsingUtils.DEFAULT_TARGET_SDK_VERSION;
String targetCode = null;
int maxVers = Integer.MAX_VALUE;
TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) {
@@ -1550,6 +1555,14 @@ public class ParsingPackageUtils {
targetCode = minCode;
}
if (checkMaxSdkVersion) {
val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
if (val != null) {
// maxSdkVersion only supports integer
maxVers = val.data;
}
}
ParseResult<Integer> targetSdkVersionResult = FrameworkParsingPackageUtils
.computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input);
if (targetSdkVersionResult.isError()) {
@@ -1574,6 +1587,15 @@ public class ParsingPackageUtils {
pkg.setMinSdkVersion(minSdkVersion)
.setTargetSdkVersion(targetSdkVersion);
if (checkMaxSdkVersion) {
ParseResult<Integer> maxSdkVersionResult = FrameworkParsingPackageUtils
.computeMaxSdkVersion(maxVers, SDK_VERSION, input);
if (maxSdkVersionResult.isError()) {
return input.error(maxSdkVersionResult);
}
int maxSdkVersion = maxSdkVersionResult.getResult();
pkg.setMaxSdkVersion(maxSdkVersion);
}
int type;
final int innerDepth = parser.getDepth();

View File

@@ -50,6 +50,7 @@ public class ParsingUtils {
public static final String ANDROID_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
public static final int DEFAULT_MIN_SDK_VERSION = 1;
public static final int DEFAULT_MAX_SDK_VERSION = Integer.MAX_VALUE;
public static final int DEFAULT_TARGET_SDK_VERSION = 0;
public static final int NOT_SET = -1;

View File

@@ -249,6 +249,11 @@ public interface PkgWithoutStateAppInfo {
*/
int getMinSdkVersion();
/**
* @see R.styleable#AndroidManifestUsesSdk_maxSdkVersion
*/
int getMaxSdkVersion();
/**
* @see ApplicationInfo#getNativeHeapZeroInitialized()
* @see R.styleable#AndroidManifestApplication_nativeHeapZeroInitialized