Merge "Only allow one pending bluetooth request at a time" into main
This commit is contained in:
commit
7fb9055ff3
2 changed files with 49 additions and 18 deletions
|
|
@ -290,7 +290,10 @@ public class Tethering {
|
|||
private SettingsObserver mSettingsObserver;
|
||||
private BluetoothPan mBluetoothPan;
|
||||
private PanServiceListener mBluetoothPanListener;
|
||||
private final ArrayList<IIntResultListener> mPendingPanRequestListeners;
|
||||
// Pending listener for starting Bluetooth tethering before the PAN service is connected. Once
|
||||
// the service is connected, the bluetooth iface will be requested and the listener will be
|
||||
// called.
|
||||
private IIntResultListener mPendingPanRequestListener;
|
||||
// AIDL doesn't support Set<Integer>. Maintain a int bitmap here. When the bitmap is passed to
|
||||
// TetheringManager, TetheringManager would convert it to a set of Integer types.
|
||||
// mSupportedTypeBitmap should always be updated inside tethering internal thread but it may be
|
||||
|
|
@ -308,11 +311,6 @@ public class Tethering {
|
|||
mTetheringMetrics = mDeps.makeTetheringMetrics(mContext);
|
||||
mRequestTracker = new RequestTracker();
|
||||
|
||||
// This is intended to ensrure that if something calls startTethering(bluetooth) just after
|
||||
// bluetooth is enabled. Before onServiceConnected is called, store the calls into this
|
||||
// list and handle them as soon as onServiceConnected is called.
|
||||
mPendingPanRequestListeners = new ArrayList<>();
|
||||
|
||||
mTetherStates = new ArrayMap<>();
|
||||
mConnectedClientsTracker = new ConnectedClientsTracker();
|
||||
|
||||
|
|
@ -862,15 +860,21 @@ public class Tethering {
|
|||
if (!enable) {
|
||||
// The service is not connected. If disabling tethering, there's no point starting
|
||||
// the service just to stop tethering since tethering is not started. Just remove
|
||||
// any pending requests to enable tethering, and notify them that they have failed.
|
||||
for (IIntResultListener pendingListener : mPendingPanRequestListeners) {
|
||||
sendTetherResult(pendingListener, TETHER_ERROR_SERVICE_UNAVAIL,
|
||||
// any pending request to enable tethering, and notify them that they have failed.
|
||||
if (mPendingPanRequestListener != null) {
|
||||
sendTetherResult(mPendingPanRequestListener, TETHER_ERROR_SERVICE_UNAVAIL,
|
||||
TETHERING_BLUETOOTH);
|
||||
}
|
||||
mPendingPanRequestListeners.clear();
|
||||
mPendingPanRequestListener = null;
|
||||
return TETHER_ERROR_NO_ERROR;
|
||||
}
|
||||
mPendingPanRequestListeners.add(listener);
|
||||
|
||||
// Only allow one pending request at a time.
|
||||
if (mPendingPanRequestListener != null) {
|
||||
return TETHER_ERROR_SERVICE_UNAVAIL;
|
||||
}
|
||||
|
||||
mPendingPanRequestListener = listener;
|
||||
|
||||
// Bluetooth tethering is not a popular feature. To avoid bind to bluetooth pan service all
|
||||
// the time but user never use bluetooth tethering. mBluetoothPanListener is created first
|
||||
|
|
@ -897,12 +901,12 @@ public class Tethering {
|
|||
mBluetoothPan = (BluetoothPan) proxy;
|
||||
mIsConnected = true;
|
||||
|
||||
for (IIntResultListener pendingListener : mPendingPanRequestListeners) {
|
||||
if (mPendingPanRequestListener != null) {
|
||||
final int result = setBluetoothTetheringSettings(mBluetoothPan,
|
||||
true /* enable */);
|
||||
sendTetherResult(pendingListener, result, TETHERING_BLUETOOTH);
|
||||
sendTetherResult(mPendingPanRequestListener, result, TETHERING_BLUETOOTH);
|
||||
}
|
||||
mPendingPanRequestListeners.clear();
|
||||
mPendingPanRequestListener = null;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -913,11 +917,11 @@ public class Tethering {
|
|||
// reachable before next onServiceConnected.
|
||||
mIsConnected = false;
|
||||
|
||||
for (IIntResultListener pendingListener : mPendingPanRequestListeners) {
|
||||
sendTetherResult(pendingListener, TETHER_ERROR_SERVICE_UNAVAIL,
|
||||
if (mPendingPanRequestListener != null) {
|
||||
sendTetherResult(mPendingPanRequestListener, TETHER_ERROR_SERVICE_UNAVAIL,
|
||||
TETHERING_BLUETOOTH);
|
||||
}
|
||||
mPendingPanRequestListeners.clear();
|
||||
mPendingPanRequestListener = null;
|
||||
mBluetoothIfaceRequest = null;
|
||||
mBluetoothCallback = null;
|
||||
maybeDisableBluetoothIpServing();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ import static org.mockito.Matchers.anyString;
|
|||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
|
|
@ -3571,6 +3572,32 @@ public class TetheringTest {
|
|||
failedEnable.assertHasResult();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartBluetoothTetheringFailsWhenTheresAnExistingRequestWaitingForPanService()
|
||||
throws Exception {
|
||||
initTetheringOnTestThread();
|
||||
|
||||
mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
|
||||
final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
|
||||
mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
|
||||
TEST_CALLER_PKG, firstResult);
|
||||
mLooper.dispatchAll();
|
||||
firstResult.assertDoesNotHaveResult();
|
||||
|
||||
// Second request should fail.
|
||||
final ResultListener secondResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
|
||||
mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
|
||||
TEST_CALLER_PKG, secondResult);
|
||||
mLooper.dispatchAll();
|
||||
secondResult.assertHasResult();
|
||||
firstResult.assertDoesNotHaveResult();
|
||||
|
||||
// Bind to PAN service should succeed for first listener only. If the second result is
|
||||
// called with TETHER_ERROR_NO_ERROR, ResultListener will fail an assertion.
|
||||
verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
|
||||
firstResult.assertHasResult();
|
||||
}
|
||||
|
||||
private void mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn) {
|
||||
when(mBluetoothAdapter.isEnabled()).thenReturn(bluetoothOn);
|
||||
when(mBluetoothPan.isTetheringOn()).thenReturn(tetheringOn);
|
||||
|
|
@ -3618,7 +3645,7 @@ public class TetheringTest {
|
|||
private ServiceListener verifySetBluetoothTethering(final boolean enable,
|
||||
final boolean bindToPanService) throws Exception {
|
||||
ServiceListener listener = null;
|
||||
verify(mBluetoothAdapter).isEnabled();
|
||||
verify(mBluetoothAdapter, atLeastOnce()).isEnabled();
|
||||
if (bindToPanService) {
|
||||
final ArgumentCaptor<ServiceListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(ServiceListener.class);
|
||||
|
|
|
|||
Loading…
Reference in a new issue