Anker Soundcore Liberty 3 Pro / 4 NC: Switch to BTBR support class, add headphones features

This commit is contained in:
José Rebelo
2026-01-01 16:37:19 +00:00
parent 1dfe8d3f5e
commit 731c1717e8
5 changed files with 26 additions and 93 deletions
@@ -61,6 +61,8 @@ public class SoundcoreLiberty3ProCoordinator extends AbstractBLClassicDeviceCoor
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_sony_headphones_ambient_sound_control_button_modes);
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_soundcore_liberty_touch_options);
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_soundcore_liberty);
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS);
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS, R.xml.devicesettings_headphones);
return deviceSpecificSettings;
}
@@ -61,6 +61,8 @@ public class SoundcoreLiberty4NCCoordinator extends AbstractBLClassicDeviceCoord
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_sony_headphones_ambient_sound_control_button_modes);
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_soundcore_liberty_touch_options);
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_soundcore_liberty);
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS);
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS, R.xml.devicesettings_headphones);
return deviceSpecificSettings;
}
@@ -2,32 +2,25 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.liberty;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractHeadphoneSerialDeviceSupportV2;
public class SoundcoreLiberty3ProDeviceSupport extends AbstractSerialDeviceSupport {
public class SoundcoreLiberty3ProDeviceSupport extends AbstractHeadphoneSerialDeviceSupportV2<SoundcoreLibertyProtocol> {
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3952");
@Override
public boolean useAutoConnect() {
return false;
public SoundcoreLiberty3ProDeviceSupport() {
addSupportedService(UUID_DEVICE_CTRL);
}
@Override
protected GBDeviceProtocol createDeviceProtocol() {
protected SoundcoreLibertyProtocol createDeviceProtocol() {
return new SoundcoreLibertyProtocol(getDevice());
}
@Override
protected synchronized GBDeviceIoThread createDeviceIOThread() {
return new SoundcoreLibertyIOThread(
getDevice(),
getContext(),
(SoundcoreLibertyProtocol) getDeviceProtocol(),
UUID_DEVICE_CTRL,
this,
getBluetoothAdapter()
);
protected TransactionBuilder initializeDevice(final TransactionBuilder builder) {
builder.write(mDeviceProtocol.encodeDeviceInfoRequest());
builder.setDeviceState(GBDevice.State.INITIALIZED);
return builder;
}
}
@@ -2,32 +2,26 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.liberty;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractHeadphoneSerialDeviceSupportV2;
public class SoundcoreLiberty4NCDeviceSupport extends AbstractSerialDeviceSupport {
public class SoundcoreLiberty4NCDeviceSupport extends AbstractHeadphoneSerialDeviceSupportV2<SoundcoreLibertyProtocol> {
public static final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3947");
@Override
public boolean useAutoConnect() {
return false;
public SoundcoreLiberty4NCDeviceSupport() {
addSupportedService(UUID_DEVICE_CTRL);
}
@Override
protected GBDeviceProtocol createDeviceProtocol() {
protected SoundcoreLibertyProtocol createDeviceProtocol() {
return new SoundcoreLibertyProtocol(getDevice());
}
@Override
protected synchronized GBDeviceIoThread createDeviceIOThread() {
return new SoundcoreLibertyIOThread(
getDevice(),
getContext(),
(SoundcoreLibertyProtocol) getDeviceProtocol(),
UUID_DEVICE_CTRL,
this,
getBluetoothAdapter()
);
protected TransactionBuilder initializeDevice(final TransactionBuilder builder) {
builder.write(mDeviceProtocol.encodeDeviceInfoRequest());
builder.setDeviceState(GBDevice.State.INITIALIZED);
return builder;
}
}
@@ -1,58 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.liberty;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.ParcelUuid;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
public class SoundcoreLibertyIOThread extends BtClassicIoThread {
private static final Logger LOG = LoggerFactory.getLogger(SoundcoreLibertyIOThread.class);
private final SoundcoreLibertyProtocol mSoundcoreProtocol;
private final UUID mUuidToConnect;
public SoundcoreLibertyIOThread(final GBDevice gbDevice,
final Context context,
final SoundcoreLibertyProtocol deviceProtocol,
final UUID uuidToConnect,
final AbstractSerialDeviceSupport deviceSupport,
final BluetoothAdapter btAdapter) {
super(gbDevice, context, deviceProtocol, deviceSupport, btAdapter);
mSoundcoreProtocol = deviceProtocol;
mUuidToConnect = uuidToConnect;
}
@Override
protected void initialize() {
write(mSoundcoreProtocol.encodeDeviceInfoRequest());
setUpdateState(GBDevice.State.INITIALIZED);
}
@Override
@NonNull
protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) {
return mUuidToConnect;
}
@Override
protected byte[] parseIncoming(InputStream inStream) throws IOException {
byte[] buffer = new byte[1048576]; //HUGE read
int bytes = inStream.read(buffer);
LOG.debug("read {} bytes. {}", bytes, hexdump(buffer, 0, bytes));
return Arrays.copyOf(buffer, bytes);
}
}