Merge "Delay freezing for given duration through broadcast options" into udc-dev am: 66c81a3e04
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23202723 Change-Id: I09782cdfcb0566025496da9f2c440d5b8b452331 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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,12 +879,20 @@ 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) {
|
||||||
mService.tempAllowlistUidLocked(queue.uid,
|
if (r.options.getTemporaryAppAllowlistType()
|
||||||
r.options.getTemporaryAppAllowlistDuration(),
|
== PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) {
|
||||||
r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(),
|
// Only delay freezer, don't add to any temp allowlist
|
||||||
r.options.getTemporaryAppAllowlistType(), r.callingUid);
|
// 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);
|
if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user