Merge "OomAdjuster: Give SDK sandbox the priority of the app it belongs to."

This commit is contained in:
Martijn Coenen
2023-01-24 07:21:16 +00:00
committed by Android (Google) Code Review
2 changed files with 84 additions and 2 deletions

View File

@@ -143,6 +143,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* All of the code required to compute proc states and oom_adj values.
@@ -743,6 +744,45 @@ public class OomAdjuster {
queue.offer(provider);
provider.mState.setReachable(true);
}
// See if this process has any corresponding SDK sandbox processes running, and if so
// scan them as well.
final List<ProcessRecord> sdkSandboxes =
mProcessList.getSdkSandboxProcessesForAppLocked(pr.uid);
final int numSdkSandboxes = sdkSandboxes != null ? sdkSandboxes.size() : 0;
for (int i = numSdkSandboxes - 1; i >= 0; i--) {
ProcessRecord sdkSandbox = sdkSandboxes.get(i);
containsCycle |= sdkSandbox.mState.isReachable();
if (sdkSandbox.mState.isReachable()) {
continue;
}
queue.offer(sdkSandbox);
sdkSandbox.mState.setReachable(true);
}
// If this process is a sandbox itself, also scan the app on whose behalf its running
if (pr.isSdkSandbox) {
for (int is = psr.numberOfRunningServices() - 1; is >= 0; is--) {
ServiceRecord s = psr.getRunningServiceAt(is);
ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections =
s.getConnections();
for (int conni = serviceConnections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
for (int i = clist.size() - 1; i >= 0; i--) {
ConnectionRecord cr = clist.get(i);
ProcessRecord attributedApp = cr.binding.attributedClient;
if (attributedApp == null || attributedApp == pr
|| ((attributedApp.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ)
&& (attributedApp.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) {
continue;
}
if (attributedApp.mState.isReachable()) {
continue;
}
queue.offer(attributedApp);
attributedApp.mState.setReachable(true);
}
}
}
}
}
int size = processes.size();
@@ -2131,6 +2171,11 @@ public class OomAdjuster {
boolean trackedProcState = false;
ProcessRecord client = cr.binding.client;
if (app.isSdkSandbox && cr.binding.attributedClient != null) {
// For SDK sandboxes, use the attributed client (eg the app that
// requested the sandbox)
client = cr.binding.attributedClient;
}
final ProcessStateRecord cstate = client.mState;
if (computeClients) {
computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now,
@@ -2377,12 +2422,12 @@ public class OomAdjuster {
state.setAdjType(adjType);
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE);
state.setAdjSource(cr.binding.client);
state.setAdjSource(client);
state.setAdjSourceProcState(clientProcState);
state.setAdjTarget(s.instanceName);
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
+ ": " + app + ", due to " + cr.binding.client
+ ": " + app + ", due to " + client
+ " adj=" + adj + " procState="
+ ProcessList.makeProcStateString(procState));
}

View File

@@ -484,6 +484,12 @@ public final class ProcessList {
@GuardedBy("mService")
final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
/**
* The currently running SDK sandbox processes for a uid.
*/
@GuardedBy("mService")
final SparseArray<ArrayList<ProcessRecord>> mSdkSandboxes = new SparseArray<>();
/**
* Managees the {@link android.app.ApplicationExitInfo} records.
*/
@@ -2990,6 +2996,14 @@ public final class ProcessList {
if (proc.isolated) {
mIsolatedProcesses.put(proc.uid, proc);
}
if (proc.isSdkSandbox) {
ArrayList<ProcessRecord> sdkSandboxes = mSdkSandboxes.get(proc.uid);
if (sdkSandboxes == null) {
sdkSandboxes = new ArrayList<>();
}
sdkSandboxes.add(proc);
mSdkSandboxes.put(Process.getAppUidForSdkSandboxUid(proc.uid), sdkSandboxes);
}
}
@GuardedBy("mService")
@@ -3030,6 +3044,19 @@ public final class ProcessList {
return ret;
}
/**
* Returns the associated SDK sandbox processes for a UID. Note that this does
* NOT return a copy, so callers should not modify the result, or use it outside
* of the lock scope.
*
* @param uid UID to return sansdbox processes for
*/
@Nullable
@GuardedBy("mService")
List<ProcessRecord> getSdkSandboxProcessesForAppLocked(int uid) {
return mSdkSandboxes.get(uid);
}
@GuardedBy("mService")
ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
@@ -3135,6 +3162,16 @@ public final class ProcessList {
if (record != null && record.appZygote) {
removeProcessFromAppZygoteLocked(record);
}
if (record != null && record.isSdkSandbox) {
final int appUid = Process.getAppUidForSdkSandboxUid(uid);
final ArrayList<ProcessRecord> sdkSandboxesForUid = mSdkSandboxes.get(appUid);
if (sdkSandboxesForUid != null) {
sdkSandboxesForUid.remove(record);
if (sdkSandboxesForUid.size() == 0) {
mSdkSandboxes.remove(appUid);
}
}
}
mAppsInBackgroundRestricted.remove(record);
return old;