diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java index d06defdf37..16962d180e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java @@ -82,5 +82,11 @@ public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoor public abstract boolean incrementCounter(); - public abstract boolean supportsLightAncAndTransparency(); + public boolean supportsInEarDetection() { + return true; + } + + public abstract boolean supportsLightAnc(); + + public abstract boolean supportsTransparency(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java index 1285c25ad7..3298a78eaf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2Coordinator.java @@ -37,7 +37,12 @@ public class CmfBuds2Coordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return true; + } + + @Override + public boolean supportsTransparency() { return true; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java new file mode 100644 index 0000000000..24ea61bc64 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBuds2aCoordinator.java @@ -0,0 +1,58 @@ +/* Copyright (C) 2026 José Rebelo + + 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 . */ +package nodomain.freeyourgadget.gadgetbridge.devices.nothing; + +import java.util.regex.Pattern; + +import nodomain.freeyourgadget.gadgetbridge.R; + +public class CmfBuds2aCoordinator extends AbstractEarCoordinator { + @Override + public boolean isExperimental() { + return true; + } + + @Override + protected Pattern getSupportedDeviceName() { + return Pattern.compile("^CMF Buds 2a$"); + } + + @Override + public int getDeviceNameResource() { + return R.string.devicetype_nothing_cmf_buds_2a; + } + + @Override + public boolean incrementCounter() { + return true; + } + + @Override + public boolean supportsInEarDetection() { + return false; + } + + @Override + public boolean supportsLightAnc() { + return false; + } + + @Override + public boolean supportsTransparency() { + return true; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java index 6f2f3e4d9b..969afbac51 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/CmfBudsPro2Coordinator.java @@ -37,7 +37,12 @@ public class CmfBudsPro2Coordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return true; + } + + @Override + public boolean supportsTransparency() { return true; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java index 6707d891cf..1c096dc199 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear1Coordinator.java @@ -38,7 +38,12 @@ public class Ear1Coordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return true; + } + + @Override + public boolean supportsTransparency() { return true; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java index e5b1a0e602..7306a280f3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/Ear2Coordinator.java @@ -37,7 +37,12 @@ public class Ear2Coordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return true; + } + + @Override + public boolean supportsTransparency() { return true; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java index 6bc59099f0..538f704e8d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarACoordinator.java @@ -37,7 +37,12 @@ public class EarACoordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return false; + } + + @Override + public boolean supportsTransparency() { return false; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java index 0d5564b58d..e57e69f283 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java @@ -52,7 +52,14 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer { public void customizeSettings(final DeviceSpecificSettingsHandler handler, final Prefs prefs, final String rootKey) { final AbstractEarCoordinator earCoordinator = (AbstractEarCoordinator) handler.getDevice().getDeviceCoordinator(); - if (!earCoordinator.supportsLightAncAndTransparency()) { + if (!earCoordinator.supportsInEarDetection()) { + final Preference inEarPreference = handler.findPreference(DeviceSettingsPreferenceConst.PREF_NOTHING_EAR1_INEAR); + if (inEarPreference != null) { + inEarPreference.setVisible(false); + } + } + + if (!earCoordinator.supportsLightAnc() || !earCoordinator.supportsTransparency()) { // If light anc and transparency is not supported, remove the values from the preference final Preference audioModePref = handler.findPreference(DeviceSettingsPreferenceConst.PREF_NOTHING_EAR1_AUDIOMODE); @@ -64,10 +71,14 @@ public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer { final List entryValues = new ArrayList<>(); for (int i = 0; i < originalEntries.length; i++) { - if ("anc".equals(originalEntryValues[i].toString()) || "off".equals(originalEntryValues[i].toString())) { - entries.add(originalEntries[i]); - entryValues.add(originalEntryValues[i]); + if ("anclight".equals(originalEntryValues[i].toString()) && !earCoordinator.supportsLightAnc()) { + continue; } + if ("transparency".equals(originalEntryValues[i].toString()) && !earCoordinator.supportsTransparency()) { + continue; + } + entries.add(originalEntries[i]); + entryValues.add(originalEntryValues[i]); } ((ListPreference) audioModePref).setEntries(entries.toArray(new CharSequence[0])); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java index 1200ec4044..324fc541c7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java @@ -37,7 +37,12 @@ public class EarStickCoordinator extends AbstractEarCoordinator { } @Override - public boolean supportsLightAncAndTransparency() { + public boolean supportsLightAnc() { + return false; + } + + @Override + public boolean supportsTransparency() { return false; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index a3f615166b..124d23ea9d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -353,6 +353,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.ViranC29Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.ZL02DCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBuds2Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBuds2aCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.nothing.CmfBudsPro2Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear1Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear2Coordinator; @@ -761,6 +762,7 @@ public enum DeviceType { NOTHING_EAR_A(EarACoordinator.class), NOTHING_EAR_STICK(EarStickCoordinator.class), NOTHING_CMF_BUDS_2(CmfBuds2Coordinator.class), + NOTHING_CMF_BUDS_2A(CmfBuds2aCoordinator.class), NOTHING_CMF_BUDS_PRO_2(CmfBudsPro2Coordinator.class), NOTHING_CMF_WATCH_PRO(CmfWatchProCoordinator.class), NOTHING_CMF_WATCH_PRO_2(CmfWatchPro2Coordinator.class), diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 302289411d..5362882baa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3150,6 +3150,7 @@ Nothing Ear (a) Nothing Ear (Stick) CMF Buds 2 + CMF Buds 2a CMF Buds Pro 2 CMF Watch Pro CMF Watch Pro 2 diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java index 5fe33e96a9..234f693fb8 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinatorTest.java @@ -30,6 +30,7 @@ public class AbstractDeviceCoordinatorTest extends TestBase { put("Xiaomi Band 9 Active AB01", DeviceType.MIBAND9ACTIVE); put("vívoactive 6", DeviceType.GARMIN_VIVOACTIVE_6); put("CMF Buds 2", DeviceType.NOTHING_CMF_BUDS_2); // #5579 + put("CMF Buds 2a", DeviceType.NOTHING_CMF_BUDS_2A); // #6028 put("HC96", DeviceType.HC96); put("P8", DeviceType.WASPOS); // from wasp-os source put("P8DFU", DeviceType.WASPOS); // from wasp-os source