Merge "Do not block broadcast on handler processing" into main am: 1882368c5c

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/3213637

Change-Id: I6a6964e296f26be47e9718d50e116293be0923df
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot 2024-08-10 03:27:34 +00:00 • committed by Automerger Merge Worker
commit ebc0574326
2 changed files with 36 additions and 29 deletions

View file

@ -62,8 +62,8 @@ public class VersionedBroadcastListener {
if (DBG) Log.d(mTag, "startListening");
if (mReceiver != null) return;
mReceiver = new Receiver(mTag, mGenerationNumber, mCallback);
mContext.registerReceiver(mReceiver, mFilter, null, mHandler);
mReceiver = new Receiver(mTag, mGenerationNumber, mCallback, mHandler);
mContext.registerReceiver(mReceiver, mFilter);
}
/** Stop listening to intent broadcast. */
@ -77,30 +77,35 @@ public class VersionedBroadcastListener {
}
private static class Receiver extends BroadcastReceiver {
public final String tag;
public final AtomicInteger atomicGenerationNumber;
public final Consumer<Intent> callback;
final String mTag;
final AtomicInteger mAtomicGenerationNumber;
final Consumer<Intent> mCallback;
// Used to verify this receiver is still current.
public final int generationNumber;
final int mGenerationNumber;
private final Handler mHandler;
Receiver(String tag, AtomicInteger atomicGenerationNumber, Consumer<Intent> callback) {
this.tag = tag;
this.atomicGenerationNumber = atomicGenerationNumber;
this.callback = callback;
generationNumber = atomicGenerationNumber.incrementAndGet();
Receiver(String tag, AtomicInteger atomicGenerationNumber, Consumer<Intent> callback,
Handler handler) {
mTag = tag;
mAtomicGenerationNumber = atomicGenerationNumber;
mCallback = callback;
mGenerationNumber = atomicGenerationNumber.incrementAndGet();
mHandler = handler;
}
@Override
public void onReceive(Context context, Intent intent) {
final int currentGenerationNumber = atomicGenerationNumber.get();
mHandler.post(() -> {
final int currentGenerationNumber = mAtomicGenerationNumber.get();
if (DBG) {
Log.d(tag, "receiver generationNumber=" + generationNumber
+ ", current generationNumber=" + currentGenerationNumber);
}
if (generationNumber != currentGenerationNumber) return;
if (DBG) {
Log.d(mTag, "receiver generationNumber=" + mGenerationNumber
+ ", current generationNumber=" + currentGenerationNumber);
}
if (mGenerationNumber != currentGenerationNumber) return;
callback.accept(intent);
mCallback.accept(intent);
});
}
}
}

View file

@ -16,6 +16,8 @@
package com.android.networkstack.tethering.util;
import static com.android.testutils.HandlerUtils.waitForIdle;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.reset;
@ -23,7 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.os.HandlerThread;
import android.os.UserHandle;
import androidx.test.filters.SmallTest;
@ -33,7 +35,6 @@ import com.android.internal.util.test.BroadcastInterceptingContext;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@ -44,9 +45,11 @@ import org.mockito.MockitoAnnotations;
public class VersionedBroadcastListenerTest {
private static final String TAG = VersionedBroadcastListenerTest.class.getSimpleName();
private static final String ACTION_TEST = "action.test.happy.broadcasts";
private static final long TEST_TIMEOUT_MS = 10_000L;
@Mock private Context mContext;
private BroadcastInterceptingContext mServiceContext;
private HandlerThread mHandlerThread;
private Handler mHandler;
private VersionedBroadcastListener mListener;
private int mCallbackCount;
@ -61,18 +64,13 @@ public class VersionedBroadcastListenerTest {
}
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
if (Looper.myLooper() == null) {
Looper.prepare();
}
}
@Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
reset(mContext);
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mServiceContext = new MockContext(mContext);
mHandler = new Handler(Looper.myLooper());
mCallbackCount = 0;
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_TEST);
@ -85,11 +83,15 @@ public class VersionedBroadcastListenerTest {
mListener.stopListening();
mListener = null;
}
mHandlerThread.quitSafely();
mHandlerThread.join(TEST_TIMEOUT_MS);
}
private void sendBroadcast() {
final Intent intent = new Intent(ACTION_TEST);
mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
// Sending the broadcast is synchronous, but the receiver just posts on the handler
waitForIdle(mHandler, TEST_TIMEOUT_MS);
}
@Test