Loading core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -11946,6 +11946,7 @@ public final class Settings { * bcast_deferral (long) * bcast_deferral_decay_factor (float) * bcast_deferral_floor (long) * bcast_allow_bg_activity_start_timeout (long) * </pre> * * @hide Loading services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -15039,7 +15039,7 @@ public class ActivityManagerService extends IActivityManager.Stub oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, oldRecord.intent, Activity.RESULT_CANCELED, null, null, false, false, oldRecord.userId, oldRecord); false, false, oldRecord.userId); } catch (RemoteException e) { Slog.w(TAG, "Failure [" + queue.mQueueName + "] sending broadcast result of " services/core/java/com/android/server/am/BroadcastConstants.java +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public class BroadcastConstants { static final String KEY_DEFERRAL = "bcast_deferral"; static final String KEY_DEFERRAL_DECAY_FACTOR = "bcast_deferral_decay_factor"; static final String KEY_DEFERRAL_FLOOR = "bcast_deferral_floor"; static final String KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT = "bcast_allow_bg_activity_start_timeout"; // All time intervals are in milliseconds private static final long DEFAULT_TIMEOUT = 10_000; Loading @@ -45,6 +47,7 @@ public class BroadcastConstants { private static final long DEFAULT_DEFERRAL = 5_000; private static final float DEFAULT_DEFERRAL_DECAY_FACTOR = 0.75f; private static final long DEFAULT_DEFERRAL_FLOOR = 0; private static final long DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT = 10_000; // All time constants are in milliseconds Loading @@ -59,6 +62,8 @@ public class BroadcastConstants { public float DEFERRAL_DECAY_FACTOR = DEFAULT_DEFERRAL_DECAY_FACTOR; // Minimum that the deferral time can decay to until the backlog fully clears public long DEFERRAL_FLOOR = DEFAULT_DEFERRAL_FLOOR; // For how long after a whitelisted receiver's start its process can start a background activity public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT; // Settings override tracking for this instance private String mSettingsKey; Loading Loading @@ -113,6 +118,8 @@ public class BroadcastConstants { DEFERRAL_DECAY_FACTOR = mParser.getFloat(KEY_DEFERRAL_DECAY_FACTOR, DEFERRAL_DECAY_FACTOR); DEFERRAL_FLOOR = mParser.getLong(KEY_DEFERRAL_FLOOR, DEFERRAL_FLOOR); ALLOW_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT, ALLOW_BG_ACTIVITY_START_TIMEOUT); } } Loading Loading @@ -145,6 +152,9 @@ public class BroadcastConstants { pw.print(" "); pw.print(KEY_DEFERRAL_FLOOR); pw.print(" = "); TimeUtils.formatDuration(DEFERRAL_FLOOR, pw); pw.print(" "); pw.print(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT); pw.print(" = "); TimeUtils.formatDuration(ALLOW_BG_ACTIVITY_START_TIMEOUT, pw); pw.println(); } } Loading services/core/java/com/android/server/am/BroadcastQueue.java +43 −20 Original line number Diff line number Diff line Loading @@ -74,9 +74,6 @@ public final class BroadcastQueue { static final int MAX_BROADCAST_SUMMARY_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 25 : 300; // For how long after a whitelisted receiver's start its process can start a background activity private static final int RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS = 10_000; final ActivityManagerService mService; /** Loading Loading @@ -310,9 +307,6 @@ public final class BroadcastQueue { r.curApp = app; app.curReceivers.add(r); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); if (r.allowBackgroundActivityStarts) { app.addAllowBackgroundActivityStartsToken(r); } mService.mProcessList.updateLruProcessLocked(app, false, null); if (!skipOomAdj) { mService.updateOomAdjLocked(); Loading Loading @@ -454,8 +448,25 @@ public final class BroadcastQueue { Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE"); } if (r.allowBackgroundActivityStarts && r.curApp != null) { if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) { // if the receiver has run for more than allowed bg activity start timeout, // just remove the token for this process now and we're done r.curApp.removeAllowBackgroundActivityStartsToken(r); } else { // the receiver had run for less than allowed bg activity start timeout, // so allow the process to still start activities from bg for some more time String msgToken = (r.curApp.toShortString() + r.toString()).intern(); // first, if there exists a past scheduled request to remove this token, drop // that request - we don't want the token to be swept from under our feet... mHandler.removeCallbacksAndMessages(msgToken); // ...then schedule the removal of the token after the extended timeout mHandler.postAtTime(() -> { if (r.curApp != null) { r.curApp.removeAllowBackgroundActivityStartsToken(r); } }, msgToken, (r.receiverTime + mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT)); } } // If we're abandoning this broadcast before any receivers were actually spun up, // nextReceiver is zero; in which case time-to-process bookkeeping doesn't apply. if (r.nextReceiver > 0) { Loading Loading @@ -554,7 +565,7 @@ public final class BroadcastQueue { void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser, BroadcastRecord br) boolean ordered, boolean sticky, int sendingUser) throws RemoteException { // Send the intent to the receiver asynchronously using one-way binder calls. if (app != null) { Loading @@ -562,15 +573,6 @@ public final class BroadcastQueue { // If we have an app thread, do the call through that so it is // correctly ordered with other one-way calls. try { if (br.allowBackgroundActivityStarts) { app.addAllowBackgroundActivityStartsToken(br); // schedule removal of the whitelisting token after the timeout mHandler.postDelayed(() -> { if (app != null) { app.removeAllowBackgroundActivityStartsToken(br); } }, RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS); } app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.getReportedProcState()); // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting Loading Loading @@ -794,9 +796,13 @@ public final class BroadcastQueue { skipReceiverLocked(r); } } else { if (r.receiverTime == 0) { r.receiverTime = SystemClock.uptimeMillis(); } maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r); performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, r.ordered, r.initialSticky, r.userId, r); r.resultExtras, r.ordered, r.initialSticky, r.userId); } if (ordered) { r.state = BroadcastRecord.CALL_DONE_RECEIVE; Loading Loading @@ -1100,7 +1106,7 @@ public final class BroadcastQueue { } performReceiveLocked(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, false, false, r.userId, r); r.resultData, r.resultExtras, false, false, r.userId); // Set this to null so that the reference // (local and remote) isn't kept in the mBroadcastHistory. r.resultTo = null; Loading Loading @@ -1255,6 +1261,9 @@ public final class BroadcastQueue { r.state = BroadcastRecord.IDLE; scheduleBroadcastsLocked(); } else { if (filter.receiverList != null) { maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r); } if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { scheduleTempWhitelistLocked(filter.owningUid, brOptions.getTemporaryAppWhitelistDuration(), r); Loading Loading @@ -1561,6 +1570,7 @@ public final class BroadcastQueue { try { app.addPackage(info.activityInfo.packageName, info.activityInfo.applicationInfo.versionCode, mService.mProcessStats); maybeAddAllowBackgroundActivityStartsToken(app, r); processCurBroadcastLocked(r, app, skipOomAdj); return; } catch (RemoteException e) { Loading Loading @@ -1611,10 +1621,23 @@ public final class BroadcastQueue { return; } maybeAddAllowBackgroundActivityStartsToken(r.curApp, r); mPendingBroadcast = r; mPendingBroadcastRecvIndex = recIdx; } private void maybeAddAllowBackgroundActivityStartsToken(ProcessRecord proc, BroadcastRecord r) { if (r == null || proc == null || !r.allowBackgroundActivityStarts) { return; } String msgToken = (proc.toShortString() + r.toString()).intern(); // first, if there exists a past scheduled request to remove this token, drop // that request - we don't want the token to be swept from under our feet... mHandler.removeCallbacksAndMessages(msgToken); // ...then add the token proc.addAllowBackgroundActivityStartsToken(r); } final void setBroadcastTimeoutLocked(long timeoutTime) { if (! mPendingBroadcastTimeoutMessage) { Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this); Loading Loading
core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -11946,6 +11946,7 @@ public final class Settings { * bcast_deferral (long) * bcast_deferral_decay_factor (float) * bcast_deferral_floor (long) * bcast_allow_bg_activity_start_timeout (long) * </pre> * * @hide Loading
services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -15039,7 +15039,7 @@ public class ActivityManagerService extends IActivityManager.Stub oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, oldRecord.intent, Activity.RESULT_CANCELED, null, null, false, false, oldRecord.userId, oldRecord); false, false, oldRecord.userId); } catch (RemoteException e) { Slog.w(TAG, "Failure [" + queue.mQueueName + "] sending broadcast result of "
services/core/java/com/android/server/am/BroadcastConstants.java +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public class BroadcastConstants { static final String KEY_DEFERRAL = "bcast_deferral"; static final String KEY_DEFERRAL_DECAY_FACTOR = "bcast_deferral_decay_factor"; static final String KEY_DEFERRAL_FLOOR = "bcast_deferral_floor"; static final String KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT = "bcast_allow_bg_activity_start_timeout"; // All time intervals are in milliseconds private static final long DEFAULT_TIMEOUT = 10_000; Loading @@ -45,6 +47,7 @@ public class BroadcastConstants { private static final long DEFAULT_DEFERRAL = 5_000; private static final float DEFAULT_DEFERRAL_DECAY_FACTOR = 0.75f; private static final long DEFAULT_DEFERRAL_FLOOR = 0; private static final long DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT = 10_000; // All time constants are in milliseconds Loading @@ -59,6 +62,8 @@ public class BroadcastConstants { public float DEFERRAL_DECAY_FACTOR = DEFAULT_DEFERRAL_DECAY_FACTOR; // Minimum that the deferral time can decay to until the backlog fully clears public long DEFERRAL_FLOOR = DEFAULT_DEFERRAL_FLOOR; // For how long after a whitelisted receiver's start its process can start a background activity public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT; // Settings override tracking for this instance private String mSettingsKey; Loading Loading @@ -113,6 +118,8 @@ public class BroadcastConstants { DEFERRAL_DECAY_FACTOR = mParser.getFloat(KEY_DEFERRAL_DECAY_FACTOR, DEFERRAL_DECAY_FACTOR); DEFERRAL_FLOOR = mParser.getLong(KEY_DEFERRAL_FLOOR, DEFERRAL_FLOOR); ALLOW_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT, ALLOW_BG_ACTIVITY_START_TIMEOUT); } } Loading Loading @@ -145,6 +152,9 @@ public class BroadcastConstants { pw.print(" "); pw.print(KEY_DEFERRAL_FLOOR); pw.print(" = "); TimeUtils.formatDuration(DEFERRAL_FLOOR, pw); pw.print(" "); pw.print(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT); pw.print(" = "); TimeUtils.formatDuration(ALLOW_BG_ACTIVITY_START_TIMEOUT, pw); pw.println(); } } Loading
services/core/java/com/android/server/am/BroadcastQueue.java +43 −20 Original line number Diff line number Diff line Loading @@ -74,9 +74,6 @@ public final class BroadcastQueue { static final int MAX_BROADCAST_SUMMARY_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 25 : 300; // For how long after a whitelisted receiver's start its process can start a background activity private static final int RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS = 10_000; final ActivityManagerService mService; /** Loading Loading @@ -310,9 +307,6 @@ public final class BroadcastQueue { r.curApp = app; app.curReceivers.add(r); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); if (r.allowBackgroundActivityStarts) { app.addAllowBackgroundActivityStartsToken(r); } mService.mProcessList.updateLruProcessLocked(app, false, null); if (!skipOomAdj) { mService.updateOomAdjLocked(); Loading Loading @@ -454,8 +448,25 @@ public final class BroadcastQueue { Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE"); } if (r.allowBackgroundActivityStarts && r.curApp != null) { if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) { // if the receiver has run for more than allowed bg activity start timeout, // just remove the token for this process now and we're done r.curApp.removeAllowBackgroundActivityStartsToken(r); } else { // the receiver had run for less than allowed bg activity start timeout, // so allow the process to still start activities from bg for some more time String msgToken = (r.curApp.toShortString() + r.toString()).intern(); // first, if there exists a past scheduled request to remove this token, drop // that request - we don't want the token to be swept from under our feet... mHandler.removeCallbacksAndMessages(msgToken); // ...then schedule the removal of the token after the extended timeout mHandler.postAtTime(() -> { if (r.curApp != null) { r.curApp.removeAllowBackgroundActivityStartsToken(r); } }, msgToken, (r.receiverTime + mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT)); } } // If we're abandoning this broadcast before any receivers were actually spun up, // nextReceiver is zero; in which case time-to-process bookkeeping doesn't apply. if (r.nextReceiver > 0) { Loading Loading @@ -554,7 +565,7 @@ public final class BroadcastQueue { void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser, BroadcastRecord br) boolean ordered, boolean sticky, int sendingUser) throws RemoteException { // Send the intent to the receiver asynchronously using one-way binder calls. if (app != null) { Loading @@ -562,15 +573,6 @@ public final class BroadcastQueue { // If we have an app thread, do the call through that so it is // correctly ordered with other one-way calls. try { if (br.allowBackgroundActivityStarts) { app.addAllowBackgroundActivityStartsToken(br); // schedule removal of the whitelisting token after the timeout mHandler.postDelayed(() -> { if (app != null) { app.removeAllowBackgroundActivityStartsToken(br); } }, RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS); } app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.getReportedProcState()); // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting Loading Loading @@ -794,9 +796,13 @@ public final class BroadcastQueue { skipReceiverLocked(r); } } else { if (r.receiverTime == 0) { r.receiverTime = SystemClock.uptimeMillis(); } maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r); performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, r.ordered, r.initialSticky, r.userId, r); r.resultExtras, r.ordered, r.initialSticky, r.userId); } if (ordered) { r.state = BroadcastRecord.CALL_DONE_RECEIVE; Loading Loading @@ -1100,7 +1106,7 @@ public final class BroadcastQueue { } performReceiveLocked(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, false, false, r.userId, r); r.resultData, r.resultExtras, false, false, r.userId); // Set this to null so that the reference // (local and remote) isn't kept in the mBroadcastHistory. r.resultTo = null; Loading Loading @@ -1255,6 +1261,9 @@ public final class BroadcastQueue { r.state = BroadcastRecord.IDLE; scheduleBroadcastsLocked(); } else { if (filter.receiverList != null) { maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r); } if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { scheduleTempWhitelistLocked(filter.owningUid, brOptions.getTemporaryAppWhitelistDuration(), r); Loading Loading @@ -1561,6 +1570,7 @@ public final class BroadcastQueue { try { app.addPackage(info.activityInfo.packageName, info.activityInfo.applicationInfo.versionCode, mService.mProcessStats); maybeAddAllowBackgroundActivityStartsToken(app, r); processCurBroadcastLocked(r, app, skipOomAdj); return; } catch (RemoteException e) { Loading Loading @@ -1611,10 +1621,23 @@ public final class BroadcastQueue { return; } maybeAddAllowBackgroundActivityStartsToken(r.curApp, r); mPendingBroadcast = r; mPendingBroadcastRecvIndex = recIdx; } private void maybeAddAllowBackgroundActivityStartsToken(ProcessRecord proc, BroadcastRecord r) { if (r == null || proc == null || !r.allowBackgroundActivityStarts) { return; } String msgToken = (proc.toShortString() + r.toString()).intern(); // first, if there exists a past scheduled request to remove this token, drop // that request - we don't want the token to be swept from under our feet... mHandler.removeCallbacksAndMessages(msgToken); // ...then add the token proc.addAllowBackgroundActivityStartsToken(r); } final void setBroadcastTimeoutLocked(long timeoutTime) { if (! mPendingBroadcastTimeoutMessage) { Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this); Loading