diff options
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 |