summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Austin Borger <borgera@google.com> 2022-02-17 00:22:33 +0000
committer Austin Borger <borgera@google.com> 2022-03-28 19:46:45 -0700
commitdb9165baf2c2649048d8cc31d55d643cfd251df8 (patch)
treedf34040299c14a41f421e21c3d12c636c0b59c26
parent177d5bb18756ddca6e9f9e8caa0338ae07f21c92 (diff)
Add new onUidProcAdjChanged callback to be consumed by the camera
service. The camera service needs to know when individual process oom adj scores are changed in order to address bug #124224342. When two separate processes are displayed in split screen and focus is switched between them, both proc states will remain the same while their oom scores change. This is a problem if both have access to the camera - we want only one owner of the camera stream at any given time and for the app in focus to be the one to own it. This patch adds a new IUidObserver registration level for individual process oom score changes. In addition a new callback has been added to IUidObserver to track these changes. Change-Id: I68d964f474d20f819f54b614a4e314ce00aac8fb Bug: 124224342 Test: -- ActivityManagerServiceTest -- ActivityManagerProcessStateTest -- ActivityManagerFgsBgStartTest -- UidObserverControllerTest -- NetworkPolicyManagerServiceTest -- ShortcutManagerTest2 -- HintManagerServiceTest -- VibrationSettingsTest -- CameraEvictionTest#testCamera2AccessCallbackInSplitMode (x100)
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java3
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java4
-rw-r--r--core/java/android/app/ActivityManager.java6
-rw-r--r--core/java/android/app/IUidObserver.aidl7
-rw-r--r--core/proto/android/app/activitymanager.proto2
-rw-r--r--core/proto/android/server/activitymanagerservice.proto1
-rw-r--r--native/android/activity_manager.cpp3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt1
-rw-r--r--services/core/java/com/android/server/PinnerService.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/am/AppRestrictionController.java4
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java142
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java46
-rw-r--r--services/core/java/com/android/server/am/UidObserverController.java20
-rw-r--r--services/core/java/com/android/server/am/UidRecord.java25
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java3
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java3
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java4
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java4
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java3
24 files changed, 218 insertions, 84 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index 70d5038945f3..fab5b5fd6933 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -767,6 +767,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
}
private final class AppOpsWatcher extends IAppOpsCallback.Stub {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 2028be738238..c4caa6cb2822 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1009,6 +1009,9 @@ public class JobSchedulerService extends com.android.server.SystemService
@Override public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
};
public Context getTestableContext() {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index ee0f9e8f9658..b3e81cb89e52 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -404,6 +404,10 @@ public final class QuotaController extends StateController {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
}
/**
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java
index 5ec2f5607153..3578c8acbd0e 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java
@@ -97,6 +97,10 @@ class ProcessStateModifier extends Modifier {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
};
ProcessStateModifier(@NonNull InternalResourceService irs) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 5b05b45d05db..7aefbae4a3b2 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -222,6 +222,9 @@ public class ActivityManager {
@Override public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
}
final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
@@ -825,6 +828,9 @@ public class ActivityManager {
/** @hide Flag for registerUidObserver: report uid capability has changed. */
public static final int UID_OBSERVER_CAPABILITY = 1<<5;
+ /** @hide Flag for registerUidObserver: report pid oom adj has changed. */
+ public static final int UID_OBSERVER_PROC_OOM_ADJ = 1 << 6;
+
/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
public static final int APP_START_MODE_NORMAL = 0;
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index 74018a8ab1f8..0c920f1359f3 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -54,6 +54,13 @@ oneway interface IUidObserver {
*/
void onUidStateChanged(int uid, int procState, long procStateSeq, int capability);
+ /**
+ * Report a proc oom adj change associated with a uid.
+ *
+ * @param uid The uid for which the state change is being reported.
+ */
+ void onUidProcAdjChanged(int uid);
+
// =============== End of transactions used on native side as well ============================
/**
diff --git a/core/proto/android/app/activitymanager.proto b/core/proto/android/app/activitymanager.proto
index a21d1d4f0a85..8d8759f20854 100644
--- a/core/proto/android/app/activitymanager.proto
+++ b/core/proto/android/app/activitymanager.proto
@@ -35,4 +35,6 @@ enum UidObserverFlag {
UID_OBSERVER_FLAG_CACHED = 5;
// report uid capability has changed, original value is 1 << 5
UID_OBSERVER_FLAG_CAPABILITY = 6;
+ // report pid oom adj has changed, original value is 1 << 6
+ UID_OBSERVER_FLAG_PROC_OOM_ADJ = 7;
}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 2bb891280e71..7205dd817eb5 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -780,6 +780,7 @@ message UidRecordProto {
CHANGE_UNCACHED = 4;
CHANGE_CAPABILITY = 5;
CHANGE_PROCSTATE = 6;
+ CHANGE_PROCADJ = 7;
}
repeated Change last_reported_changes = 8;
optional int32 num_procs = 9;
diff --git a/native/android/activity_manager.cpp b/native/android/activity_manager.cpp
index 82f4569b871e..155a355241c8 100644
--- a/native/android/activity_manager.cpp
+++ b/native/android/activity_manager.cpp
@@ -45,6 +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;
// IBinder::DeathRecipient implementation
void binderDied(const wp<IBinder>& who) override;
@@ -120,6 +121,8 @@ 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::onUidStateChanged(uid_t uid, int32_t procState,
int64_t procStateSeq __unused,
int32_t capability __unused) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 6ee65ae7e2ef..ec44f18c8eb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -394,6 +394,7 @@ class OngoingCallController @Inject constructor(
override fun onUidActive(uid: Int) {}
override fun onUidIdle(uid: Int, disabled: Boolean) {}
override fun onUidCachedChanged(uid: Int, cached: Boolean) {}
+ override fun onUidProcAdjChanged(uid: Int) {}
}
}
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 16ff167380bd..c5eb25b9981e 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -385,6 +385,10 @@ public final class PinnerService extends SystemService {
@Override
public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) throws RemoteException {
+ }
}, UID_OBSERVER_GONE | UID_OBSERVER_ACTIVE, 0, null);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to register uid observer", e);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 45f06c74cac2..15218611b51e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15257,7 +15257,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if ((enqueuedChange & UidRecord.CHANGE_GONE) != 0) {
mLocalPowerManager.uidGone(uid);
- } else {
+ } else if ((enqueuedChange & UidRecord.CHANGE_PROCSTATE) != 0) {
mLocalPowerManager.updateUidProcState(uid, procState);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 2b61e7fd2752..1d39d4a2aa99 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1671,6 +1671,10 @@ final class ActivityManagerShellCommand extends ShellCommand {
}
@Override
+ public void onUidProcAdjChanged(int uid) throws RemoteException {
+ }
+
+ @Override
public void onOomAdjMessage(String msg) {
synchronized (this) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 41ff08309d89..d758a7fdcd82 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -908,6 +908,10 @@ public final class AppRestrictionController {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
};
/**
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 85d3d5dca16b..85f2a922932d 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1191,70 +1191,88 @@ public class OomAdjuster {
}
for (int i = activeUids.size() - 1; i >= 0; i--) {
final UidRecord uidRec = activeUids.valueAt(i);
- int uidChange = 0;
- if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT
- && (uidRec.getSetProcState() != uidRec.getCurProcState()
- || uidRec.getSetCapability() != uidRec.getCurCapability()
- || uidRec.isSetAllowListed() != uidRec.isCurAllowListed())) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
- + ": proc state from " + uidRec.getSetProcState() + " to "
- + uidRec.getCurProcState() + ", capability from "
- + uidRec.getSetCapability() + " to " + uidRec.getCurCapability()
- + ", allowlist from " + uidRec.isSetAllowListed()
- + " to " + uidRec.isCurAllowListed());
- if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
- && !uidRec.isCurAllowListed()) {
- // UID is now in the background (and not on the temp allowlist). Was it
- // previously in the foreground (or on the temp allowlist)?
- if (!ActivityManager.isProcStateBackground(uidRec.getSetProcState())
- || uidRec.isSetAllowListed()) {
- uidRec.setLastBackgroundTime(nowElapsed);
- if (!mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
- // Note: the background settle time is in elapsed realtime, while
- // the handler time base is uptime. All this means is that we may
- // stop background uids later than we had intended, but that only
- // happens because the device was sleeping so we are okay anyway.
- mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
- mConstants.BACKGROUND_SETTLE_TIME);
+ if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT) {
+ if (uidRec.getSetProcState() != uidRec.getCurProcState()
+ || uidRec.getSetCapability() != uidRec.getCurCapability()
+ || uidRec.isSetAllowListed() != uidRec.isCurAllowListed()
+ || uidRec.getProcAdjChanged()) {
+ int uidChange = 0;
+ if (DEBUG_UID_OBSERVERS) {
+ Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
+ + ": proc state from " + uidRec.getSetProcState() + " to "
+ + uidRec.getCurProcState() + ", capability from "
+ + uidRec.getSetCapability() + " to " + uidRec.getCurCapability()
+ + ", allowlist from " + uidRec.isSetAllowListed()
+ + " to " + uidRec.isCurAllowListed()
+ + ", procAdjChanged: " + uidRec.getProcAdjChanged());
+ }
+ if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
+ && !uidRec.isCurAllowListed()) {
+ // UID is now in the background (and not on the temp allowlist). Was it
+ // previously in the foreground (or on the temp allowlist)?
+ if (!ActivityManager.isProcStateBackground(uidRec.getSetProcState())
+ || uidRec.isSetAllowListed()) {
+ uidRec.setLastBackgroundTime(nowElapsed);
+ if (!mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
+ // Note: the background settle time is in elapsed realtime, while
+ // the handler time base is uptime. All this means is that we may
+ // stop background uids later than we had intended, but that only
+ // happens because the device was sleeping so we are okay anyway.
+ mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
+ mConstants.BACKGROUND_SETTLE_TIME);
+ }
+ }
+ if (uidRec.isIdle() && !uidRec.isSetIdle()) {
+ uidChange |= UidRecord.CHANGE_IDLE;
+ becameIdle.add(uidRec);
}
+ } else {
+ if (uidRec.isIdle()) {
+ uidChange |= UidRecord.CHANGE_ACTIVE;
+ EventLogTags.writeAmUidActive(uidRec.getUid());
+ uidRec.setIdle(false);
+ }
+ uidRec.setLastBackgroundTime(0);
}
- if (uidRec.isIdle() && !uidRec.isSetIdle()) {
- uidChange |= UidRecord.CHANGE_IDLE;
- becameIdle.add(uidRec);
+ final boolean wasCached = uidRec.getSetProcState()
+ > ActivityManager.PROCESS_STATE_RECEIVER;
+ final boolean isCached = uidRec.getCurProcState()
+ > ActivityManager.PROCESS_STATE_RECEIVER;
+ if (wasCached != isCached
+ || uidRec.getSetProcState() == PROCESS_STATE_NONEXISTENT) {
+ uidChange |= isCached ? UidRecord.CHANGE_CACHED :
+ UidRecord.CHANGE_UNCACHED;
}
- } else {
- if (uidRec.isIdle()) {
- uidChange |= UidRecord.CHANGE_ACTIVE;
- EventLogTags.writeAmUidActive(uidRec.getUid());
- uidRec.setIdle(false);
+ if (uidRec.getSetCapability() != uidRec.getCurCapability()) {
+ uidChange |= UidRecord.CHANGE_CAPABILITY;
+ }
+ if (uidRec.getSetProcState() != uidRec.getCurProcState()) {
+ uidChange |= UidRecord.CHANGE_PROCSTATE;
+ }
+ if (uidRec.getProcAdjChanged()) {
+ uidChange |= UidRecord.CHANGE_PROCADJ;
+ }
+ uidRec.setSetProcState(uidRec.getCurProcState());
+ uidRec.setSetCapability(uidRec.getCurCapability());
+ uidRec.setSetAllowListed(uidRec.isCurAllowListed());
+ uidRec.setSetIdle(uidRec.isIdle());
+ uidRec.clearProcAdjChanged();
+ if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0
+ || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) {
+ mService.mAtmInternal.onUidProcStateChanged(
+ uidRec.getUid(), uidRec.getSetProcState());
+ }
+ if (uidChange != 0) {
+ mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
+ }
+ if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0
+ || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) {
+ mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(),
+ uidRec.getCurCapability());
+ }
+ if (uidRec.hasForegroundServices()) {
+ mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
}
- uidRec.setLastBackgroundTime(0);
- }
- final boolean wasCached = uidRec.getSetProcState()
- > ActivityManager.PROCESS_STATE_RECEIVER;
- final boolean isCached = uidRec.getCurProcState()
- > ActivityManager.PROCESS_STATE_RECEIVER;
- if (wasCached != isCached
- || uidRec.getSetProcState() == PROCESS_STATE_NONEXISTENT) {
- uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
- }
- if (uidRec.getSetCapability() != uidRec.getCurCapability()) {
- uidChange |= UidRecord.CHANGE_CAPABILITY;
- }
- if (uidRec.getSetProcState() != uidRec.getCurProcState()) {
- uidChange |= UidRecord.CHANGE_PROCSTATE;
- }
- uidRec.setSetProcState(uidRec.getCurProcState());
- uidRec.setSetCapability(uidRec.getCurCapability());
- uidRec.setSetAllowListed(uidRec.isCurAllowListed());
- uidRec.setSetIdle(uidRec.isIdle());
- mService.mAtmInternal.onUidProcStateChanged(
- uidRec.getUid(), uidRec.getSetProcState());
- mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
- mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(),
- uidRec.getCurCapability());
- if (uidRec.hasForegroundServices()) {
- mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
}
}
mService.mInternal.deletePendingTopUid(uidRec.getUid());
@@ -2513,6 +2531,7 @@ public class OomAdjuster {
long nowElapsed) {
boolean success = true;
final ProcessStateRecord state = app.mState;
+ final UidRecord uidRec = app.getUidRecord();
if (state.getCurRawAdj() != state.getSetRawAdj()) {
state.setSetRawAdj(state.getCurRawAdj());
@@ -2551,6 +2570,9 @@ public class OomAdjuster {
reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
}
state.setSetAdj(state.getCurAdj());
+ if (uidRec != null) {
+ uidRec.noteProcAdjChanged();
+ }
state.setVerifiedAdj(ProcessList.INVALID_ADJ);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a8612fd8b190..6629a3018f81 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -180,22 +180,22 @@ public final class ProcessList {
// OOM adjustments for processes in various states:
// Uninitialized value for any major or minor adj fields
- static final int INVALID_ADJ = -10000;
+ public static final int INVALID_ADJ = -10000;
// Adjustment used in certain places where we don't know it yet.
// (Generally this is something that is going to be cached, but we
// don't know the exact value in the cached range to assign yet.)
- static final int UNKNOWN_ADJ = 1001;
+ public static final int UNKNOWN_ADJ = 1001;
// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption.
- static final int CACHED_APP_MAX_ADJ = 999;
- static final int CACHED_APP_MIN_ADJ = 900;
+ public static final int CACHED_APP_MAX_ADJ = 999;
+ public static final int CACHED_APP_MIN_ADJ = 900;
// This is the oom_adj level that we allow to die first. This cannot be equal to
// CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
// CACHED_APP_MAX_ADJ.
- static final int CACHED_APP_LMK_FIRST_ADJ = 950;
+ public static final int CACHED_APP_LMK_FIRST_ADJ = 950;
// Number of levels we have available for different service connection group importance
// levels.
@@ -203,7 +203,7 @@ public final class ProcessList {
// The B list of SERVICE_ADJ -- these are the old and decrepit
// services that aren't as shiny and interesting as the ones in the A list.
- static final int SERVICE_B_ADJ = 800;
+ public static final int SERVICE_B_ADJ = 800;
// This is the process of the previous application that the user was in.
// This process is kept above other things, because it is very common to
@@ -211,68 +211,68 @@ public final class ProcessList {
// task switch (toggling between the two top recent apps) as well as normal
// UI flow such as clicking on a URI in the e-mail app to view in the browser,
// and then pressing back to return to e-mail.
- static final int PREVIOUS_APP_ADJ = 700;
+ public static final int PREVIOUS_APP_ADJ = 700;
// This is a process holding the home application -- we want to try
// avoiding killing it, even if it would normally be in the background,
// because the user interacts with it so much.
- static final int HOME_APP_ADJ = 600;
+ public static final int HOME_APP_ADJ = 600;
// This is a process holding an application service -- killing it will not
// have much of an impact as far as the user is concerned.
- static final int SERVICE_ADJ = 500;
+ public static final int SERVICE_ADJ = 500;
// This is a process with a heavy-weight application. It is in the
// background, but we want to try to avoid killing it. Value set in
// system/rootdir/init.rc on startup.
- static final int HEAVY_WEIGHT_APP_ADJ = 400;
+ public static final int HEAVY_WEIGHT_APP_ADJ = 400;
// This is a process currently hosting a backup operation. Killing it
// is not entirely fatal but is generally a bad idea.
- static final int BACKUP_APP_ADJ = 300;
+ public static final int BACKUP_APP_ADJ = 300;
// This is a process bound by the system (or other app) that's more important than services but
// not so perceptible that it affects the user immediately if killed.
- static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
+ public static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
// This is a process hosting services that are not perceptible to the user but the
// client (system) binding to it requested to treat it as if it is perceptible and avoid killing
// it if possible.
- static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225;
+ public static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225;
// This is a process only hosting components that are perceptible to the
// user, and we really want to avoid killing them, but they are not
// immediately visible. An example is background music playback.
- static final int PERCEPTIBLE_APP_ADJ = 200;
+ public static final int PERCEPTIBLE_APP_ADJ = 200;
// This is a process only hosting activities that are visible to the
// user, so we'd prefer they don't disappear.
- static final int VISIBLE_APP_ADJ = 100;
+ public static final int VISIBLE_APP_ADJ = 100;
static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
// This is a process that was recently TOP and moved to FGS. Continue to treat it almost
// like a foreground app for a while.
// @see TOP_TO_FGS_GRACE_PERIOD
- static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
+ public static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
// This is the process running the current foreground app. We'd really
// rather not kill it!
- static final int FOREGROUND_APP_ADJ = 0;
+ public static final int FOREGROUND_APP_ADJ = 0;
// This is a process that the system or a persistent process has bound to,
// and indicated it is important.
- static final int PERSISTENT_SERVICE_ADJ = -700;
+ public static final int PERSISTENT_SERVICE_ADJ = -700;
// This is a system persistent process, such as telephony. Definitely
// don't want to kill it, but doing so is not completely fatal.
- static final int PERSISTENT_PROC_ADJ = -800;
+ public static final int PERSISTENT_PROC_ADJ = -800;
// The system process runs at the default adjustment.
- static final int SYSTEM_ADJ = -900;
+ public static final int SYSTEM_ADJ = -900;
// Special code for native processes that are not being managed by the system (so
// don't have an oom adj assigned by the system).
- static final int NATIVE_ADJ = -1000;
+ public static final int NATIVE_ADJ = -1000;
// Memory pages are 4K.
static final int PAGE_SIZE = 4 * 1024;
@@ -5383,5 +5383,9 @@ public final class ProcessList {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
};
}
diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java
index c3a232aac4b5..e42dac46d7c7 100644
--- a/services/core/java/com/android/server/am/UidObserverController.java
+++ b/services/core/java/com/android/server/am/UidObserverController.java
@@ -157,6 +157,9 @@ public class UidObserverController {
if ((pendingChange & UidRecord.CHANGE_PROCSTATE) != 0) {
currentChange |= UidRecord.CHANGE_PROCSTATE;
}
+ if ((pendingChange & UidRecord.CHANGE_PROCADJ) != 0) {
+ currentChange |= UidRecord.CHANGE_PROCADJ;
+ }
return currentChange;
}
@@ -248,6 +251,7 @@ public class UidObserverController {
try {
for (int j = 0; j < changesSize; j++) {
final ChangeRecord item = mActiveUidChanges[j];
+ final long start = SystemClock.uptimeMillis();
final int change = item.change;
if (change == UidRecord.CHANGE_PROCSTATE
&& (reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
@@ -255,7 +259,12 @@ public class UidObserverController {
// interested in all proc state changes.
continue;
}
- final long start = SystemClock.uptimeMillis();
+ if (change == UidRecord.CHANGE_PROCADJ
+ && (reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) == 0) {
+ // No-op common case: no significant change, the observer is not
+ // interested in proc adj changes.
+ continue;
+ }
if ((change & UidRecord.CHANGE_IDLE) != 0) {
if ((reg.mWhich & ActivityManager.UID_OBSERVER_IDLE) != 0) {
if (DEBUG_UID_OBSERVERS) {
@@ -322,7 +331,12 @@ public class UidObserverController {
reg.mLastProcStates.put(item.uid, item.procState);
}
observer.onUidStateChanged(item.uid, item.procState,
- item.procStateSeq, item.capability);
+ item.procStateSeq,
+ item.capability);
+ }
+ if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) != 0
+ && (change & UidRecord.CHANGE_PROCADJ) != 0) {
+ observer.onUidProcAdjChanged(item.uid);
}
}
final int duration = (int) (SystemClock.uptimeMillis() - start);
@@ -443,6 +457,7 @@ public class UidObserverController {
ActivityManager.UID_OBSERVER_GONE,
ActivityManager.UID_OBSERVER_PROCSTATE,
ActivityManager.UID_OBSERVER_CAPABILITY,
+ ActivityManager.UID_OBSERVER_PROC_OOM_ADJ,
};
private static final int[] PROTO_ENUMS = new int[]{
ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
@@ -450,6 +465,7 @@ public class UidObserverController {
ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
ActivityManagerProto.UID_OBSERVER_FLAG_CAPABILITY,
+ ActivityManagerProto.UID_OBSERVER_FLAG_PROC_OOM_ADJ,
};
UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint) {
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 606e6fc82650..5c78d1eb5ff2 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -48,6 +48,9 @@ public final class UidRecord {
private int mSetProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
@CompositeRWLock({"mService", "mProcLock"})
+ private boolean mProcAdjChanged;
+
+ @CompositeRWLock({"mService", "mProcLock"})
private int mCurCapability;
@CompositeRWLock({"mService", "mProcLock"})
@@ -126,6 +129,7 @@ public final class UidRecord {
static final int CHANGE_CACHED = 1 << 3;
static final int CHANGE_UNCACHED = 1 << 4;
static final int CHANGE_CAPABILITY = 1 << 5;
+ static final int CHANGE_PROCADJ = 1 << 6;
static final int CHANGE_PROCSTATE = 1 << 31;
// Keep the enum lists in sync
@@ -186,6 +190,21 @@ public final class UidRecord {
mSetProcState = setProcState;
}
+ @GuardedBy({"mService", "mProcLock"})
+ void noteProcAdjChanged() {
+ mProcAdjChanged = true;
+ }
+
+ @GuardedBy({"mService", "mProcLock"})
+ void clearProcAdjChanged() {
+ mProcAdjChanged = false;
+ }
+
+ @GuardedBy({"mService", "mProcLock"})
+ boolean getProcAdjChanged() {
+ return mProcAdjChanged;
+ }
+
@GuardedBy(anyOf = {"mService", "mProcLock"})
int getCurCapability() {
return mCurCapability;
@@ -428,6 +447,12 @@ public final class UidRecord {
}
sb.append("procstate");
}
+ if ((mLastReportedChange & CHANGE_PROCADJ) != 0) {
+ if (printed) {
+ sb.append("|");
+ }
+ sb.append("procadj");
+ }
}
sb.append(" procs:");
sb.append(mNumProcs);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index a68fc05dbbf1..dc6bd49e546f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -862,6 +862,9 @@ public class AudioService extends IAudioService.Stub
disableAudioForUid(cached, uid);
}
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
+
private void disableAudioForUid(boolean disable, int uid) {
queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
disable ? 1 : 0 /* arg1 */, uid /* arg2 */,
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 589b8f18b1a5..4da84006ea64 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1126,6 +1126,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@Override public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
};
private static final class UidStateCallbackInfo {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 25fe0007ec4b..d02402097040 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -593,6 +593,9 @@ public class ShortcutService extends IShortcutService.Stub {
@Override public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
};
void handleOnUidStateChanged(int uid, int procState) {
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 8755662ac813..dfa12814a138 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -256,6 +256,10 @@ public final class HintManagerService extends SystemService {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index e9535e0a56e1..bedb9f0528c6 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -700,5 +700,9 @@ final class VibrationSettings {
@Override
public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override
+ public void onUidProcAdjChanged(int uid) {
+ }
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 366ab0968bb8..0e5c94f0227a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -599,6 +599,9 @@ public class UsageStatsService extends SystemService implements
@Override public void onUidCachedChanged(int uid, boolean cached) {
}
+
+ @Override public void onUidProcAdjChanged(int uid) {
+ }
};
@Override