ActivityManagerService: explicitly break connection cycles
Currently, it is possible for two services to bind to each other and
receive each other's oom_adj, even if there are no other bindings that
would cause either process to be promoted. This causes a pair of
services to remain at a higher oom_adj level than they intended if
one service was promoted by a binding that was later destroyed.
To fix this, any process that encounters a cycle will be marked for a
later adjustment, and those bindings that encounter a cycle will not be
used to promote processes. After the initial oom_adj adjustments, all
processes that encountered a cycle will be retried. These retries will
continue until no process that encountered a cycle changes its process
state, at which point the process states should be stable.
Test: CTS; boots; runs normally
bug 78894563
Change-Id: I7cb2aa2fc461c08bc8e7f687a673249aef78351b
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b7fde1d..caf52e3 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -149,6 +149,8 @@
String waitingToKill; // Process is waiting to be killed when in the bg, and reason
Object forcingToImportant; // Token that is forcing this process to be important
int adjSeq; // Sequence id for identifying oom_adj assignment cycles
+ int completedAdjSeq; // Sequence id for identifying oom_adj assignment cycles
+ boolean containsCycle; // Whether this app has encountered a cycle in the most recent update
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
IBinder.DeathRecipient deathRecipient; // Who is watching for the death.