Loading apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,15 @@ public class PowerExemptionManager { */ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; /** * Delay freezing the app when the broadcast is delivered. This flag is not required if * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED or * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED are specified, as those will * already defer freezing during the allowlist duration. * @hide temporarily until the next release */ public static final int TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED = 1 << 2; /** * The list of temp allow list types. * @hide Loading @@ -105,6 +114,7 @@ public class PowerExemptionManager { TEMPORARY_ALLOW_LIST_TYPE_NONE, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED }) @Retention(RetentionPolicy.SOURCE) public @interface TempAllowListType {} Loading Loading @@ -216,6 +226,11 @@ public class PowerExemptionManager { * Set temp-allow-list for transferring accounts between users. */ public static final int REASON_ACCOUNT_TRANSFER = 104; /** * Set temp-allow-list for server push messaging that can be deferred. * @hide temporarily until the next release */ public static final int REASON_PUSH_MESSAGING_DEFERRABLE = 105; /* Reason code range 200-299 are reserved for broadcast actions */ /** Loading Loading @@ -449,6 +464,7 @@ public class PowerExemptionManager { REASON_PUSH_MESSAGING_OVER_QUOTA, REASON_ACTIVITY_RECOGNITION, REASON_ACCOUNT_TRANSFER, REASON_PUSH_MESSAGING_DEFERRABLE, REASON_BOOT_COMPLETED, REASON_PRE_BOOT_COMPLETED, REASON_LOCKED_BOOT_COMPLETED, Loading Loading @@ -781,6 +797,8 @@ public class PowerExemptionManager { return "ACTIVITY_RECOGNITION"; case REASON_ACCOUNT_TRANSFER: return "REASON_ACCOUNT_TRANSFER"; case REASON_PUSH_MESSAGING_DEFERRABLE: return "PUSH_MESSAGING_DEFERRABLE"; case REASON_BOOT_COMPLETED: return "BOOT_COMPLETED"; case REASON_PRE_BOOT_COMPLETED: Loading services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +14 −5 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.os.Bundle; import android.os.BundleMerger; import android.os.Handler; import android.os.Message; import android.os.PowerExemptionManager; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; Loading Loading @@ -878,13 +879,21 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mLocalHandler.sendMessageDelayed( Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout); } if (r.options != null && r.options.getTemporaryAppAllowlistDuration() > 0) { if (r.options.getTemporaryAppAllowlistType() == PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) { // Only delay freezer, don't add to any temp allowlist // TODO: Add a unit test mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app, CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER, r.options.getTemporaryAppAllowlistDuration()); } else { mService.tempAllowlistUidLocked(queue.uid, r.options.getTemporaryAppAllowlistDuration(), r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(), r.options.getTemporaryAppAllowlistType(), r.callingUid); } } if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app); setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED, Loading services/core/java/com/android/server/am/CachedAppOptimizer.java +31 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.annotation.IntDef; import android.annotation.UptimeMillisLong; import android.app.ActivityManager; import android.app.ActivityManagerInternal.OomAdjReason; import android.app.ActivityThread; Loading Loading @@ -1278,14 +1279,35 @@ public final class CachedAppOptimizer { return true; } /** * Returns the earliest time (relative) from now that the app can be frozen. * @param app The app to update * @param delayMillis How much to delay freezing by */ @GuardedBy("mProcLock") private long updateEarliestFreezableTime(ProcessRecord app, long delayMillis) { final long now = SystemClock.uptimeMillis(); app.mOptRecord.setEarliestFreezableTime( Math.max(app.mOptRecord.getEarliestFreezableTime(), now + delayMillis)); return app.mOptRecord.getEarliestFreezableTime() - now; } // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout. @GuardedBy("mAm") void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason) { unfreezeTemporarily(app, reason, mFreezerDebounceTimeout); } // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout. @GuardedBy("mAm") void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason, long delayMillis) { if (mUseFreezer) { synchronized (mProcLock) { // Move the earliest freezable time further, if necessary final long delay = updateEarliestFreezableTime(app, delayMillis); if (app.mOptRecord.isFrozen() || app.mOptRecord.isPendingFreeze()) { unfreezeAppLSP(app, reason); freezeAppAsyncLSP(app); freezeAppAsyncLSP(app, delay); } } } Loading @@ -1293,11 +1315,17 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncLSP(ProcessRecord app) { freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false); freezeAppAsyncLSP(app, updateEarliestFreezableTime(app, mFreezerDebounceTimeout)); } @GuardedBy({"mAm", "mProcLock"}) private void freezeAppAsyncLSP(ProcessRecord app, @UptimeMillisLong long delayMillis) { freezeAppAsyncInternalLSP(app, delayMillis, false); } @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) { void freezeAppAsyncInternalLSP(ProcessRecord app, @UptimeMillisLong long delayMillis, boolean force) { final ProcessCachedOptimizerRecord opt = app.mOptRecord; if (opt.isPendingFreeze()) { // Skip redundant DO_FREEZE message Loading services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.am; import android.annotation.UptimeMillisLong; import android.app.ActivityManagerInternal.OomAdjReason; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -119,6 +120,12 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") private boolean mPendingFreeze; /** * This is the soonest the process can be allowed to freeze, in uptime millis */ @GuardedBy("mProcLock") private @UptimeMillisLong long mEarliestFreezableTimeMillis; @GuardedBy("mProcLock") long getLastCompactTime() { return mLastCompactTime; Loading Loading @@ -263,6 +270,16 @@ final class ProcessCachedOptimizerRecord { mShouldNotFreeze = shouldNotFreeze; } @GuardedBy("mProcLock") @UptimeMillisLong long getEarliestFreezableTime() { return mEarliestFreezableTimeMillis; } @GuardedBy("mProcLock") void setEarliestFreezableTime(@UptimeMillisLong long earliestFreezableTimeMillis) { mEarliestFreezableTimeMillis = earliestFreezableTimeMillis; } @GuardedBy("mProcLock") boolean isFreezeExempt() { return mFreezeExempt; Loading Loading
apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,15 @@ public class PowerExemptionManager { */ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; /** * Delay freezing the app when the broadcast is delivered. This flag is not required if * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED or * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED are specified, as those will * already defer freezing during the allowlist duration. * @hide temporarily until the next release */ public static final int TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED = 1 << 2; /** * The list of temp allow list types. * @hide Loading @@ -105,6 +114,7 @@ public class PowerExemptionManager { TEMPORARY_ALLOW_LIST_TYPE_NONE, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED }) @Retention(RetentionPolicy.SOURCE) public @interface TempAllowListType {} Loading Loading @@ -216,6 +226,11 @@ public class PowerExemptionManager { * Set temp-allow-list for transferring accounts between users. */ public static final int REASON_ACCOUNT_TRANSFER = 104; /** * Set temp-allow-list for server push messaging that can be deferred. * @hide temporarily until the next release */ public static final int REASON_PUSH_MESSAGING_DEFERRABLE = 105; /* Reason code range 200-299 are reserved for broadcast actions */ /** Loading Loading @@ -449,6 +464,7 @@ public class PowerExemptionManager { REASON_PUSH_MESSAGING_OVER_QUOTA, REASON_ACTIVITY_RECOGNITION, REASON_ACCOUNT_TRANSFER, REASON_PUSH_MESSAGING_DEFERRABLE, REASON_BOOT_COMPLETED, REASON_PRE_BOOT_COMPLETED, REASON_LOCKED_BOOT_COMPLETED, Loading Loading @@ -781,6 +797,8 @@ public class PowerExemptionManager { return "ACTIVITY_RECOGNITION"; case REASON_ACCOUNT_TRANSFER: return "REASON_ACCOUNT_TRANSFER"; case REASON_PUSH_MESSAGING_DEFERRABLE: return "PUSH_MESSAGING_DEFERRABLE"; case REASON_BOOT_COMPLETED: return "BOOT_COMPLETED"; case REASON_PRE_BOOT_COMPLETED: Loading
services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +14 −5 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.os.Bundle; import android.os.BundleMerger; import android.os.Handler; import android.os.Message; import android.os.PowerExemptionManager; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; Loading Loading @@ -878,13 +879,21 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mLocalHandler.sendMessageDelayed( Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout); } if (r.options != null && r.options.getTemporaryAppAllowlistDuration() > 0) { if (r.options.getTemporaryAppAllowlistType() == PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) { // Only delay freezer, don't add to any temp allowlist // TODO: Add a unit test mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app, CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER, r.options.getTemporaryAppAllowlistDuration()); } else { mService.tempAllowlistUidLocked(queue.uid, r.options.getTemporaryAppAllowlistDuration(), r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(), r.options.getTemporaryAppAllowlistType(), r.callingUid); } } if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app); setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED, Loading
services/core/java/com/android/server/am/CachedAppOptimizer.java +31 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.annotation.IntDef; import android.annotation.UptimeMillisLong; import android.app.ActivityManager; import android.app.ActivityManagerInternal.OomAdjReason; import android.app.ActivityThread; Loading Loading @@ -1278,14 +1279,35 @@ public final class CachedAppOptimizer { return true; } /** * Returns the earliest time (relative) from now that the app can be frozen. * @param app The app to update * @param delayMillis How much to delay freezing by */ @GuardedBy("mProcLock") private long updateEarliestFreezableTime(ProcessRecord app, long delayMillis) { final long now = SystemClock.uptimeMillis(); app.mOptRecord.setEarliestFreezableTime( Math.max(app.mOptRecord.getEarliestFreezableTime(), now + delayMillis)); return app.mOptRecord.getEarliestFreezableTime() - now; } // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout. @GuardedBy("mAm") void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason) { unfreezeTemporarily(app, reason, mFreezerDebounceTimeout); } // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout. @GuardedBy("mAm") void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason, long delayMillis) { if (mUseFreezer) { synchronized (mProcLock) { // Move the earliest freezable time further, if necessary final long delay = updateEarliestFreezableTime(app, delayMillis); if (app.mOptRecord.isFrozen() || app.mOptRecord.isPendingFreeze()) { unfreezeAppLSP(app, reason); freezeAppAsyncLSP(app); freezeAppAsyncLSP(app, delay); } } } Loading @@ -1293,11 +1315,17 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncLSP(ProcessRecord app) { freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false); freezeAppAsyncLSP(app, updateEarliestFreezableTime(app, mFreezerDebounceTimeout)); } @GuardedBy({"mAm", "mProcLock"}) private void freezeAppAsyncLSP(ProcessRecord app, @UptimeMillisLong long delayMillis) { freezeAppAsyncInternalLSP(app, delayMillis, false); } @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) { void freezeAppAsyncInternalLSP(ProcessRecord app, @UptimeMillisLong long delayMillis, boolean force) { final ProcessCachedOptimizerRecord opt = app.mOptRecord; if (opt.isPendingFreeze()) { // Skip redundant DO_FREEZE message Loading
services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.am; import android.annotation.UptimeMillisLong; import android.app.ActivityManagerInternal.OomAdjReason; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -119,6 +120,12 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") private boolean mPendingFreeze; /** * This is the soonest the process can be allowed to freeze, in uptime millis */ @GuardedBy("mProcLock") private @UptimeMillisLong long mEarliestFreezableTimeMillis; @GuardedBy("mProcLock") long getLastCompactTime() { return mLastCompactTime; Loading Loading @@ -263,6 +270,16 @@ final class ProcessCachedOptimizerRecord { mShouldNotFreeze = shouldNotFreeze; } @GuardedBy("mProcLock") @UptimeMillisLong long getEarliestFreezableTime() { return mEarliestFreezableTimeMillis; } @GuardedBy("mProcLock") void setEarliestFreezableTime(@UptimeMillisLong long earliestFreezableTimeMillis) { mEarliestFreezableTimeMillis = earliestFreezableTimeMillis; } @GuardedBy("mProcLock") boolean isFreezeExempt() { return mFreezeExempt; Loading