BluetoothServerThread extends AbstractBluetoothThread implements BluetoothSocketIoThread.Listener { @Override public void onBytesRead(byte[] bytes, int size, BluetoothSocketIoThread who) { final long threadId = who.getId(); Log.d(TAG, "onBytesRead: Read " + size + " bytes successfully (thread ID: " + threadId + ")"); if (who.getPeerProperties() != null) { Log.d(TAG, "onBytesRead: Peer props = " + who.getPeerProperties().toString()); } PeerProperties peerProperties = BluetoothUtils.validateReceivedHandshakeMessage(bytes, size, who.getSocket()); if (peerProperties != null) { Log.i(TAG, "Got valid identity from " + peerProperties.toString()); who.setPeerProperties(peerProperties); if (!who.write(getHandshakeMessage())) { Log.e(TAG, "Failed to respond to thread with ID " + threadId); removeThreadFromList(threadId, true); } } else { Log.e(TAG, "Failed to receive valid identity (thread ID: " + threadId + ")"); removeThreadFromList(threadId, true); } } BluetoothServerThread(
            Listener listener, BluetoothAdapter bluetoothAdapter,
            UUID serviceRecordUuid, String myBluetoothName, String myIdentityString); @Override void run(); @Override synchronized void shutdown(); @Override void onBytesRead(byte[] bytes, int size, BluetoothSocketIoThread who); @Override void onBytesWritten(byte[] bytes, int size, BluetoothSocketIoThread who); @Override void onDisconnected(String reason, BluetoothSocketIoThread who);  }
@Test public void testOnBytesRead() throws Exception { String macAddress = "0A:1B:2C:3D:4E:5F"; Field mSocketIoThreadsField = mBluetoothServerThread.getClass() .getDeclaredField("mSocketIoThreads"); mSocketIoThreadsField.setAccessible(true); CopyOnWriteArrayList<BluetoothSocketIoThread> mySocketIoThreads = new CopyOnWriteArrayList<>(); mSocketIoThreadsField.set(mBluetoothServerThread, mySocketIoThreads); mySocketIoThreads.add(mMockBluetoothSocketIoThread); when(mMockBluetoothSocketIoThread.getSocket()).thenReturn(mMockBluetoothSocket); when(mMockBluetoothSocket.getRemoteDevice()).thenReturn(mMockBluetoothDevice); when(mMockBluetoothDevice.getAddress()).thenReturn(macAddress); when(mMockBluetoothSocketIoThread.write( myIdentityId.getBytes(StandardCharsets.UTF_8))).thenReturn(true); mBluetoothServerThread.onBytesRead(BluetoothUtils.SIMPLE_HANDSHAKE_MESSAGE_AS_BYTE_ARRAY, 15, mMockBluetoothSocketIoThread); verify(mMockBluetoothSocketIoThread, never()).close(anyBoolean(), anyBoolean()); verify(mMockBluetoothSocketIoThread, times(1)).setPeerProperties(any(PeerProperties.class)); verify(mMockBluetoothSocketIoThread, times(1)) .write(myIdentityId.getBytes(StandardCharsets.UTF_8)); assertThat("The list of IO threads is not changed", mySocketIoThreads.isEmpty(), is(false)); }
@Test public void testOnBytesRead_notValidIdentity() throws Exception { Field mSocketIoThreadsField = mBluetoothServerThread.getClass() .getDeclaredField("mSocketIoThreads"); mSocketIoThreadsField.setAccessible(true); CopyOnWriteArrayList<BluetoothSocketIoThread> mySocketIoThreads = new CopyOnWriteArrayList<>(); mSocketIoThreadsField.set(mBluetoothServerThread, mySocketIoThreads); mySocketIoThreads.add(mMockBluetoothSocketIoThread); mBluetoothServerThread.onBytesRead("WrongMessage".getBytes(), 15, mMockBluetoothSocketIoThread); verify(mMockBluetoothSocketIoThread, times(1)).close(true, true); verify(mMockBluetoothSocketIoThread, never()).setPeerProperties(any(PeerProperties.class)); verify(mMockBluetoothSocketIoThread, never()) .write(myIdentityId.getBytes(StandardCharsets.UTF_8)); assertThat("The thread is removed from the list of IO threads", mySocketIoThreads.isEmpty(), is(true)); }
@Test public void testOnBytesRead_notValidResponse() throws Exception { String macAddress = "0A:1B:2C:3D:4E:5F"; Field mSocketIoThreadsField = mBluetoothServerThread.getClass() .getDeclaredField("mSocketIoThreads"); mSocketIoThreadsField.setAccessible(true); CopyOnWriteArrayList<BluetoothSocketIoThread> mySocketIoThreads = new CopyOnWriteArrayList<>(); mSocketIoThreadsField.set(mBluetoothServerThread, mySocketIoThreads); mySocketIoThreads.add(mMockBluetoothSocketIoThread); when(mMockBluetoothSocketIoThread.getSocket()).thenReturn(mMockBluetoothSocket); when(mMockBluetoothSocket.getRemoteDevice()).thenReturn(mMockBluetoothDevice); when(mMockBluetoothDevice.getAddress()).thenReturn(macAddress); when(mMockBluetoothSocketIoThread.write( myIdentityId.getBytes(StandardCharsets.UTF_8))).thenReturn(false); mBluetoothServerThread.onBytesRead(BluetoothUtils.SIMPLE_HANDSHAKE_MESSAGE_AS_BYTE_ARRAY, 15, mMockBluetoothSocketIoThread); verify(mMockBluetoothSocketIoThread, times(1)).close(true, true); assertThat("The thread is removed from the list of IO threads", mySocketIoThreads.isEmpty(), is(true)); }