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
This commit is contained in:
@@ -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 ============================
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class UidObserver extends IUidObserver.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidProcAdjChanged(int uid) {
|
||||
public void onUidProcAdjChanged(int uid, int adj) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -644,6 +644,11 @@ class ProcessRecord implements WindowProcessListener {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy({"mService", "mProcLock"})
|
||||
int getSetAdj() {
|
||||
return mState.getSetAdj();
|
||||
}
|
||||
|
||||
@GuardedBy(anyOf = {"mService", "mProcLock"})
|
||||
IApplicationThread getThread() {
|
||||
return mThread;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -50,6 +50,12 @@ public final class UidRecord {
|
||||
@CompositeRWLock({"mService", "mProcLock"})
|
||||
private boolean mProcAdjChanged;
|
||||
|
||||
@CompositeRWLock({"mService", "mProcLock"})
|
||||
private int mCurAdj;
|
||||
|
||||
@CompositeRWLock({"mService", "mProcLock"})
|
||||
private int mSetAdj;
|
||||
|
||||
@CompositeRWLock({"mService", "mProcLock"})
|
||||
private int mCurCapability;
|
||||
|
||||
@@ -201,11 +207,23 @@ 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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user