Flip default of extractNativeLibs if targets Q+

Test: Local in-progress CTS
Test: CtsDynamicLinkerTestCases
Bug: 112037137
Change-Id: I41289ec6bdfff13ef4aa551bf0a98bad73c9371e
This commit is contained in:
Victor Hsieh
2018-10-12 15:38:18 -07:00
parent a4ee276629
commit 4e54b521bc

View File

@@ -1621,7 +1621,7 @@ public class PackageParser {
}
final AttributeSet attrs = parser;
return parseApkLite(apkPath, parser, attrs, signingDetails);
return parseApkLite(apkPath, parser, attrs, signingDetails, flags);
} catch (XmlPullParserException | IOException | RuntimeException e) {
Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1708,7 +1708,7 @@ public class PackageParser {
}
private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
SigningDetails signingDetails)
SigningDetails signingDetails, int flags)
throws IOException, XmlPullParserException, PackageParserException {
final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
@@ -1716,11 +1716,12 @@ public class PackageParser {
int versionCode = 0;
int versionCodeMajor = 0;
int revisionCode = 0;
int targetSdkVersion = 0;
boolean coreApp = false;
boolean debuggable = false;
boolean multiArch = false;
boolean use32bitAbi = false;
boolean extractNativeLibs = true;
Boolean extractNativeLibsProvided = null;
boolean isolatedSplits = false;
boolean isFeatureSplit = false;
boolean isSplitRequired = false;
@@ -1785,7 +1786,8 @@ public class PackageParser {
use32bitAbi = attrs.getAttributeBooleanValue(i, false);
}
if ("extractNativeLibs".equals(attr)) {
extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
extractNativeLibsProvided = Boolean.valueOf(
attrs.getAttributeBooleanValue(i, true));
}
if ("preferCodeIntegrity".equals(attr)) {
preferCodeIntegrity = attrs.getAttributeBooleanValue(i, false);
@@ -1803,9 +1805,51 @@ public class PackageParser {
PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
"<uses-split> tag requires 'android:name' attribute");
}
} else if (TAG_USES_SDK.equals(parser.getName())) {
final String[] errorMsg = new String[1];
Pair<Integer, Integer> versions = deriveSdkVersions(new AbstractVersionsAccessor() {
@Override public String getMinSdkVersionCode() {
return getAttributeAsString("minSdkVersion");
}
@Override public int getMinSdkVersion() {
return getAttributeAsInt("minSdkVersion");
}
@Override public String getTargetSdkVersionCode() {
return getAttributeAsString("targetSdkVersion");
}
@Override public int getTargetSdkVersion() {
return getAttributeAsInt("targetSdkVersion");
}
private String getAttributeAsString(String name) {
return attrs.getAttributeValue(ANDROID_RESOURCES, name);
}
private int getAttributeAsInt(String name) {
try {
return attrs.getAttributeIntValue(ANDROID_RESOURCES, name, -1);
} catch (NumberFormatException e) {
return -1;
}
}
}, flags, errorMsg);
if (versions == null) {
throw new PackageParserException(
PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, errorMsg[0]);
}
targetSdkVersion = versions.second;
}
}
final boolean extractNativeLibsDefault = targetSdkVersion < Build.VERSION_CODES.Q;
final boolean extractNativeLibs = (extractNativeLibsProvided != null)
? extractNativeLibsProvided : extractNativeLibsDefault;
if (preferCodeIntegrity && extractNativeLibs) {
throw new PackageParserException(
PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
@@ -2215,65 +2259,60 @@ public class PackageParser {
} else if (tagName.equals(TAG_USES_SDK)) {
if (SDK_VERSION > 0) {
sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestUsesSdk);
sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
final TypedArray saFinal = sa;
Pair<Integer, Integer> versions = deriveSdkVersions(
new AbstractVersionsAccessor() {
@Override public String getMinSdkVersionCode() {
return getAttributeAsString(
R.styleable.AndroidManifestUsesSdk_minSdkVersion);
}
int minVers = 1;
String minCode = null;
int targetVers = 0;
String targetCode = null;
@Override public int getMinSdkVersion() {
return getAttributeAsInt(
R.styleable.AndroidManifestUsesSdk_minSdkVersion);
}
TypedValue val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) {
if (val.type == TypedValue.TYPE_STRING && val.string != null) {
minCode = val.string.toString();
} else {
// If it's not a string, it's an integer.
minVers = val.data;
}
@Override public String getTargetSdkVersionCode() {
return getAttributeAsString(
R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
}
@Override public int getTargetSdkVersion() {
return getAttributeAsInt(
R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
}
private String getAttributeAsString(int index) {
TypedValue val = saFinal.peekValue(index);
if (val != null && val.type == TypedValue.TYPE_STRING
&& val.string != null) {
return val.string.toString();
}
return null;
}
private int getAttributeAsInt(int index) {
TypedValue val = saFinal.peekValue(index);
if (val != null && val.type != TypedValue.TYPE_STRING) {
// If it's not a string, it's an integer.
return val.data;
}
return -1;
}
}, flags, outError);
if (versions == null) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
if (val != null) {
if (val.type == TypedValue.TYPE_STRING && val.string != null) {
targetCode = val.string.toString();
if (minCode == null) {
minCode = targetCode;
}
} else {
// If it's not a string, it's an integer.
targetVers = val.data;
}
} else {
targetVers = minVers;
targetCode = minCode;
}
pkg.applicationInfo.minSdkVersion = versions.first;
pkg.applicationInfo.targetSdkVersion = versions.second;
sa.recycle();
final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers, minCode,
SDK_VERSION, SDK_CODENAMES, outError);
if (minSdkVersion < 0) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
boolean defaultToCurrentDevBranch = (flags & PARSE_FORCE_SDK) != 0;
final int targetSdkVersion = PackageParser.computeTargetSdkVersion(targetVers,
targetCode, SDK_CODENAMES, outError, defaultToCurrentDevBranch);
if (targetSdkVersion < 0) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
pkg.applicationInfo.minSdkVersion = minSdkVersion;
pkg.applicationInfo.targetSdkVersion = targetSdkVersion;
}
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals(TAG_SUPPORT_SCREENS)) {
sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestSupportsScreens);
@@ -2675,6 +2714,67 @@ public class PackageParser {
return -1;
}
private interface AbstractVersionsAccessor {
/** Returns minimum SDK version code string, or null if absent. */
String getMinSdkVersionCode();
/** Returns minimum SDK version code, or -1 if absent. */
int getMinSdkVersion();
/** Returns target SDK version code string, or null if absent. */
String getTargetSdkVersionCode();
/** Returns target SDK version code, or -1 if absent. */
int getTargetSdkVersion();
}
private static @Nullable Pair<Integer, Integer> deriveSdkVersions(
@NonNull AbstractVersionsAccessor accessor, int flags, String[] outError) {
int minVers = 1;
String minCode = null;
int targetVers = 0;
String targetCode = null;
String code = accessor.getMinSdkVersionCode();
int version = accessor.getMinSdkVersion();
// Check integer first since code is almost never a null string (e.g. "28").
if (version >= 0) {
minVers = version;
} else if (code != null) {
minCode = code;
}
code = accessor.getTargetSdkVersionCode();
version = accessor.getTargetSdkVersion();
// Check integer first since code is almost never a null string (e.g. "28").
if (version >= 0) {
targetVers = version;
} else if (code != null) {
targetCode = code;
if (minCode == null) {
minCode = targetCode;
}
} else {
targetVers = minVers;
targetCode = minCode;
}
final int minSdkVersion = computeMinSdkVersion(minVers, minCode,
SDK_VERSION, SDK_CODENAMES, outError);
if (minSdkVersion < 0) {
return null;
}
boolean defaultToCurrentDevBranch = (flags & PARSE_FORCE_SDK) != 0;
final int targetSdkVersion = computeTargetSdkVersion(targetVers,
targetCode, SDK_CODENAMES, outError, defaultToCurrentDevBranch);
if (targetSdkVersion < 0) {
return null;
}
return Pair.create(minSdkVersion, targetSdkVersion);
}
/**
* Computes the minSdkVersion to use at runtime. If the package is not
* compatible with this platform, populates {@code outError[0]} with an