mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-09-01 03:55:47 +02:00
parent
20f4248e1c
commit
b8a2fc0076
@ -57,80 +57,8 @@ public final class BtBRQueue {
|
||||
private final Context mContext;
|
||||
private final int mBufferSize;
|
||||
|
||||
private Handler mWriteHandler;
|
||||
|
||||
private final HandlerThread mWriteHandlerThread = new HandlerThread("Write Thread", Process.THREAD_PRIORITY_BACKGROUND) {
|
||||
@Override
|
||||
protected void onLooperPrepared() {
|
||||
LOG.debug("Write handler thread's looper prepared, creating write handler");
|
||||
mWriteHandler = new Handler(mWriteHandlerThread.getLooper()) {
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
switch (msg.what) {
|
||||
case HANDLER_SUBJECT_CONNECT: {
|
||||
try {
|
||||
mBtSocket.connect();
|
||||
|
||||
LOG.info("Connected to RFCOMM socket for {}", mGbDevice.getName());
|
||||
setDeviceConnectionState(GBDevice.State.CONNECTED);
|
||||
|
||||
// update thread names to show device names in logs
|
||||
readThread.setName(String.format(Locale.ENGLISH,
|
||||
"Read Thread for %s", mGbDevice.getName()));
|
||||
mWriteHandlerThread.setName(String.format(Locale.ENGLISH,
|
||||
"Write Thread for %s", mGbDevice.getName()));
|
||||
|
||||
// now that connect has been created, start the threads
|
||||
readThread.start();
|
||||
onConnectionEstablished();
|
||||
} catch (IOException e) {
|
||||
LOG.error("IO exception while establishing socket connection: ", e);
|
||||
setDeviceConnectionState(GBDevice.State.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case HANDLER_SUBJECT_PERFORM_TRANSACTION: {
|
||||
try {
|
||||
if (!isConnected()) {
|
||||
LOG.debug("Not connected, updating device state to WAITING_FOR_RECONNECT");
|
||||
setDeviceConnectionState(GBDevice.State.WAITING_FOR_RECONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(msg.obj instanceof Transaction)) {
|
||||
LOG.error("msg.obj is not an instance of Transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
Transaction transaction = (Transaction) msg.obj;
|
||||
|
||||
for (BtBRAction action : transaction.getActions()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("About to run action: {}", action);
|
||||
}
|
||||
|
||||
if (action.run(mBtSocket)) {
|
||||
LOG.debug("Action ok: {}", action);
|
||||
} else {
|
||||
LOG.error("Action returned false, cancelling further actions in transaction: {}", action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("IO Write Thread died: " + ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG.warn("Unhandled write handler message {}", msg.what);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
private final Handler mWriteHandler;
|
||||
private final HandlerThread mWriteHandlerThread = new HandlerThread("Write Thread", Process.THREAD_PRIORITY_BACKGROUND);
|
||||
|
||||
private Thread readThread = new Thread("Read Thread") {
|
||||
@Override
|
||||
@ -176,6 +104,74 @@ public final class BtBRQueue {
|
||||
mBufferSize = bufferSize;
|
||||
|
||||
mWriteHandlerThread.start();
|
||||
|
||||
LOG.debug("Write handler thread is prepared, creating write handler");
|
||||
mWriteHandler = new Handler(mWriteHandlerThread.getLooper()) {
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
switch (msg.what) {
|
||||
case HANDLER_SUBJECT_CONNECT: {
|
||||
try {
|
||||
mBtSocket.connect();
|
||||
|
||||
LOG.info("Connected to RFCOMM socket for {}", mGbDevice.getName());
|
||||
setDeviceConnectionState(GBDevice.State.CONNECTED);
|
||||
|
||||
// update thread names to show device names in logs
|
||||
readThread.setName(String.format(Locale.ENGLISH,
|
||||
"Read Thread for %s", mGbDevice.getName()));
|
||||
mWriteHandlerThread.setName(String.format(Locale.ENGLISH,
|
||||
"Write Thread for %s", mGbDevice.getName()));
|
||||
|
||||
// now that connect has been created, start the threads
|
||||
readThread.start();
|
||||
onConnectionEstablished();
|
||||
} catch (IOException e) {
|
||||
LOG.error("IO exception while establishing socket connection: ", e);
|
||||
setDeviceConnectionState(GBDevice.State.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case HANDLER_SUBJECT_PERFORM_TRANSACTION: {
|
||||
try {
|
||||
if (!isConnected()) {
|
||||
LOG.debug("Not connected, updating device state to WAITING_FOR_RECONNECT");
|
||||
setDeviceConnectionState(GBDevice.State.WAITING_FOR_RECONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(msg.obj instanceof Transaction)) {
|
||||
LOG.error("msg.obj is not an instance of Transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
Transaction transaction = (Transaction) msg.obj;
|
||||
|
||||
for (BtBRAction action : transaction.getActions()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("About to run action: {}", action);
|
||||
}
|
||||
|
||||
if (action.run(mBtSocket)) {
|
||||
LOG.debug("Action ok: {}", action);
|
||||
} else {
|
||||
LOG.error("Action returned false, cancelling further actions in transaction: {}", action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("IO Write Thread died: " + ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG.warn("Unhandled write handler message {}", msg.what);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2022-2023 Martin.JM
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btbr.BtBRQueue;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TestBtBRQueue {
|
||||
|
||||
@Test
|
||||
public void connect() {
|
||||
GBDevice device = Mockito.mock(GBDevice.class);
|
||||
when(device.isConnected()).thenReturn(false);
|
||||
|
||||
BluetoothDevice btDevice = Mockito.mock(BluetoothDevice.class);
|
||||
|
||||
BluetoothAdapter btAdapter = Mockito.mock(BluetoothAdapter.class);
|
||||
when(btAdapter.getRemoteDevice((String) any())).thenReturn(btDevice);
|
||||
|
||||
BtBRQueue queue = new BtBRQueue(btAdapter, device, null, null, null, 512);
|
||||
Assert.assertTrue(queue.connect());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reconnect() {
|
||||
GBDevice device = Mockito.mock(GBDevice.class);
|
||||
when(device.isConnected()).thenReturn(false);
|
||||
|
||||
BluetoothDevice btDevice = Mockito.mock(BluetoothDevice.class);
|
||||
|
||||
BluetoothAdapter btAdapter = Mockito.mock(BluetoothAdapter.class);
|
||||
when(btAdapter.getRemoteDevice((String) any())).thenReturn(btDevice);
|
||||
|
||||
BtBRQueue queue = new BtBRQueue(btAdapter, device, null, null, null, 512);
|
||||
Assert.assertTrue(queue.connect());
|
||||
|
||||
queue.disconnect();
|
||||
|
||||
Assert.assertTrue(queue.connect());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user