Do not block broadcast on handler processing
Instead of blocking the broadcast until onReceive returns on the handler, only post in onReceive. This should make no difference for the only user, the mCarrierConfigChange listener in Tethering.java, as the callback still runs on the handler. Bug: 349919195 Test: atest Change-Id: Ie8ce7afbe905b4c6972b3aabda2d7792c96eda6c
This commit is contained in:
parent
6ade6e2042
commit
151be34424
2 changed files with 36 additions and 29 deletions
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue