| package com.android.clockwork.bluetooth; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Matchers.anyString; |
| import static org.mockito.Mockito.isNull; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import android.bluetooth.BluetoothAdapter; |
| import android.bluetooth.BluetoothDevice; |
| import android.bluetooth.MockBluetoothProxyHelper; |
| import android.content.Context; |
| import android.os.ParcelFileDescriptor; |
| import android.os.RemoteException; |
| import com.android.clockwork.WearRobolectricTestRunner; |
| import com.android.clockwork.bluetooth.proxy.ProxyServiceManager; |
| import com.android.internal.util.IndentingPrintWriter; |
| import java.net.InetAddress; |
| import java.util.HashSet; |
| import java.util.List; |
| import org.junit.Before; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| import org.robolectric.annotation.Config; |
| import org.robolectric.shadows.ShadowApplication; |
| import org.robolectric.shadows.ShadowLooper; |
| |
| /** Test for Companion proxy shard */ |
| @RunWith(WearRobolectricTestRunner.class) |
| @Config(manifest = Config.NONE, |
| shadows = {ShadowBluetoothAdapter.class }, |
| sdk = 26) |
| public class CompanionProxyShardTest { |
| final ShadowApplication shadowApplication = ShadowApplication.getInstance(); |
| |
| private static final int INSTANCE = -1; |
| private static final int FD = 2; |
| |
| private static final int WHAT_START_SYSPROXY = 1; |
| private static final int WHAT_STOP_SYSPROXY = 2; |
| private static final int WHAT_JNI_CONNECTED = 3; |
| private static final int WHAT_JNI_DISCONNECTED = 4; |
| private static final int WHAT_CONNECTION_FAILED = 5; |
| private static final int WHAT_RESET_CONNECTION = 6; |
| |
| private static final int INVALID_NETWORK_TYPE = -1; |
| |
| private Context mContext; |
| |
| private CompanionProxyShardTestClass mCompanionProxyShard; |
| private CompanionProxyShardListener mCompanionProxyShardListener |
| = new CompanionProxyShardListener(); |
| |
| private MockBluetoothProxyHelper mBluetoothProxyHelper; |
| |
| @Mock BluetoothAdapter mockBluetoothAdapter; |
| @Mock BluetoothDevice mockBluetoothDevice; |
| @Mock Context mockContext; |
| @Mock IndentingPrintWriter mockIndentingPrintWriter; |
| @Mock ParcelFileDescriptor mockParcelFileDescriptor; |
| @Mock ProxyServiceManager mockProxyServiceManager; |
| |
| @Before |
| public void setUp() throws RemoteException { |
| MockitoAnnotations.initMocks(this); |
| mContext = shadowApplication.getApplicationContext(); |
| mCompanionProxyShard = createCompanionProxyShard(); |
| |
| when(mockBluetoothAdapter.isEnabled()).thenReturn(true); |
| mBluetoothProxyHelper = new MockBluetoothProxyHelper(mockBluetoothAdapter); |
| |
| ShadowBluetoothAdapter.setAdapter(mockBluetoothAdapter); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| when(mockParcelFileDescriptor.detachFd()).thenReturn(FD); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyDisconnected() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager, times(2)).setConnecting(anyString()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| ensureMessageQueueEmpty(); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyConnected() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_CONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| assertEquals(0, mCompanionProxyShard.connectNativeCount); |
| |
| verify(mockParcelFileDescriptor, never()).detachFd(); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager, never()).setConnecting(anyString()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| ensureMessageQueueEmpty(); |
| } |
| |
| @Test |
| public void testStartNetwork_ConnectedOnStop() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager, times(2)).setConnecting(anyString()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| mCompanionProxyShard.onStopNetwork(); |
| |
| assertFalse(mCompanionProxyShardListener.isConnected); |
| verify(mockProxyServiceManager).setDisconnected(anyString()); |
| } |
| |
| @Test |
| public void testStartNetwork_ClosedAndConnected() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_CONNECTED); |
| |
| mCompanionProxyShard.mIsClosed = true; |
| mCompanionProxyShard.onStartNetwork(); |
| |
| verify(mockProxyServiceManager, times(1)).ensureValidNetworkAgent(anyString()); |
| verify(mockProxyServiceManager, never()).getNetworkScore(); |
| } |
| |
| @Test |
| public void testStartNetwork_NullParcelFileDescriptor() { |
| ShadowLooper.pauseMainLooper(); |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(null); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| ShadowLooper.runMainLooperOneTask(); |
| ShadowLooper.runMainLooperOneTask(); |
| |
| verify(mockProxyServiceManager, times(1)).ensureValidNetworkAgent(anyString()); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_RESET_CONNECTION)); |
| } |
| |
| @Test |
| public void testStartNetwork_DisconnectedOnStop() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| |
| mCompanionProxyShard.onStopNetwork(); |
| |
| assertFalse(mCompanionProxyShardListener.isConnected); |
| verify(mockProxyServiceManager, never()).setDisconnected(anyString()); |
| } |
| |
| @Test |
| public void testUpdateNetwork() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| |
| mCompanionProxyShard.onUpdateNetwork(100); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyDisconnectRequest() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECT_REQUEST); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| assertEquals(0, mCompanionProxyShard.connectNativeCount); |
| |
| verify(mockParcelFileDescriptor, never()).detachFd(); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_DISCONNECT_REQUEST, |
| mCompanionProxyShard.mState.current()); |
| // Ensure the proper message queue state |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_START_SYSPROXY)); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyDisconnectedAndUnpaired() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| when(mockBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE); |
| |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.onStartNetwork(); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| assertEquals(0, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, never()).detachFd(); |
| |
| assertEquals(CompanionProxyShard.State.BLUETOOTH_SOCKET_REQUESTING, |
| mCompanionProxyShard.mState.current()); |
| |
| ensureMessageQueueEmpty(); |
| } |
| |
| @Test |
| public void testStartNetwork_AdapterIsNull() { |
| // Force bluetooth adapter to return null |
| ShadowBluetoothAdapter.forceNull = true; |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.onStartNetwork(); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| |
| assertEquals(CompanionProxyShard.State.BLUETOOTH_SOCKET_REQUESTING, |
| mCompanionProxyShard.mState.current()); |
| ensureMessageQueueEmpty(); |
| // Restore bluetooth adapter to return a valid instance |
| ShadowBluetoothAdapter.forceNull = false; |
| } |
| |
| @Test |
| public void testStartNetwork_AdapterIsDisabled() { |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| when(mockBluetoothAdapter.isEnabled()).thenReturn(false); |
| |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.onStartNetwork(); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| |
| assertEquals(CompanionProxyShard.State.BLUETOOTH_SOCKET_REQUESTING, |
| mCompanionProxyShard.mState.current()); |
| ensureMessageQueueEmpty(); |
| } |
| |
| @Test |
| public void testStartNetwork_BluetoothServiceIsNull() { |
| mBluetoothProxyHelper.setBluetoothService(null); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.onStartNetwork(); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| ShadowLooper.runMainLooperOneTask(); |
| |
| assertEquals(CompanionProxyShard.State.BLUETOOTH_SOCKET_REQUESTING, |
| mCompanionProxyShard.mState.current()); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_RESET_CONNECTION)); |
| } |
| |
| @Test |
| public void testJniActiveNetworkState_AlreadyClosed() { |
| mCompanionProxyShard.mIsClosed = true; |
| mCompanionProxyShard.simulateJniCallbackConnect(1, true); |
| assertTrue(ShadowLooper.getMainLooper().myQueue().isIdle()); |
| } |
| |
| @Test |
| public void testJniActiveNetworkState_InvalidNetworkType() { |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.simulateJniCallbackConnect(INVALID_NETWORK_TYPE, true); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_CONNECTION_FAILED)); |
| } |
| |
| @Test |
| public void testJniActiveNetworkState_ConnectionFailedConnected() { |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_CONNECTED); |
| mCompanionProxyShard.simulateJniCallbackConnect(INVALID_NETWORK_TYPE, true); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_CONNECTION_FAILED)); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_START_SYSPROXY)); |
| assertFalse(mCompanionProxyShard.mHandler.hasMessages(WHAT_CONNECTION_FAILED)); |
| } |
| |
| @Test |
| public void testJniActiveNetworkState_ConnectionFailedNotConnected() { |
| ShadowLooper.pauseMainLooper(); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| mCompanionProxyShard.simulateJniCallbackConnect(INVALID_NETWORK_TYPE, true); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_CONNECTION_FAILED)); |
| |
| ShadowLooper.runMainLooperOneTask(); |
| assertTrue(mCompanionProxyShard.mHandler.hasMessages(WHAT_START_SYSPROXY)); |
| assertFalse(mCompanionProxyShard.mHandler.hasMessages(WHAT_CONNECTION_FAILED)); |
| } |
| |
| @Test |
| public void testStartNetwork_JniDisconnectNotClosed() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI connect callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| // Simulate JNI disconnect callback |
| mCompanionProxyShard.simulateJniCallbackDisconnect(-1); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_DISCONNECTED, |
| mCompanionProxyShard.mState.current()); |
| assertFalse(mCompanionProxyShardListener.isConnected); |
| verify(mockProxyServiceManager).setDisconnected(anyString()); |
| } |
| |
| @Test |
| public void testStartNetwork_JniDisconnectClosed() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI connect callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| mCompanionProxyShard.mIsClosed = true; |
| |
| // Simulate JNI disconnect callback |
| mCompanionProxyShard.simulateJniCallbackDisconnect(-1); |
| |
| verify(mockProxyServiceManager, never()).setDisconnected(anyString()); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyConnected_ClosedWasConnected() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| mCompanionProxyShard.close(); |
| verify(mockProxyServiceManager).setCallback(isNull()); |
| verify(mockProxyServiceManager).setDisconnected(anyString()); |
| assertFalse(mCompanionProxyShardListener.isConnected); |
| assertTrue(mCompanionProxyShard.mIsClosed); |
| assertEquals(1, mCompanionProxyShard.disconnectNativeCount); |
| assertEquals(CompanionProxyShard.State.SYSPROXY_DISCONNECT_RESPONSE, |
| mCompanionProxyShard.mState.current()); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyConnected_ClosedWasDisconnected() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.onStartNetwork(); |
| |
| assertEquals(1, mCompanionProxyShard.connectNativeCount); |
| verify(mockParcelFileDescriptor, times(1)).detachFd(); |
| |
| // Simulate JNI callback |
| mCompanionProxyShard.simulateJniCallbackConnect(1, false); |
| |
| assertEquals(CompanionProxyShard.State.SYSPROXY_CONNECTED, |
| mCompanionProxyShard.mState.current()); |
| verify(mockProxyServiceManager).setConnected(anyString()); |
| assertTrue(mCompanionProxyShardListener.isConnected); |
| assertEquals(0, mCompanionProxyShardListener.proxyScore); |
| |
| // Set false |
| mCompanionProxyShard.disconnectReturnValue = false; |
| |
| mCompanionProxyShard.close(); |
| verify(mockProxyServiceManager).setCallback(isNull()); |
| verify(mockProxyServiceManager).setDisconnected(anyString()); |
| assertFalse(mCompanionProxyShardListener.isConnected); |
| assertTrue(mCompanionProxyShard.mIsClosed); |
| assertEquals(1, mCompanionProxyShard.disconnectNativeCount); |
| assertEquals(CompanionProxyShard.State.SYSPROXY_DISCONNECTED, |
| mCompanionProxyShard.mState.current()); |
| } |
| |
| @Test |
| public void testStartNetwork_StateSysproxyConnected_ClosedWasAlreadyClosed() { |
| mBluetoothProxyHelper.setMockParcelFileDescriptor(mockParcelFileDescriptor); |
| mCompanionProxyShard.mState.advanceState(INSTANCE, |
| CompanionProxyShard.State.SYSPROXY_DISCONNECTED); |
| |
| mCompanionProxyShard.mIsClosed = true; |
| |
| mCompanionProxyShard.close(); |
| |
| verify(mockProxyServiceManager, never()).setCallback(isNull()); |
| verify(mockProxyServiceManager, never()).setDisconnected(anyString()); |
| } |
| |
| @Test |
| public void testToString() { |
| assertNotEquals("", mCompanionProxyShard.toString()); |
| } |
| |
| @Test |
| public void testDump() { |
| mCompanionProxyShard.dump(mockIndentingPrintWriter); |
| } |
| |
| // Create the companion proxy shard to be used in the tests. |
| // The class abstracts away dependencies on difficult framework methods and fields. |
| private CompanionProxyShardTestClass createCompanionProxyShard() { |
| when(mockBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); |
| |
| CompanionProxyShardTestClass companionProxyShard |
| = new CompanionProxyShardTestClass(mockContext, mockProxyServiceManager, |
| mockBluetoothDevice, mCompanionProxyShardListener); |
| |
| return companionProxyShard; |
| } |
| |
| private void ensureMessageQueueEmpty() { |
| for (int i = WHAT_START_SYSPROXY; i <= WHAT_RESET_CONNECTION; i++) { |
| assertFalse(mCompanionProxyShard.mHandler.hasMessages(i)); |
| } |
| } |
| |
| private class CompanionProxyShardTestClass extends CompanionProxyShard { |
| int connectNativeCount; |
| int disconnectNativeCount; |
| int unregisterCount; |
| |
| boolean connectReturnValue = true; |
| boolean disconnectReturnValue = true; |
| |
| public CompanionProxyShardTestClass( |
| final Context context, |
| final ProxyServiceManager proxyServiceManager, |
| final BluetoothDevice device, |
| final Listener listener) { |
| super(context, proxyServiceManager, device, listener); |
| } |
| |
| @Override |
| protected boolean connectNative(int fd) { |
| connectNativeCount += 1; |
| return connectReturnValue; |
| } |
| |
| void simulateJniCallbackConnect(int networkType, boolean isMetered) { |
| super.onActiveNetworkState(networkType, isMetered); |
| } |
| |
| @Override |
| protected boolean disconnectNative() { |
| disconnectNativeCount += 1; |
| return disconnectReturnValue; |
| } |
| |
| void simulateJniCallbackDisconnect(int status) { |
| super.onDisconnect(status); |
| } |
| } |
| |
| private class CompanionProxyShardListener implements CompanionProxyShard.Listener { |
| private boolean isConnected; |
| private int proxyScore; |
| |
| @Override |
| public void onProxyConnectionChange(boolean isConnected, int proxyScore) { |
| this.isConnected = isConnected; |
| this.proxyScore = proxyScore; |
| } |
| } |
| |
| public static <InetAddress> boolean listEqualsIgnoreOrder(List<InetAddress> list1, |
| List<InetAddress> list2) { |
| return new HashSet<>(list1).equals(new HashSet<>(list2)); |
| } |
| } |