Loading core/java/android/app/ActivityManager.java +32 −0 Original line number Diff line number Diff line Loading @@ -5304,6 +5304,38 @@ public class ActivityManager { } } /** * Delays delivering broadcasts to the specified package. * * <p> When {@code delayedDurationMs} is {@code 0}, it will clears any previously * set forced delays. * * @hide */ @RequiresPermission(android.Manifest.permission.DUMP) public void forceDelayBroadcastDelivery(@NonNull String targetPackage, @IntRange(from = 0) long delayedDurationMs) { try { getService().forceDelayBroadcastDelivery(targetPackage, delayedDurationMs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Checks if the "modern" broadcast queue is enabled. * * @hide */ @RequiresPermission(android.Manifest.permission.DUMP) public boolean isModernBroadcastQueueEnabled() { try { return getService().isModernBroadcastQueueEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return The reason code of whether or not the given UID should be exempted from background * restrictions here. Loading core/java/android/app/IActivityManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -771,6 +771,14 @@ interface IActivityManager { /** Blocks until all broadcast queues become idle. */ void waitForBroadcastIdle(); /** Delays delivering broadcasts to the specified package. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") void forceDelayBroadcastDelivery(in String targetPackage, long delayedDurationMs); /** Checks if the modern broadcast queue is enabled. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") boolean isModernBroadcastQueueEnabled(); /** * @return The reason code of whether or not the given UID should be exempted from background * restrictions here. Loading services/core/java/com/android/server/am/ActivityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -18388,6 +18388,25 @@ public class ActivityManagerService extends IActivityManager.Stub } } @Override public void forceDelayBroadcastDelivery(@NonNull String targetPackage, long delayedDurationMs) { Objects.requireNonNull(targetPackage); Preconditions.checkArgumentNonnegative(delayedDurationMs); Preconditions.checkState(mEnableModernQueue, "Not valid in legacy queue"); enforceCallingPermission(permission.DUMP, "forceDelayBroadcastDelivery()"); for (BroadcastQueue queue : mBroadcastQueues) { queue.forceDelayBroadcastDelivery(targetPackage, delayedDurationMs); } } @Override public boolean isModernBroadcastQueueEnabled() { enforceCallingPermission(permission.DUMP, "isModernBroadcastQueueEnabled()"); return mEnableModernQueue; } @Override @ReasonCode public int getBackgroundRestrictionExemptionReason(int uid) { services/core/java/com/android/server/am/BroadcastProcessQueue.java +25 −3 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class BroadcastProcessQueue { private String mCachedToString; private String mCachedToShortString; /** * The duration by which any broadcasts to this process need to be delayed */ private long mForcedDelayedDurationMs; public BroadcastProcessQueue(@NonNull BroadcastConstants constants, @NonNull String processName, int uid) { this.constants = Objects.requireNonNull(constants); Loading Loading @@ -275,7 +280,7 @@ class BroadcastProcessQueue { */ @FunctionalInterface public interface BroadcastPredicate { public boolean test(@NonNull BroadcastRecord r, int index); boolean test(@NonNull BroadcastRecord r, int index); } /** Loading @@ -284,7 +289,7 @@ class BroadcastProcessQueue { */ @FunctionalInterface public interface BroadcastConsumer { public void accept(@NonNull BroadcastRecord r, int index); void accept(@NonNull BroadcastRecord r, int index); } /** Loading Loading @@ -417,6 +422,13 @@ class BroadcastProcessQueue { return mActiveViaColdStart; } /** * Get package name of the first application loaded into this process. */ public String getPackageName() { return app.getApplicationInfo().packageName; } /** * Set the currently active broadcast to the next pending broadcast. */ Loading Loading @@ -555,6 +567,10 @@ class BroadcastProcessQueue { return mActive != null; } void forceDelayBroadcastDelivery(long delayedDurationMs) { mForcedDelayedDurationMs = delayedDurationMs; } /** * Will thrown an exception if there are no pending broadcasts; relies on * {@link #isEmpty()} being false. Loading Loading @@ -729,6 +745,7 @@ class BroadcastProcessQueue { static final int REASON_BLOCKED = 4; static final int REASON_INSTRUMENTED = 5; static final int REASON_PERSISTENT = 6; static final int REASON_FORCE_DELAYED = 7; static final int REASON_CONTAINS_FOREGROUND = 10; static final int REASON_CONTAINS_ORDERED = 11; static final int REASON_CONTAINS_ALARM = 12; Loading @@ -746,6 +763,7 @@ class BroadcastProcessQueue { REASON_BLOCKED, REASON_INSTRUMENTED, REASON_PERSISTENT, REASON_FORCE_DELAYED, REASON_CONTAINS_FOREGROUND, REASON_CONTAINS_ORDERED, REASON_CONTAINS_ALARM, Loading @@ -767,6 +785,7 @@ class BroadcastProcessQueue { case REASON_BLOCKED: return "BLOCKED"; case REASON_INSTRUMENTED: return "INSTRUMENTED"; case REASON_PERSISTENT: return "PERSISTENT"; case REASON_FORCE_DELAYED: return "FORCE_DELAYED"; case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND"; case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED"; case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM"; Loading Loading @@ -810,7 +829,10 @@ class BroadcastProcessQueue { return; } if (mCountForeground > 0) { if (mForcedDelayedDurationMs > 0) { mRunnableAt = runnableAt + mForcedDelayedDurationMs; mRunnableAtReason = REASON_FORCE_DELAYED; } else if (mCountForeground > 0) { mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS; mRunnableAtReason = REASON_CONTAINS_FOREGROUND; } else if (mCountInteractive > 0) { Loading services/core/java/com/android/server/am/BroadcastQueue.java +10 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,16 @@ public abstract class BroadcastQueue { */ public abstract void waitForBarrier(@Nullable PrintWriter pw); /** * Delays delivering broadcasts to the specified package. * * <p> Note that this is only valid for modern queue. */ public void forceDelayBroadcastDelivery(@NonNull String targetPackage, long delayedDurationMs) { // No default implementation. } /** * Brief summary of internal state, useful for debugging purposes. */ Loading Loading
core/java/android/app/ActivityManager.java +32 −0 Original line number Diff line number Diff line Loading @@ -5304,6 +5304,38 @@ public class ActivityManager { } } /** * Delays delivering broadcasts to the specified package. * * <p> When {@code delayedDurationMs} is {@code 0}, it will clears any previously * set forced delays. * * @hide */ @RequiresPermission(android.Manifest.permission.DUMP) public void forceDelayBroadcastDelivery(@NonNull String targetPackage, @IntRange(from = 0) long delayedDurationMs) { try { getService().forceDelayBroadcastDelivery(targetPackage, delayedDurationMs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Checks if the "modern" broadcast queue is enabled. * * @hide */ @RequiresPermission(android.Manifest.permission.DUMP) public boolean isModernBroadcastQueueEnabled() { try { return getService().isModernBroadcastQueueEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return The reason code of whether or not the given UID should be exempted from background * restrictions here. Loading
core/java/android/app/IActivityManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -771,6 +771,14 @@ interface IActivityManager { /** Blocks until all broadcast queues become idle. */ void waitForBroadcastIdle(); /** Delays delivering broadcasts to the specified package. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") void forceDelayBroadcastDelivery(in String targetPackage, long delayedDurationMs); /** Checks if the modern broadcast queue is enabled. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") boolean isModernBroadcastQueueEnabled(); /** * @return The reason code of whether or not the given UID should be exempted from background * restrictions here. Loading
services/core/java/com/android/server/am/ActivityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -18388,6 +18388,25 @@ public class ActivityManagerService extends IActivityManager.Stub } } @Override public void forceDelayBroadcastDelivery(@NonNull String targetPackage, long delayedDurationMs) { Objects.requireNonNull(targetPackage); Preconditions.checkArgumentNonnegative(delayedDurationMs); Preconditions.checkState(mEnableModernQueue, "Not valid in legacy queue"); enforceCallingPermission(permission.DUMP, "forceDelayBroadcastDelivery()"); for (BroadcastQueue queue : mBroadcastQueues) { queue.forceDelayBroadcastDelivery(targetPackage, delayedDurationMs); } } @Override public boolean isModernBroadcastQueueEnabled() { enforceCallingPermission(permission.DUMP, "isModernBroadcastQueueEnabled()"); return mEnableModernQueue; } @Override @ReasonCode public int getBackgroundRestrictionExemptionReason(int uid) {
services/core/java/com/android/server/am/BroadcastProcessQueue.java +25 −3 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class BroadcastProcessQueue { private String mCachedToString; private String mCachedToShortString; /** * The duration by which any broadcasts to this process need to be delayed */ private long mForcedDelayedDurationMs; public BroadcastProcessQueue(@NonNull BroadcastConstants constants, @NonNull String processName, int uid) { this.constants = Objects.requireNonNull(constants); Loading Loading @@ -275,7 +280,7 @@ class BroadcastProcessQueue { */ @FunctionalInterface public interface BroadcastPredicate { public boolean test(@NonNull BroadcastRecord r, int index); boolean test(@NonNull BroadcastRecord r, int index); } /** Loading @@ -284,7 +289,7 @@ class BroadcastProcessQueue { */ @FunctionalInterface public interface BroadcastConsumer { public void accept(@NonNull BroadcastRecord r, int index); void accept(@NonNull BroadcastRecord r, int index); } /** Loading Loading @@ -417,6 +422,13 @@ class BroadcastProcessQueue { return mActiveViaColdStart; } /** * Get package name of the first application loaded into this process. */ public String getPackageName() { return app.getApplicationInfo().packageName; } /** * Set the currently active broadcast to the next pending broadcast. */ Loading Loading @@ -555,6 +567,10 @@ class BroadcastProcessQueue { return mActive != null; } void forceDelayBroadcastDelivery(long delayedDurationMs) { mForcedDelayedDurationMs = delayedDurationMs; } /** * Will thrown an exception if there are no pending broadcasts; relies on * {@link #isEmpty()} being false. Loading Loading @@ -729,6 +745,7 @@ class BroadcastProcessQueue { static final int REASON_BLOCKED = 4; static final int REASON_INSTRUMENTED = 5; static final int REASON_PERSISTENT = 6; static final int REASON_FORCE_DELAYED = 7; static final int REASON_CONTAINS_FOREGROUND = 10; static final int REASON_CONTAINS_ORDERED = 11; static final int REASON_CONTAINS_ALARM = 12; Loading @@ -746,6 +763,7 @@ class BroadcastProcessQueue { REASON_BLOCKED, REASON_INSTRUMENTED, REASON_PERSISTENT, REASON_FORCE_DELAYED, REASON_CONTAINS_FOREGROUND, REASON_CONTAINS_ORDERED, REASON_CONTAINS_ALARM, Loading @@ -767,6 +785,7 @@ class BroadcastProcessQueue { case REASON_BLOCKED: return "BLOCKED"; case REASON_INSTRUMENTED: return "INSTRUMENTED"; case REASON_PERSISTENT: return "PERSISTENT"; case REASON_FORCE_DELAYED: return "FORCE_DELAYED"; case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND"; case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED"; case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM"; Loading Loading @@ -810,7 +829,10 @@ class BroadcastProcessQueue { return; } if (mCountForeground > 0) { if (mForcedDelayedDurationMs > 0) { mRunnableAt = runnableAt + mForcedDelayedDurationMs; mRunnableAtReason = REASON_FORCE_DELAYED; } else if (mCountForeground > 0) { mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS; mRunnableAtReason = REASON_CONTAINS_FOREGROUND; } else if (mCountInteractive > 0) { Loading
services/core/java/com/android/server/am/BroadcastQueue.java +10 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,16 @@ public abstract class BroadcastQueue { */ public abstract void waitForBarrier(@Nullable PrintWriter pw); /** * Delays delivering broadcasts to the specified package. * * <p> Note that this is only valid for modern queue. */ public void forceDelayBroadcastDelivery(@NonNull String targetPackage, long delayedDurationMs) { // No default implementation. } /** * Brief summary of internal state, useful for debugging purposes. */ Loading