Merge "Fail install when resources.arsc is compressed" into rvc-dev

This commit is contained in:
Ryan Mitchell
2020-04-13 14:57:19 +00:00
committed by Android (Google) Code Review
8 changed files with 74 additions and 7 deletions

View File

@@ -1550,6 +1550,16 @@ public abstract class PackageManager {
*/
public static final int INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED = -123;
/**
* Installation failed return code: the {@code resources.arsc} of one of the APKs being
* installed is compressed or not aligned on a 4-byte boundary. Resource tables that cannot be
* memory mapped exert excess memory pressure on the system and drastically slow down
* construction of {@link Resources} objects.
*
* @hide
*/
public static final int INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED = -124;
/** @hide */
@IntDef(flag = true, prefix = { "DELETE_" }, value = {
DELETE_KEEP_DATA,

View File

@@ -22,6 +22,7 @@ import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
import static android.os.Build.VERSION_CODES.DONUT;
import static android.os.Build.VERSION_CODES.O;
@@ -344,7 +345,20 @@ public class ParsingPackageUtils {
+ result.getErrorMessage());
}
ParsingPackage pkg = result.getResult();
final ParsingPackage pkg = result.getResult();
if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.R
&& assets.containsAllocatedTable()) {
final ParseResult<?> deferResult = input.deferError(
"Targeting R+ (version" + Build.VERSION_CODES.R + " and above) requires the"
+ " resources.arsc of installed APKs to be stored uncompressed and"
+ " aligned on a 4-byte boundary",
DeferredError.RESOURCES_ARSC_COMPRESSED);
if (deferResult.isError()) {
return input.error(INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED,
deferResult.getErrorMessage());
}
}
ApkAssets apkAssets = assets.getApkAssets()[0];
if (apkAssets.definesOverlayable()) {
SparseArray<String> packageNames = assets.getAssignedPackageIdentifiers();

View File

@@ -59,6 +59,16 @@ public interface ParseInput {
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
public static final long EMPTY_INTENT_ACTION_CATEGORY = 151163173;
/**
* The {@code resources.arsc} of one of the APKs being installed is compressed or not
* aligned on a 4-byte boundary. Resource tables that cannot be memory mapped exert excess
* memory pressure on the system and drastically slow down construction of
* {@link android.content.res.Resources} objects.
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
public static final long RESOURCES_ARSC_COMPRESSED = 132742131;
}
<ResultType> ParseResult<ResultType> success(ResultType result);

View File

@@ -819,6 +819,19 @@ public final class AssetManager implements AutoCloseable {
}
}
/**
* Returns whether the {@code resources.arsc} of any loaded apk assets is allocated in RAM
* (not mmapped).
*
* @hide
*/
public boolean containsAllocatedTable() {
synchronized (this) {
ensureValidLocked();
return nativeContainsAllocatedTable(mObject);
}
}
CharSequence getPooledStringForCookie(int cookie, int id) {
// Cookies map to ApkAssets starting at 1.
return getApkAssets()[cookie - 1].getStringFromPool(id);
@@ -1482,6 +1495,7 @@ public final class AssetManager implements AutoCloseable {
long ptr, boolean includeOverlays, boolean includeLoaders);
// File native methods.
private static native boolean nativeContainsAllocatedTable(long ptr);
private static native @Nullable String[] nativeList(long ptr, @NonNull String path)
throws IOException;
private static native long nativeOpenAsset(long ptr, @NonNull String fileName, int accessMode);