Merge "Delay freezing for given duration through broadcast options" into udc-dev

This commit is contained in:
Amith Yamasani
2023-05-16 16:39:00 +00:00
committed by Android (Google) Code Review
4 changed files with 80 additions and 8 deletions

View File

@@ -97,6 +97,15 @@ public class PowerExemptionManager {
*/ */
public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; 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. * The list of temp allow list types.
* @hide * @hide
@@ -105,6 +114,7 @@ public class PowerExemptionManager {
TEMPORARY_ALLOW_LIST_TYPE_NONE, TEMPORARY_ALLOW_LIST_TYPE_NONE,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface TempAllowListType {} public @interface TempAllowListType {}
@@ -216,6 +226,11 @@ public class PowerExemptionManager {
* Set temp-allow-list for transferring accounts between users. * Set temp-allow-list for transferring accounts between users.
*/ */
public static final int REASON_ACCOUNT_TRANSFER = 104; 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 */ /* Reason code range 200-299 are reserved for broadcast actions */
/** /**
@@ -449,6 +464,7 @@ public class PowerExemptionManager {
REASON_PUSH_MESSAGING_OVER_QUOTA, REASON_PUSH_MESSAGING_OVER_QUOTA,
REASON_ACTIVITY_RECOGNITION, REASON_ACTIVITY_RECOGNITION,
REASON_ACCOUNT_TRANSFER, REASON_ACCOUNT_TRANSFER,
REASON_PUSH_MESSAGING_DEFERRABLE,
REASON_BOOT_COMPLETED, REASON_BOOT_COMPLETED,
REASON_PRE_BOOT_COMPLETED, REASON_PRE_BOOT_COMPLETED,
REASON_LOCKED_BOOT_COMPLETED, REASON_LOCKED_BOOT_COMPLETED,
@@ -781,6 +797,8 @@ public class PowerExemptionManager {
return "ACTIVITY_RECOGNITION"; return "ACTIVITY_RECOGNITION";
case REASON_ACCOUNT_TRANSFER: case REASON_ACCOUNT_TRANSFER:
return "REASON_ACCOUNT_TRANSFER"; return "REASON_ACCOUNT_TRANSFER";
case REASON_PUSH_MESSAGING_DEFERRABLE:
return "PUSH_MESSAGING_DEFERRABLE";
case REASON_BOOT_COMPLETED: case REASON_BOOT_COMPLETED:
return "BOOT_COMPLETED"; return "BOOT_COMPLETED";
case REASON_PRE_BOOT_COMPLETED: case REASON_PRE_BOOT_COMPLETED:

View File

@@ -62,6 +62,7 @@ import android.os.Bundle;
import android.os.BundleMerger; import android.os.BundleMerger;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.PowerExemptionManager;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
@@ -878,13 +879,21 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
mLocalHandler.sendMessageDelayed( mLocalHandler.sendMessageDelayed(
Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout); Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout);
} }
if (r.options != null && r.options.getTemporaryAppAllowlistDuration() > 0) { 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, mService.tempAllowlistUidLocked(queue.uid,
r.options.getTemporaryAppAllowlistDuration(), r.options.getTemporaryAppAllowlistDuration(),
r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(), r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(),
r.options.getTemporaryAppAllowlistType(), r.callingUid); r.options.getTemporaryAppAllowlistType(), r.callingUid);
} }
}
if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app); if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app);
setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED, setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED,

View File

@@ -47,6 +47,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.UptimeMillisLong;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerInternal.OomAdjReason; import android.app.ActivityManagerInternal.OomAdjReason;
import android.app.ActivityThread; import android.app.ActivityThread;
@@ -1278,14 +1279,35 @@ public final class CachedAppOptimizer {
return true; 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. // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout.
@GuardedBy("mAm") @GuardedBy("mAm")
void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason) { 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) { if (mUseFreezer) {
synchronized (mProcLock) { synchronized (mProcLock) {
// Move the earliest freezable time further, if necessary
final long delay = updateEarliestFreezableTime(app, delayMillis);
if (app.mOptRecord.isFrozen() || app.mOptRecord.isPendingFreeze()) { if (app.mOptRecord.isFrozen() || app.mOptRecord.isPendingFreeze()) {
unfreezeAppLSP(app, reason); unfreezeAppLSP(app, reason);
freezeAppAsyncLSP(app); freezeAppAsyncLSP(app, delay);
} }
} }
} }
@@ -1293,11 +1315,17 @@ public final class CachedAppOptimizer {
@GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"})
void freezeAppAsyncLSP(ProcessRecord app) { void freezeAppAsyncLSP(ProcessRecord app) {
freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false); freezeAppAsyncLSP(app, updateEarliestFreezableTime(app, mFreezerDebounceTimeout));
} }
@GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"})
void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) { private void freezeAppAsyncLSP(ProcessRecord app, @UptimeMillisLong long delayMillis) {
freezeAppAsyncInternalLSP(app, delayMillis, false);
}
@GuardedBy({"mAm", "mProcLock"})
void freezeAppAsyncInternalLSP(ProcessRecord app, @UptimeMillisLong long delayMillis,
boolean force) {
final ProcessCachedOptimizerRecord opt = app.mOptRecord; final ProcessCachedOptimizerRecord opt = app.mOptRecord;
if (opt.isPendingFreeze()) { if (opt.isPendingFreeze()) {
// Skip redundant DO_FREEZE message // Skip redundant DO_FREEZE message

View File

@@ -16,6 +16,7 @@
package com.android.server.am; package com.android.server.am;
import android.annotation.UptimeMillisLong;
import android.app.ActivityManagerInternal.OomAdjReason; import android.app.ActivityManagerInternal.OomAdjReason;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
@@ -119,6 +120,12 @@ final class ProcessCachedOptimizerRecord {
@GuardedBy("mProcLock") @GuardedBy("mProcLock")
private boolean mPendingFreeze; 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") @GuardedBy("mProcLock")
long getLastCompactTime() { long getLastCompactTime() {
return mLastCompactTime; return mLastCompactTime;
@@ -263,6 +270,16 @@ final class ProcessCachedOptimizerRecord {
mShouldNotFreeze = shouldNotFreeze; mShouldNotFreeze = shouldNotFreeze;
} }
@GuardedBy("mProcLock")
@UptimeMillisLong long getEarliestFreezableTime() {
return mEarliestFreezableTimeMillis;
}
@GuardedBy("mProcLock")
void setEarliestFreezableTime(@UptimeMillisLong long earliestFreezableTimeMillis) {
mEarliestFreezableTimeMillis = earliestFreezableTimeMillis;
}
@GuardedBy("mProcLock") @GuardedBy("mProcLock")
boolean isFreezeExempt() { boolean isFreezeExempt() {
return mFreezeExempt; return mFreezeExempt;