diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 65b670bcc41e9..4b9fed220dab3 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -4987,9 +4987,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - // TODO: make BroadcastInterceptingContext use the Handler passed in to registerReceiver - // and put this back. - // ensureRunningOnConnectivityServiceThread(); + ensureRunningOnConnectivityServiceThread(); final String action = intent.getAction(); final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 3c4abde380252..abe06c543a776 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -1300,10 +1300,8 @@ public class ConnectivityServiceTest { } private void processBroadcastForVpn(Intent intent) { - // The BroadcastReceiver for this broadcast checks it is being run on the handler thread. - final Handler handler = new Handler(mVMSHandlerThread.getLooper()); - handler.post(() -> mServiceContext.sendBroadcast(intent)); - HandlerUtils.waitForIdle(handler, TIMEOUT_MS); + mServiceContext.sendBroadcast(intent); + HandlerUtils.waitForIdle(mVMSHandlerThread, TIMEOUT_MS); waitForIdle(); } @@ -1430,6 +1428,7 @@ public class ConnectivityServiceTest { FakeSettingsProvider.clearSettingsProvider(); mServiceContext = new MockContext(InstrumentationRegistry.getContext(), new FakeSettingsProvider()); + mServiceContext.setUseRegisteredHandlers(true); LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); LocalServices.addService( NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class)); diff --git a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java index 1102624da0310..4a1f96d145bd0 100644 --- a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java +++ b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java @@ -42,6 +42,8 @@ public class BroadcastInterceptingContext extends ContextWrapper { private final List mInterceptors = new ArrayList<>(); + private boolean mUseRegisteredHandlers; + public abstract class FutureIntent extends FutureTask { public FutureIntent() { super( @@ -61,17 +63,24 @@ public class BroadcastInterceptingContext extends ContextWrapper { public class BroadcastInterceptor extends FutureIntent { private final BroadcastReceiver mReceiver; private final IntentFilter mFilter; + private final Handler mHandler; - public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) { + public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter, + Handler handler) { mReceiver = receiver; mFilter = filter; + mHandler = mUseRegisteredHandlers ? handler : null; } public boolean dispatchBroadcast(Intent intent) { if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) { if (mReceiver != null) { final Context context = BroadcastInterceptingContext.this; - mReceiver.onReceive(context, intent); + if (mHandler == null) { + mReceiver.onReceive(context, intent); + } else { + mHandler.post(() -> mReceiver.onReceive(context, intent)); + } return false; } else { set(intent); @@ -116,25 +125,38 @@ public class BroadcastInterceptingContext extends ContextWrapper { } public FutureIntent nextBroadcastIntent(IntentFilter filter) { - final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter); + final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter, null); synchronized (mInterceptors) { mInterceptors.add(interceptor); } return interceptor; } + /** + * Whether to send broadcasts to registered handlers. By default, receivers are called + * synchronously by sendBroadcast. If this method is called with {@code true}, the receiver is + * instead called by a runnable posted to the Handler specified when the receiver was + * registered. This method applies only to future registrations, already-registered receivers + * are unaffected. + */ + public void setUseRegisteredHandlers(boolean use) { + synchronized (mInterceptors) { + mUseRegisteredHandlers = use; + } + } + @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { - synchronized (mInterceptors) { - mInterceptors.add(new BroadcastInterceptor(receiver, filter)); - } - return null; + return registerReceiver(receiver, filter, null, null); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { - return registerReceiver(receiver, filter); + synchronized (mInterceptors) { + mInterceptors.add(new BroadcastInterceptor(receiver, filter, scheduler)); + } + return null; } @Override