mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
BT Classic/BTBR: Fix concurrency issues on connection
This commit is contained in:
+5
-10
@@ -25,7 +25,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||||
|
|
||||||
public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDeviceSupport implements HeadphoneHelper.Callback {
|
public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDeviceSupport implements HeadphoneHelper.Callback {
|
||||||
|
|
||||||
private HeadphoneHelper headphoneHelper;
|
private HeadphoneHelper headphoneHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,12 +43,6 @@ public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDevic
|
|||||||
headphoneHelper = new HeadphoneHelper(getContext(), getDevice(), this);
|
headphoneHelper = new HeadphoneHelper(getContext(), getDevice(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendConfiguration(String config) {
|
public void onSendConfiguration(String config) {
|
||||||
if (!headphoneHelper.onSendConfiguration(config))
|
if (!headphoneHelper.onSendConfiguration(config))
|
||||||
@@ -58,8 +51,10 @@ public abstract class AbstractHeadphoneDeviceSupport extends AbstractSerialDevic
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (headphoneHelper != null)
|
synchronized (ConnectionMonitor) {
|
||||||
headphoneHelper.dispose();
|
if (headphoneHelper != null)
|
||||||
super.dispose();
|
headphoneHelper.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-13
@@ -36,6 +36,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
|
|||||||
* @see nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread
|
* @see nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport implements SocketCallback {
|
public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport implements SocketCallback {
|
||||||
|
|
||||||
|
/// used to guard {@link #connect()}, {@link #disconnect()} and {@link #dispose()}
|
||||||
|
protected final Object ConnectionMonitor = new Object();
|
||||||
|
|
||||||
private BtBRQueue mQueue;
|
private BtBRQueue mQueue;
|
||||||
private UUID mSupportedService = null;
|
private UUID mSupportedService = null;
|
||||||
private int mBufferSize = 1024;
|
private int mBufferSize = 1024;
|
||||||
@@ -50,20 +54,24 @@ public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connect() {
|
public boolean connect() {
|
||||||
final UUID supportedService = getSupportedService();
|
synchronized (ConnectionMonitor) {
|
||||||
if (supportedService == null) {
|
final UUID supportedService = getSupportedService();
|
||||||
throw new NullPointerException("No supported service UUID specified");
|
if (supportedService == null) {
|
||||||
}
|
throw new NullPointerException("No supported service UUID specified");
|
||||||
|
}
|
||||||
|
|
||||||
if (mQueue == null) {
|
if (mQueue == null) {
|
||||||
mQueue = new BtBRQueue(getBluetoothAdapter(), getDevice(), getContext(), this, supportedService, getBufferSize());
|
mQueue = new BtBRQueue(getBluetoothAdapter(), getDevice(), getContext(), this, supportedService, getBufferSize());
|
||||||
|
}
|
||||||
|
return mQueue.connect();
|
||||||
}
|
}
|
||||||
return mQueue.connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
if (mQueue != null) {
|
synchronized (ConnectionMonitor) {
|
||||||
mQueue.disconnect();
|
if (mQueue != null) {
|
||||||
|
mQueue.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +88,11 @@ public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (mQueue != null) {
|
synchronized (ConnectionMonitor) {
|
||||||
mQueue.dispose();
|
if (mQueue != null) {
|
||||||
mQueue = null;
|
mQueue.dispose();
|
||||||
|
mQueue = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +101,7 @@ public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport im
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConnected(){
|
public boolean isConnected() {
|
||||||
// in a multi-threaded environment the queue knows
|
// in a multi-threaded environment the queue knows
|
||||||
// best about the up-to-date connection status
|
// best about the up-to-date connection status
|
||||||
return (mQueue != null) && mQueue.isConnected();
|
return (mQueue != null) && mQueue.isConnected();
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@@ -171,13 +170,11 @@ public final class BtBRQueue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(msg.obj instanceof Transaction)) {
|
if (!(msg.obj instanceof Transaction transaction)) {
|
||||||
LOG.error("msg.obj is not an instance of Transaction");
|
LOG.error("msg.obj is not an instance of Transaction");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction transaction = (Transaction) msg.obj;
|
|
||||||
|
|
||||||
for (BtBRAction action : transaction.getActions()) {
|
for (BtBRAction action : transaction.getActions()) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("About to run action: {}", action);
|
LOG.debug("About to run action: {}", action);
|
||||||
@@ -212,8 +209,15 @@ public final class BtBRQueue {
|
|||||||
*/
|
*/
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
public boolean connect() {
|
public boolean connect() {
|
||||||
if (isConnected()) {
|
final GBDevice.State state = mGbDevice.getState();
|
||||||
LOG.warn("Ignoring connect() because already connected.");
|
if (state.equalsOrHigherThan(GBDevice.State.CONNECTING)) {
|
||||||
|
LOG.warn("connect - ignored, state is {}", state);
|
||||||
|
return false;
|
||||||
|
} else if (mBtSocket != null) {
|
||||||
|
LOG.warn("connect - ignored, mBtSocket isn't null");
|
||||||
|
return false;
|
||||||
|
} else if (mDisposed.get()) {
|
||||||
|
LOG.error("connect - ignored, this BtBRQueue has already been disposed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,6 +308,7 @@ public final class BtBRQueue {
|
|||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (mDisposed.getAndSet(true)) {
|
if (mDisposed.getAndSet(true)) {
|
||||||
|
LOG.warn("dispose() was called repeatedly");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -101,13 +101,15 @@ public class AAWirelessSupport extends AbstractBTBRDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
try {
|
synchronized (ConnectionMonitor) {
|
||||||
getContext().unregisterReceiver(commandReceiver);
|
try {
|
||||||
} catch (final Exception e) {
|
getContext().unregisterReceiver(commandReceiver);
|
||||||
LOG.warn("Failed to unregister receiver", e);
|
} catch (final Exception e) {
|
||||||
}
|
LOG.warn("Failed to unregister receiver", e);
|
||||||
|
}
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
-12
@@ -19,28 +19,16 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.divoom;
|
|||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
|
||||||
public class PixooSupport extends AbstractSerialDeviceSupport {
|
public class PixooSupport extends AbstractSerialDeviceSupport {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(PixooSupport.class);
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendConfiguration(String config) {
|
public void onSendConfiguration(String config) {
|
||||||
super.onSendConfiguration(config);
|
super.onSendConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized PixooIOThread getDeviceIOThread() {
|
public synchronized PixooIOThread getDeviceIOThread() {
|
||||||
return (PixooIOThread) super.getDeviceIOThread();
|
return (PixooIOThread) super.getDeviceIOThread();
|
||||||
|
|||||||
+5
-3
@@ -117,9 +117,11 @@ public class ZeppOsBtbrSupport extends AbstractBTBRDeviceSupport implements Zepp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
zeppOsSupport.dispose();
|
synchronized (ConnectionMonitor) {
|
||||||
pingHandler.removeCallbacksAndMessages(null);
|
zeppOsSupport.dispose();
|
||||||
super.dispose();
|
pingHandler.removeCallbacksAndMessages(null);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+4
-2
@@ -199,8 +199,10 @@ public class HuaweiBRSupport extends AbstractBTBRDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
supportProvider.dispose();
|
synchronized (ConnectionMonitor) {
|
||||||
super.dispose();
|
supportProvider.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+5
-3
@@ -108,9 +108,11 @@ public class HuaweiFreebudsSupport extends HuaweiBRSupport implements HeadphoneH
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (headphoneHelper != null)
|
synchronized (ConnectionMonitor) {
|
||||||
headphoneHelper.dispose();
|
if (headphoneHelper != null)
|
||||||
super.dispose();
|
headphoneHelper.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
-23
@@ -17,29 +17,11 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.liveview;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.liveview;
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
|
||||||
public class LiveviewSupport extends AbstractSerialDeviceSupport {
|
public class LiveviewSupport extends AbstractSerialDeviceSupport {
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GBDeviceProtocol createDeviceProtocol() {
|
protected GBDeviceProtocol createDeviceProtocol() {
|
||||||
return new LiveviewProtocol(getDevice());
|
return new LiveviewProtocol(getDevice());
|
||||||
@@ -59,9 +41,4 @@ public class LiveviewSupport extends AbstractSerialDeviceSupport {
|
|||||||
public synchronized LiveviewIoThread getDeviceIOThread() {
|
public synchronized LiveviewIoThread getDeviceIOThread() {
|
||||||
return (LiveviewIoThread) super.getDeviceIOThread();
|
return (LiveviewIoThread) super.getDeviceIOThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
|
||||||
super.onNotification(notificationSpec);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -55,8 +55,10 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
synchronized (ConnectionMonitor) {
|
||||||
unregisterSunriseSunsetAlarmReceiver();
|
super.dispose();
|
||||||
|
unregisterSunriseSunsetAlarmReceiver();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerSunriseSunsetAlarmReceiver() {
|
private void registerSunriseSunsetAlarmReceiver() {
|
||||||
@@ -79,8 +81,13 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connect() {
|
public boolean connect() {
|
||||||
getDeviceIOThread().start();
|
synchronized (ConnectionMonitor) {
|
||||||
registerSunriseSunsetAlarmReceiver();
|
final PebbleIoThread deviceIOThread = getDeviceIOThread();
|
||||||
|
if (!deviceIOThread.isAlive()) {
|
||||||
|
deviceIOThread.start();
|
||||||
|
}
|
||||||
|
registerSunriseSunsetAlarmReceiver();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-7
@@ -5,13 +5,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
|
||||||
public class PixelBudsADeviceSupport extends AbstractSerialDeviceSupport {
|
public class PixelBudsADeviceSupport extends AbstractSerialDeviceSupport {
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
-8
@@ -21,14 +21,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
|
||||||
public class QC35BaseSupport extends AbstractSerialDeviceSupport {
|
public class QC35BaseSupport extends AbstractSerialDeviceSupport {
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceProtocol();
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
-6
@@ -33,12 +33,6 @@ public class RedmiBudsDeviceSupport extends AbstractSerialDeviceSupport {
|
|||||||
RedmiBudsDeviceSupport.this, getBluetoothAdapter());
|
RedmiBudsDeviceSupport.this, getBluetoothAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+10
-7
@@ -79,11 +79,14 @@ public class RoidmiSupport extends AbstractSerialDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connect() {
|
public boolean connect() {
|
||||||
getDeviceIOThread().start();
|
synchronized (ConnectionMonitor) {
|
||||||
|
final RoidmiIoThread deviceIOThread = getDeviceIOThread();
|
||||||
requestDeviceInfos(1500);
|
if (!deviceIOThread.isAlive()) {
|
||||||
|
deviceIOThread.start();
|
||||||
return true;
|
requestDeviceInfos(1500);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -104,7 +107,7 @@ public class RoidmiSupport extends AbstractSerialDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendConfiguration(final String config) {
|
public void onSendConfiguration(final String config) {
|
||||||
LOG.debug("onSendConfiguration " + config);
|
LOG.debug("onSendConfiguration {}", config);
|
||||||
|
|
||||||
final RoidmiIoThread roidmiIoThread = getDeviceIOThread();
|
final RoidmiIoThread roidmiIoThread = getDeviceIOThread();
|
||||||
final RoidmiProtocol roidmiProtocol = (RoidmiProtocol) getDeviceProtocol();
|
final RoidmiProtocol roidmiProtocol = (RoidmiProtocol) getDeviceProtocol();
|
||||||
@@ -120,7 +123,7 @@ public class RoidmiSupport extends AbstractSerialDeviceSupport {
|
|||||||
roidmiIoThread.write(roidmiProtocol.encodeGetVoltage());
|
roidmiIoThread.write(roidmiProtocol.encodeGetVoltage());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG.error("Invalid Roidmi configuration " + config);
|
LOG.error("Invalid Roidmi configuration {}", config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-6
@@ -9,12 +9,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
|||||||
public class SoundcoreLiberty3ProDeviceSupport extends AbstractSerialDeviceSupport {
|
public class SoundcoreLiberty3ProDeviceSupport extends AbstractSerialDeviceSupport {
|
||||||
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3952");
|
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3952");
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
-6
@@ -9,12 +9,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
|||||||
public class SoundcoreLiberty4NCDeviceSupport extends AbstractSerialDeviceSupport {
|
public class SoundcoreLiberty4NCDeviceSupport extends AbstractSerialDeviceSupport {
|
||||||
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3947");
|
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3947");
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
-6
@@ -16,12 +16,6 @@ public class SoundcoreQ30DeviceSupport extends AbstractSerialDeviceSupport {
|
|||||||
return new SoundcoreQ30IOThread(getDevice(), getContext(), (SoundcoreQ30Protocol) getDeviceProtocol(),this, getBluetoothAdapter());
|
return new SoundcoreQ30IOThread(getDevice(), getContext(), (SoundcoreQ30Protocol) getDeviceProtocol(),this, getBluetoothAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connect() {
|
|
||||||
getDeviceIOThread().start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAutoConnect() {
|
public boolean useAutoConnect() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+21
-5
@@ -56,6 +56,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
|
|||||||
public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport {
|
public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractSerialDeviceSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractSerialDeviceSupport.class);
|
||||||
|
|
||||||
|
/// used to guard {@link #connect()} and {@link #dispose()}
|
||||||
|
protected final Object ConnectionMonitor = new Object();
|
||||||
|
|
||||||
private GBDeviceProtocol gbDeviceProtocol;
|
private GBDeviceProtocol gbDeviceProtocol;
|
||||||
protected GBDeviceIoThread gbDeviceIOThread;
|
protected GBDeviceIoThread gbDeviceIOThread;
|
||||||
|
|
||||||
@@ -69,13 +72,26 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
|
|||||||
*/
|
*/
|
||||||
protected abstract GBDeviceIoThread createDeviceIOThread();
|
protected abstract GBDeviceIoThread createDeviceIOThread();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean connect() {
|
||||||
|
synchronized (ConnectionMonitor) {
|
||||||
|
final GBDeviceIoThread deviceIOThread = getDeviceIOThread();
|
||||||
|
if (!deviceIOThread.isAlive()) {
|
||||||
|
deviceIOThread.start();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
// currently only one thread allowed
|
synchronized (ConnectionMonitor) {
|
||||||
if (gbDeviceIOThread != null) {
|
// currently only one thread allowed
|
||||||
gbDeviceIOThread.quit();
|
if (gbDeviceIOThread != null) {
|
||||||
gbDeviceIOThread.interrupt();
|
gbDeviceIOThread.quit();
|
||||||
gbDeviceIOThread = null;
|
gbDeviceIOThread.interrupt();
|
||||||
|
gbDeviceIOThread = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user