
- 19.1/20.0: Enable low ram for <6GB devices - 20.0: support RROs with exec spawning patch from GrapheneOS - allow work profiles when low ram is enabled - churn - cherrypicks Signed-off-by: Tad <tad@spotco.us>
126 lines
5.7 KiB
Diff
126 lines
5.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
|
|
Date: Thu, 30 Mar 2023 17:42:56 +0300
|
|
Subject: [PATCH] exec spawning: support runtime resource overlays
|
|
|
|
---
|
|
core/java/android/app/IActivityManager.aidl | 2 ++
|
|
.../android/content/res/AssetManager.java | 33 +++++++++++++++++--
|
|
.../com/android/internal/os/ExecInit.java | 4 +++
|
|
.../server/am/ActivityManagerService.java | 6 ++++
|
|
4 files changed, 43 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
|
|
index 8367441b1b95..e582ea40ccf5 100644
|
|
--- a/core/java/android/app/IActivityManager.aidl
|
|
+++ b/core/java/android/app/IActivityManager.aidl
|
|
@@ -760,4 +760,6 @@ interface IActivityManager {
|
|
* </p>
|
|
*/
|
|
int getBackgroundRestrictionExemptionReason(int uid);
|
|
+
|
|
+ String[] getSystemIdmapPaths();
|
|
}
|
|
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
|
|
index 4d9c3258f659..2e0ba40c6552 100644
|
|
--- a/core/java/android/content/res/AssetManager.java
|
|
+++ b/core/java/android/content/res/AssetManager.java
|
|
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
|
|
import android.annotation.StringRes;
|
|
import android.annotation.StyleRes;
|
|
import android.annotation.TestApi;
|
|
+import android.app.ActivityManager;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.content.pm.ActivityInfo;
|
|
import android.content.res.Configuration.NativeConfig;
|
|
@@ -38,6 +39,7 @@ import android.util.TypedValue;
|
|
import com.android.internal.annotations.GuardedBy;
|
|
import com.android.internal.annotations.VisibleForTesting;
|
|
import com.android.internal.content.om.OverlayConfig;
|
|
+import com.android.internal.os.ExecInit;
|
|
|
|
import java.io.FileDescriptor;
|
|
import java.io.FileNotFoundException;
|
|
@@ -233,6 +235,9 @@ public final class AssetManager implements AutoCloseable {
|
|
}
|
|
}
|
|
|
|
+ /** @hide */
|
|
+ public static volatile String[] systemIdmapPaths_;
|
|
+
|
|
/**
|
|
* This must be called from Zygote so that system assets are shared by all applications.
|
|
* @hide
|
|
@@ -249,8 +254,32 @@ public final class AssetManager implements AutoCloseable {
|
|
final ArrayList<ApkAssets> apkAssets = new ArrayList<>();
|
|
apkAssets.add(ApkAssets.loadFromPath(frameworkPath, ApkAssets.PROPERTY_SYSTEM));
|
|
|
|
- final String[] systemIdmapPaths =
|
|
- OverlayConfig.getZygoteInstance().createImmutableFrameworkIdmapsInZygote();
|
|
+ // createImmutableFrameworkIdmapsInZygote() should be called only in zygote, it fails
|
|
+ // in regular processes and is unnecessary there.
|
|
+ // When it's called in zygote, overlay state is cached in /data/resource-cache/*@idmap
|
|
+ // files. These files are readable by regular app processes.
|
|
+ //
|
|
+ // When exec-based spawning in used, in-memory cache of assets is lost, and the spawned
|
|
+ // process is unable to recreate it, since it's not allowed to create idmaps.
|
|
+ //
|
|
+ // As a workaround, ask the ActivityManager to return paths of cached idmaps and use
|
|
+ // them directly. ActivityManager runs in system_server, which always uses zygote-based
|
|
+ // spawning.
|
|
+
|
|
+ String[] systemIdmapPaths;
|
|
+ if (ExecInit.isExecSpawned) {
|
|
+ try {
|
|
+ systemIdmapPaths = ActivityManager.getService().getSystemIdmapPaths();
|
|
+ Objects.requireNonNull(systemIdmapPaths);
|
|
+ } catch (Throwable t) {
|
|
+ Log.e(TAG, "unable to retrieve systemIdmapPaths", t);
|
|
+ systemIdmapPaths = new String[0];
|
|
+ }
|
|
+ } else {
|
|
+ systemIdmapPaths = OverlayConfig.getZygoteInstance().createImmutableFrameworkIdmapsInZygote();
|
|
+ systemIdmapPaths_ = systemIdmapPaths;
|
|
+ }
|
|
+
|
|
for (String idmapPath : systemIdmapPaths) {
|
|
apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, ApkAssets.PROPERTY_SYSTEM));
|
|
}
|
|
diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java
|
|
index 749c67abf389..39f08b6a0f15 100644
|
|
--- a/core/java/com/android/internal/os/ExecInit.java
|
|
+++ b/core/java/com/android/internal/os/ExecInit.java
|
|
@@ -84,6 +84,8 @@ public class ExecInit {
|
|
}
|
|
}
|
|
|
|
+ public static boolean isExecSpawned;
|
|
+
|
|
/**
|
|
* The main function called when an application is started with exec-based spawning.
|
|
*
|
|
@@ -99,6 +101,8 @@ public class ExecInit {
|
|
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from exec");
|
|
}
|
|
|
|
+ isExecSpawned = true;
|
|
+
|
|
// Check whether the first argument is a "-cp" in argv, and assume the next argument is the
|
|
// classpath. If found, create a PathClassLoader and use it for applicationInit.
|
|
ClassLoader classLoader = null;
|
|
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
|
|
index aa64cbffda24..71458e8568c7 100644
|
|
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
|
|
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
|
|
@@ -18597,4 +18597,10 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|
Trace.traceBegin(traceTag, methodName + subInfo);
|
|
}
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public String[] getSystemIdmapPaths() {
|
|
+ // see comment in AssetManager#createSystemAssetsInZygoteLocked()
|
|
+ return android.content.res.AssetManager.systemIdmapPaths_;
|
|
+ }
|
|
}
|