diff --git a/core/api/current.txt b/core/api/current.txt index 776f37489ccd3..8d655d9349ac8 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32516,6 +32516,7 @@ package android.os { method public static final boolean is64Bit(); method public static boolean isApplicationUid(int); method public static final boolean isIsolated(); + method public static final boolean isSupplemental(); method public static final void killProcess(int); method public static final int myPid(); method @NonNull public static String myProcessName(); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index fe53e63a6500a..b082629ce99c0 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -389,6 +389,9 @@ package android.os { } public class Process { + method public static final boolean isSupplemental(int); + method public static final int toAppUid(int); + method public static final int toSupplementalUid(int); field public static final int NFC_UID = 1027; // 0x403 field public static final int VPN_UID = 1016; // 0x3f8 } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index a63f68a343d27..2fe0622681127 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -279,6 +279,26 @@ public class Process { */ public static final int LAST_APPLICATION_UID = 19999; + /** + * Defines the start of a range of UIDs going from this number to + * {@link #LAST_SUPPLEMENTAL_UID} that are reserved for assigning to + * supplemental processes. There is a 1-1 mapping between a supplemental + * process UID and the app that it belongs to, which can be computed by + * subtracting (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID) from the + * uid of a supplemental process. + * + * Note that there are no GIDs associated with these processes; storage + * attribution for them will be done using project IDs. + * @hide + */ + public static final int FIRST_SUPPLEMENTAL_UID = 20000; + + /** + * Last UID that is used for supplemental processes. + * @hide + */ + public static final int LAST_SUPPLEMENTAL_UID = 29999; + /** * First uid used for fully isolated sandboxed processes spawned from an app zygote * @hide @@ -880,6 +900,46 @@ public class Process { || (uid >= FIRST_APP_ZYGOTE_ISOLATED_UID && uid <= LAST_APP_ZYGOTE_ISOLATED_UID); } + /** + * Returns whether the provided UID belongs to a supplemental process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final boolean isSupplemental(int uid) { + uid = UserHandle.getAppId(uid); + return (uid >= FIRST_SUPPLEMENTAL_UID && uid <= LAST_SUPPLEMENTAL_UID); + } + + /** + * + * Returns the app process corresponding to a supplemental process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int toAppUid(int uid) { + return uid - (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID); + } + + /** + * + * Returns the supplemental process corresponding to an app process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int toSupplementalUid(int uid) { + return uid + (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID); + } + + /** + * Returns whether the current process is a supplemental process. + */ + public static final boolean isSupplemental() { + return isSupplemental(myUid()); + } + /** * Returns the UID assigned to a particular user name, or -1 if there is * none. If the given string consists of only numbers, it is converted diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index e040319b8aeee..888710857706b 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -4138,7 +4138,7 @@ public final class ActiveServices { // for a previous process to come up. To deal with this, we store // in the service any current isolated process it is running in or // waiting to have come up. - app = r.isolatedProc; + app = r.isolationHostProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingRecord = HostingRecord.byWebviewZygote(r.instanceName); @@ -4165,7 +4165,7 @@ public final class ActiveServices { return msg; } if (isolated) { - r.isolatedProc = app; + r.isolationHostProc = app; } } @@ -4976,7 +4976,7 @@ public final class ActiveServices { try { for (int i=0; i(); } @@ -5321,7 +5321,7 @@ public final class ActiveServices { sr.app.mServices.updateBoundClientUids(); } sr.setProcess(null, null, 0, null); - sr.isolatedProc = null; + sr.isolationHostProc = null; sr.executeNesting = 0; synchronized (mAm.mProcessStats.mLock) { sr.forceClearTracker(); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index b1234962efc23..bdfd02e9c25a8 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -598,7 +598,7 @@ public class OomAdjuster { for (int i = psr.numberOfConnections() - 1; i >= 0; i--) { ConnectionRecord cr = psr.getConnectionAt(i); ProcessRecord service = (cr.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 - ? cr.binding.service.isolatedProc : cr.binding.service.app; + ? cr.binding.service.isolationHostProc : cr.binding.service.app; if (service == null || service == pr) { continue; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c830554c398b7..be187e21db47d 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -513,7 +513,7 @@ class ProcessRecord implements WindowProcessListener { } } processInfo = procInfo; - isolated = _info.uid != _uid; + isolated = Process.isIsolated(_uid); appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID && UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID); uid = _uid; diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 9b32e61763f36..24e7ba4a32b96 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -102,7 +102,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // IBinder -> ConnectionRecord of all bound clients ProcessRecord app; // where this service is running or null. - ProcessRecord isolatedProc; // keep track of isolated process, if requested + ProcessRecord isolationHostProc; // process which we've started for this service (used for + // isolated and supplemental processes) ServiceState tracker; // tracking service execution, may be null ServiceState restartTracker; // tracking service restart boolean allowlistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? @@ -352,8 +353,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN if (app != null) { app.dumpDebug(proto, ServiceRecordProto.APP); } - if (isolatedProc != null) { - isolatedProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); + if (isolationHostProc != null) { + isolationHostProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); } proto.write(ServiceRecordProto.WHITELIST_MANAGER, allowlistManager); proto.write(ServiceRecordProto.DELAYED, delayed); @@ -455,8 +456,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir); } pw.print(prefix); pw.print("app="); pw.println(app); - if (isolatedProc != null) { - pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); + if (isolationHostProc != null) { + pw.print(prefix); pw.print("isolationHostProc="); pw.println(isolationHostProc); } if (allowlistManager) { pw.print(prefix); pw.print("allowlistManager="); pw.println(allowlistManager);