Deliver DEVICE_IDLE_MODE_CHANGED broadcasts as non-ordered.

They are currently being sent as ordered in order to receive
the finish callback. Since the modern broadcast queue supports
a finish callback with the need for the broadcasts to be ordered,
don't send these broadcasts as ordered anymore.

Bug: 256597397
Bug: 256597171
Bug: 253226131
Test: treehugger
Change-Id: I00a0dec0df99892b2d0f4a023efcc965a2061379
This commit is contained in:
Sudheer Shanka
2022-11-02 10:50:41 -07:00
parent d38145cf94
commit c7e66035bb
3 changed files with 41 additions and 6 deletions

View File

@@ -31,6 +31,7 @@ import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
@@ -740,8 +741,10 @@ public class DeviceIdleController extends SystemService
}
};
private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
private final IIntentReceiver mIdleStartedDoneReceiver = new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) {
// When coming out of a deep idle, we will add in some delay before we allow
// the system to settle down and finish the maintenance window. This is
// to give a chance for any pending work to be scheduled.
@@ -1816,13 +1819,15 @@ public class DeviceIdleController extends SystemService
}
if (deepChanged) {
incActiveIdleOps();
getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
null, mIdleStartedDoneReceiver, null, 0, null, null);
mLocalActivityManager.broadcastIntentWithCallback(mIdleIntent,
mIdleStartedDoneReceiver, null, UserHandle.USER_ALL,
null, null, null);
}
if (lightChanged) {
incActiveIdleOps();
getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
null, mIdleStartedDoneReceiver, null, 0, null, null);
mLocalActivityManager.broadcastIntentWithCallback(mLightIdleIntent,
mIdleStartedDoneReceiver, null, UserHandle.USER_ALL,
null, null, null);
}
// Always start with one active op for the message being sent here.
// Now we are done!

View File

@@ -639,6 +639,8 @@ public abstract class ActivityManagerInternal {
* using the rules of package visibility. Returns extras with legitimate package info that the
* receiver is able to access, or {@code null} if none of the packages is visible to the
* receiver.
* @param serialized Specifies whether or not the broadcast should be delivered to the
* receivers in a serial order.
*
* @see com.android.server.am.ActivityManagerService#broadcastIntentWithFeature(
* IApplicationThread, String, Intent, String, IIntentReceiver, int, String, Bundle,
@@ -651,6 +653,19 @@ public abstract class ActivityManagerInternal {
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
@Nullable Bundle bOptions);
/**
* Variant of
* {@link #broadcastIntent(Intent, IIntentReceiver, String[], boolean, int, int[], BiFunction, Bundle)}
* that allows sender to receive a finish callback once the broadcast delivery is completed,
* but provides no ordering guarantee for how the broadcast is delivered to receivers.
*/
public abstract int broadcastIntentWithCallback(Intent intent,
IIntentReceiver resultTo,
String[] requiredPermissions,
int userId, int[] appIdAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
@Nullable Bundle bOptions);
/**
* Add uid to the ActivityManagerService PendingStartActivityUids list.
* @param uid uid

View File

@@ -17327,6 +17327,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
public int broadcastIntentWithCallback(Intent intent,
IIntentReceiver resultTo,
String[] requiredPermissions,
int userId, int[] appIdAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
@Nullable Bundle bOptions) {
// Sending broadcasts with a finish callback without the need for the broadcasts
// delivery to be serialized is only supported by modern queue. So, when modern
// queue is disabled, we continue to send broadcasts in a serialized fashion.
final boolean serialized = !isModernQueueEnabled();
return broadcastIntent(intent, resultTo, requiredPermissions, serialized, userId,
appIdAllowList, filterExtrasForReceiver, bOptions);
}
@Override
public ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
boolean fgRequired, String callingPackage, @Nullable String callingFeatureId,