diff options
author | 2023-03-30 17:52:34 -0700 | |
---|---|---|
committer | 2023-04-28 17:04:09 -0700 | |
commit | 690c1ed1163333ec2fdf7bf01e57b141efddf65c (patch) | |
tree | 7b4dd7a13c0757fb27ae335a16c6971ddd3c5ed6 | |
parent | 49faea5924c524c12eb337fe9286f51bdf15a670 (diff) |
UidObserver / Camera: Track the OOM adj of a uid via UidObserver.
Previously, onUidProcAdjChanged merely signaled that the OOM adj of a
uid changed, but did not provide the actual OOM adj score. Having this
information allows the camera service to cut out redundant calls to
onCameraAccessPrioritiesChanged and avoid overwhelming apps.
The number of calls to onCameraAccessPrioritiesChanged is reduced by
only signaling when it's likely the uid owning a camera would lose
access to it if another uid tried to open that camera. This is opposed
to the status quo, which signals every time a watched uid changes its
OOM adj, which is highly inefficient.
Bug: 274486653
Test: -- on physical device:
-- testCamera2AccessCallbackInSplitMode x10
-- ActivityManagerServiceTest
-- ActivityManagerProcessStateTest
-- ActivityManagerFgsBgStartTest
-- UidObserverControllerTest
-- Alternate focus in split screen between Camera2 + GCA x20
Change-Id: I994bf56d8e1687460149626a3a658851ca9513c4
8 files changed, 44 insertions, 12 deletions
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl index 0c920f1359f3..60c2eeddac63 100644 --- a/core/java/android/app/IUidObserver.aidl +++ b/core/java/android/app/IUidObserver.aidl @@ -58,8 +58,9 @@ oneway interface IUidObserver { * Report a proc oom adj change associated with a uid. * * @param uid The uid for which the state change is being reported. + * @param adj The minimum OOM adj among all processes with this uid. */ - void onUidProcAdjChanged(int uid); + void onUidProcAdjChanged(int uid, int adj); // =============== End of transactions used on native side as well ============================ diff --git a/core/java/android/app/UidObserver.java b/core/java/android/app/UidObserver.java index 9e928073ac5c..519662448e91 100644 --- a/core/java/android/app/UidObserver.java +++ b/core/java/android/app/UidObserver.java @@ -41,7 +41,7 @@ public class UidObserver extends IUidObserver.Stub { } @Override - public void onUidProcAdjChanged(int uid) { + public void onUidProcAdjChanged(int uid, int adj) { } @Override diff --git a/native/android/activity_manager.cpp b/native/android/activity_manager.cpp index 155a355241c8..bc6a84f01517 100644 --- a/native/android/activity_manager.cpp +++ b/native/android/activity_manager.cpp @@ -45,7 +45,7 @@ struct UidObserver : public BnUidObserver, public virtual IBinder::DeathRecipien void onUidIdle(uid_t uid, bool disabled) override; void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq, int32_t capability) override; - void onUidProcAdjChanged(uid_t uid) override; + void onUidProcAdjChanged(uid_t uid, int32_t adj) override; // IBinder::DeathRecipient implementation void binderDied(const wp<IBinder>& who) override; @@ -121,7 +121,7 @@ void UidObserver::onUidActive(uid_t uid __unused) {} void UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {} -void UidObserver::onUidProcAdjChanged(uid_t uid __unused) {} +void UidObserver::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {} void UidObserver::onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq __unused, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1a5d4253b5ba..a992765c0411 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16060,6 +16060,8 @@ public class ActivityManagerService extends IActivityManager.Stub final int procState = uidRec != null ? uidRec.getSetProcState() : PROCESS_STATE_NONEXISTENT; + final int procAdj = uidRec != null + ? uidRec.getMinProcAdj() : ProcessList.INVALID_ADJ; final long procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0; final int capability = uidRec != null ? uidRec.getSetCapability() : 0; final boolean ephemeral = uidRec != null ? uidRec.isEphemeral() : isEphemeralLocked(uid); @@ -16075,7 +16077,7 @@ public class ActivityManagerService extends IActivityManager.Stub } final int enqueuedChange = mUidObserverController.enqueueUidChange( uidRec == null ? null : uidRec.pendingChange, - uid, change, procState, procStateSeq, capability, ephemeral); + uid, change, procState, procAdj, procStateSeq, capability, ephemeral); if (uidRec != null) { uidRec.setLastReportedChange(enqueuedChange); } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 438a08c44ef4..0417b8cfa2e2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -644,6 +644,11 @@ class ProcessRecord implements WindowProcessListener { } } + @GuardedBy({"mService", "mProcLock"}) + int getSetAdj() { + return mState.getSetAdj(); + } + @GuardedBy(anyOf = {"mService", "mProcLock"}) IApplicationThread getThread() { return mThread; diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java index 51cb9878c0b3..790cc7b87f80 100644 --- a/services/core/java/com/android/server/am/UidObserverController.java +++ b/services/core/java/com/android/server/am/UidObserverController.java @@ -96,7 +96,7 @@ public class UidObserverController { } int enqueueUidChange(@Nullable ChangeRecord currentRecord, int uid, int change, int procState, - long procStateSeq, int capability, boolean ephemeral) { + int procAdj, long procStateSeq, int capability, boolean ephemeral) { synchronized (mLock) { if (mPendingUidChanges.size() == 0) { if (DEBUG_UID_OBSERVERS) { @@ -117,6 +117,7 @@ public class UidObserverController { changeRecord.uid = uid; changeRecord.change = change; changeRecord.procState = procState; + changeRecord.procAdj = procAdj; changeRecord.procStateSeq = procStateSeq; changeRecord.capability = capability; changeRecord.ephemeral = ephemeral; @@ -344,7 +345,7 @@ public class UidObserverController { } if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) != 0 && (change & UidRecord.CHANGE_PROCADJ) != 0) { - observer.onUidProcAdjChanged(item.uid); + observer.onUidProcAdjChanged(item.uid, item.procAdj); } } final int duration = (int) (SystemClock.uptimeMillis() - start); @@ -426,6 +427,7 @@ public class UidObserverController { public int uid; public int change; public int procState; + public int procAdj; public int capability; public boolean ephemeral; public long procStateSeq; @@ -435,6 +437,7 @@ public class UidObserverController { changeRecord.uid = uid; changeRecord.change = change; changeRecord.procState = procState; + changeRecord.procAdj = procAdj; changeRecord.capability = capability; changeRecord.ephemeral = ephemeral; changeRecord.procStateSeq = procStateSeq; diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java index e39ac2b08479..993088ef106e 100644 --- a/services/core/java/com/android/server/am/UidRecord.java +++ b/services/core/java/com/android/server/am/UidRecord.java @@ -51,6 +51,12 @@ public final class UidRecord { private boolean mProcAdjChanged; @CompositeRWLock({"mService", "mProcLock"}) + private int mCurAdj; + + @CompositeRWLock({"mService", "mProcLock"}) + private int mSetAdj; + + @CompositeRWLock({"mService", "mProcLock"}) private int mCurCapability; @CompositeRWLock({"mService", "mProcLock"}) @@ -201,12 +207,24 @@ public final class UidRecord { mProcAdjChanged = false; } - @GuardedBy({"mService", "mProcLock"}) + @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean getProcAdjChanged() { return mProcAdjChanged; } @GuardedBy(anyOf = {"mService", "mProcLock"}) + int getMinProcAdj() { + int minAdj = ProcessList.UNKNOWN_ADJ; + for (int i = mProcRecords.size() - 1; i >= 0; i--) { + int adj = mProcRecords.valueAt(i).getSetAdj(); + if (adj < minAdj) { + minAdj = adj; + } + } + return minAdj; + } + + @GuardedBy(anyOf = {"mService", "mProcLock"}) int getCurCapability() { return mCurCapability; } diff --git a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java index f788c92b24b2..46974cf72381 100644 --- a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java @@ -28,6 +28,8 @@ import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; +import static com.android.server.am.ProcessList.UNKNOWN_ADJ; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; @@ -81,7 +83,7 @@ public class UidObserverControllerTest { public void testEnqueueUidChange() { int change = mUidObserverController.enqueueUidChange(null, TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, - PROCESS_CAPABILITY_ALL, 0, false); + UNKNOWN_ADJ, PROCESS_CAPABILITY_ALL, 0, false); assertEquals("expected=ACTIVE,actual=" + changeToStr(change), UidRecord.CHANGE_ACTIVE, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, @@ -91,8 +93,8 @@ public class UidObserverControllerTest { final ChangeRecord record2 = new ChangeRecord(); change = mUidObserverController.enqueueUidChange(record2, TEST_UID2, - UidRecord.CHANGE_CACHED, PROCESS_STATE_CACHED_RECENT, PROCESS_CAPABILITY_NONE, - 99, true); + UidRecord.CHANGE_CACHED, PROCESS_STATE_CACHED_RECENT, UNKNOWN_ADJ, + PROCESS_CAPABILITY_NONE, 99, true); assertEquals("expected=ACTIVE,actual=" + changeToStr(change), UidRecord.CHANGE_CACHED, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, @@ -101,7 +103,8 @@ public class UidObserverControllerTest { PROCESS_CAPABILITY_NONE, 99, true, record2); change = mUidObserverController.enqueueUidChange(record1, TEST_UID1, - UidRecord.CHANGE_UNCACHED, PROCESS_STATE_TOP, PROCESS_CAPABILITY_ALL, 0, false); + UidRecord.CHANGE_UNCACHED, PROCESS_STATE_TOP, UNKNOWN_ADJ, + PROCESS_CAPABILITY_ALL, 0, false); assertEquals("expected=ACTIVE|UNCACHED,actual=" + changeToStr(change), UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_UNCACHED, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_UNCACHED, |