summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorRyan Mitchell <rtmitchell@google.com>2020-04-13 14:57:19 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-04-13 14:57:19 +0000
commitb8a61d13c2fd447abe5ce9cd635ea3a49c08ebe9 (patch)
tree409f4650f743226a23edce1febcafd7700af4f02 /core/java/android
parent2dc9632eb555fe4e3fe46ccf6454200025569c86 (diff)
parent192400cf334e0e8befe336861a6d214c6a88c993 (diff)
Merge "Fail install when resources.arsc is compressed" into rvc-dev
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/pm/PackageManager.java10
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java16
-rw-r--r--core/java/android/content/pm/parsing/result/ParseInput.java10
-rw-r--r--core/java/android/content/res/AssetManager.java14
4 files changed, 49 insertions, 1 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9a2e07e9cfbd..9ca2db970eb7 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -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,
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 6bd8b1d9d7c0..c61362feaeae 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -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();
diff --git a/core/java/android/content/pm/parsing/result/ParseInput.java b/core/java/android/content/pm/parsing/result/ParseInput.java
index 538510049e04..6b659bea84f1 100644
--- a/core/java/android/content/pm/parsing/result/ParseInput.java
+++ b/core/java/android/content/pm/parsing/result/ParseInput.java
@@ -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);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index d2103af1d247..15a184f0e5ef 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -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);