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
new file mode 100644
index 000000000..8da21877c
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java
@@ -0,0 +1,101 @@
+/* Copyright (C) 2023 Daniele Gobbetti, 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 android.content.Context;
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+
+import nodomain.freeyourgadget.gadgetbridge.GBException;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
+import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
+import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
+import nodomain.freeyourgadget.gadgetbridge.entities.Device;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
+import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.nothing.Ear1Support;
+
+public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoordinator {
+ @Override
+ public InstallHandler findInstallHandler(Uri uri, Context context) {
+ return null;
+ }
+
+ @Override
+ public String getManufacturer() {
+ return "Nothing";
+ }
+
+ @Override
+ public boolean supportsFindDevice() {
+ return true;
+ }
+
+ @Override
+ protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
+
+ }
+
+ @Override
+ public int getBatteryCount() {
+ return 3;
+ }
+
+ @Override
+ public BatteryConfig[] getBatteryConfig() {
+ BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case);
+ BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud);
+ BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud);
+ return new BatteryConfig[]{battery1, battery2, battery3};
+ }
+
+ @NonNull
+ @Override
+ public Class extends DeviceSupport> getDeviceSupportClass() {
+ return Ear1Support.class;
+ }
+
+ @Override
+ public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
+ return new int[]{
+ R.xml.devicesettings_nothing_ear1
+ };
+ }
+
+ @Override
+ public int getDefaultIconResource() {
+ return R.drawable.ic_device_nothingear;
+ }
+
+ @Override
+ public int getDisabledIconResource() {
+ return R.drawable.ic_device_nothingear_disabled;
+ }
+
+ @Override
+ public DeviceSpecificSettingsCustomizer getDeviceSpecificSettingsCustomizer(final GBDevice device) {
+ return new EarSettingsCustomizer();
+ }
+
+ public abstract boolean incrementCounter();
+
+ public abstract boolean supportsLightAncAndTransparency();
+}
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 8fd1b844a..0c688a262 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
@@ -1,87 +1,27 @@
package nodomain.freeyourgadget.gadgetbridge.devices.nothing;
-import android.content.Context;
-import android.net.Uri;
-
-import androidx.annotation.NonNull;
-
import java.util.regex.Pattern;
-import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator;
-import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
-import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
-import nodomain.freeyourgadget.gadgetbridge.entities.Device;
-import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
-import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
-import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.nothing.Ear1Support;
-public class Ear1Coordinator extends AbstractBLClassicDeviceCoordinator {
+public class Ear1Coordinator extends AbstractEarCoordinator {
@Override
protected Pattern getSupportedDeviceName() {
return Pattern.compile("Nothing ear (1)", Pattern.LITERAL);
}
- @Override
- public InstallHandler findInstallHandler(Uri uri, Context context) {
- return null;
- }
-
- @Override
- public String getManufacturer() {
- return "Nothing";
- }
-
- @Override
- public boolean supportsFindDevice() {
- return true;
- }
-
- @Override
- protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
-
- }
-
- @Override
- public int getBatteryCount() {
- return 3;
- }
-
- @Override
- public BatteryConfig[] getBatteryConfig() {
- BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case);
- BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud);
- BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud);
- return new BatteryConfig[]{battery1, battery2, battery3};
- }
-
- @NonNull
- @Override
- public Class extends DeviceSupport> getDeviceSupportClass() {
- return Ear1Support.class;
- }
-
- @Override
- public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
- return new int[] {
- R.xml.devicesettings_nothing_ear1
- };
- }
-
@Override
public int getDeviceNameResource() {
return R.string.devicetype_nothingear1;
}
@Override
- public int getDefaultIconResource() {
- return R.drawable.ic_device_nothingear;
+ public boolean incrementCounter() {
+ return false;
}
@Override
- public int getDisabledIconResource() {
- return R.drawable.ic_device_nothingear_disabled;
+ public boolean supportsLightAncAndTransparency() {
+ 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 367f9ac42..33c074700 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
@@ -16,88 +16,28 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.devices.nothing;
-import android.content.Context;
-import android.net.Uri;
-
-import androidx.annotation.NonNull;
-
import java.util.regex.Pattern;
-import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator;
-import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
-import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
-import nodomain.freeyourgadget.gadgetbridge.entities.Device;
-import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
-import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
-import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.nothing.Ear1Support;
-public class Ear2Coordinator extends AbstractBLClassicDeviceCoordinator {
+public class Ear2Coordinator extends AbstractEarCoordinator {
@Override
protected Pattern getSupportedDeviceName() {
return Pattern.compile("Ear (2)", Pattern.LITERAL);
}
- @Override
- public InstallHandler findInstallHandler(Uri uri, Context context) {
- return null;
- }
-
- @Override
- public String getManufacturer() {
- return "Nothing";
- }
-
- @Override
- public boolean supportsFindDevice() {
- return true;
- }
-
- @Override
- protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
-
- }
-
- @Override
- public int getBatteryCount() {
- return 3;
- }
-
- @Override
- public BatteryConfig[] getBatteryConfig() {
- BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case);
- BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud);
- BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud);
- return new BatteryConfig[]{battery1, battery2, battery3};
- }
-
- @NonNull
- @Override
- public Class extends DeviceSupport> getDeviceSupportClass() {
- return Ear1Support.class;
- }
-
- @Override
- public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
- return new int[] {
- R.xml.devicesettings_nothing_ear1
- };
- }
-
@Override
public int getDeviceNameResource() {
return R.string.devicetype_nothingear2;
}
@Override
- public int getDefaultIconResource() {
- return R.drawable.ic_device_nothingear;
+ public boolean incrementCounter() {
+ return false;
}
@Override
- public int getDisabledIconResource() {
- return R.drawable.ic_device_nothingear_disabled;
+ public boolean supportsLightAncAndTransparency() {
+ return true;
}
}
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
new file mode 100644
index 000000000..5c0277953
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarSettingsCustomizer.java
@@ -0,0 +1,92 @@
+/* Copyright (C) 2023 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 android.os.Parcel;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
+import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
+
+public class EarSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
+ @Override
+ public void onPreferenceChange(final Preference preference, final DeviceSpecificSettingsHandler handler) {
+ }
+
+ @Override
+ public void customizeSettings(final DeviceSpecificSettingsHandler handler, final Prefs prefs) {
+ final AbstractEarCoordinator earCoordinator = (AbstractEarCoordinator) handler.getDevice().getDeviceCoordinator();
+
+ if (!earCoordinator.supportsLightAncAndTransparency()) {
+ // If light anc and transparency is not supported, remove the values from the preference
+ final Preference audioModePref = handler.findPreference(DeviceSettingsPreferenceConst.PREF_NOTHING_EAR1_AUDIOMODE);
+
+ if (audioModePref != null) {
+ final CharSequence[] originalEntries = ((ListPreference) audioModePref).getEntries();
+ final CharSequence[] originalEntryValues = ((ListPreference) audioModePref).getEntryValues();
+
+ final List entries = new ArrayList<>();
+ 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]);
+ }
+ }
+
+ ((ListPreference) audioModePref).setEntries(entries.toArray(new CharSequence[0]));
+ ((ListPreference) audioModePref).setEntryValues(entryValues.toArray(new CharSequence[0]));
+ }
+ }
+ }
+
+ @Override
+ public Set getPreferenceKeysWithSummary() {
+ return Collections.emptySet();
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public EarSettingsCustomizer createFromParcel(final Parcel in) {
+ return new EarSettingsCustomizer();
+ }
+
+ @Override
+ public EarSettingsCustomizer[] newArray(final int size) {
+ return new EarSettingsCustomizer[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(final Parcel dest, final int flags) {
+ }
+}
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
new file mode 100644
index 000000000..11c718198
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/EarStickCoordinator.java
@@ -0,0 +1,43 @@
+/* Copyright (C) 2023 Daniele Gobbetti, 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 EarStickCoordinator extends AbstractEarCoordinator {
+ @Override
+ protected Pattern getSupportedDeviceName() {
+ return Pattern.compile("Ear (stick)", Pattern.LITERAL);
+ }
+
+ @Override
+ public int getDeviceNameResource() {
+ return R.string.devicetype_nothingearstick;
+ }
+
+ @Override
+ public boolean incrementCounter() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsLightAncAndTransparency() {
+ 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 b1a9777f5..7d8a03bb8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -115,6 +115,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miscale2.MiScale2DeviceCoord
import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear2Coordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.nothing.EarStickCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nut.NutCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pinetime.PineTimeJFCoordinator;
@@ -279,6 +280,7 @@ public enum DeviceType {
DOMYOS_T540(DomyosT540Coordinator.class),
NOTHING_EAR1(Ear1Coordinator.class),
NOTHING_EAR2(Ear2Coordinator.class),
+ NOTHING_EAR_STICK(EarStickCoordinator.class),
GALAXY_BUDS_PRO(GalaxyBudsProDeviceCoordinator.class),
GALAXY_BUDS_LIVE(GalaxyBudsLiveDeviceCoordinator.class),
GALAXY_BUDS(GalaxyBudsDeviceCoordinator.class),
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/NothingProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/NothingProtocol.java
index 9f773553c..e3de16717 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/NothingProtocol.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/nothing/NothingProtocol.java
@@ -20,6 +20,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
+import nodomain.freeyourgadget.gadgetbridge.devices.nothing.AbstractEarCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
@@ -61,6 +62,8 @@ public class NothingProtocol extends GBDeviceProtocol {
private static final short in_ear_detection = (short) 0xf004;
private static final short audio_mode = (short) 0xf00f;
+ private final boolean incrementCounter;
+ private int messageCounter = 0x00;
private HashMap batteries;
private static final byte battery_earphone_left = 0x02;
@@ -133,10 +136,16 @@ public class NothingProtocol extends GBDeviceProtocol {
ByteBuffer msgBuf = ByteBuffer.allocate(8 + payload.length);
msgBuf.order(ByteOrder.LITTLE_ENDIAN);
msgBuf.put((byte) 0x55); //sof
- msgBuf.putShort(control);
+ msgBuf.putShort((short) (incrementCounter ? (control | 0x40) : control));
msgBuf.putShort(command);
msgBuf.putShort((short) payload.length);
- msgBuf.put((byte) 0x00); //fsn TODO: is this always 0?
+ msgBuf.put((byte) messageCounter); //fsn
+ if (incrementCounter) {
+ messageCounter++;
+ if ((byte) messageCounter == (byte) 0xfd) {
+ messageCounter = 0x00;
+ }
+ }
msgBuf.put(payload);
if (isCrcNeeded(control)) {
@@ -294,8 +303,13 @@ public class NothingProtocol extends GBDeviceProtocol {
return (byte) ((control & MASK_DEVICE_TYPE) >> 8);
}
+ private AbstractEarCoordinator getCoordinator() {
+ return (AbstractEarCoordinator) getDevice().getDeviceCoordinator();
+ }
+
protected NothingProtocol(GBDevice device) {
super(device);
+
batteries = new HashMap<>(3);
batteries.put(battery_earphone_left, new GBDeviceEventBatteryInfo());
@@ -306,5 +320,6 @@ public class NothingProtocol extends GBDeviceProtocol {
batteries.get(battery_earphone_left).batteryIndex=1;
batteries.get(battery_earphone_right).batteryIndex=2;
+ incrementCounter = getCoordinator().incrementCounter();
}
}
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index d09fb8b3f..c57150f86 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -2820,8 +2820,15 @@
- 2
- 3
-
-
+
+
+ - @string/prefs_active_noise_cancelling
+ - @string/prefs_active_noise_cancelling_light
+ - @string/prefs_active_noise_cancelling_transparency
+ - @string/off
+
+
+
- anc
- anc-light
- transparency
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index aa487bdfe..c7e09d949 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1961,6 +1961,7 @@
Frequency of measurements
Nothing Ear (1)
Nothing Ear (2)
+ Nothing Ear (Stick)
Galaxy Buds
Galaxy Buds Live
Galaxy Buds Pro
@@ -2001,6 +2002,8 @@
Ambient Mode
Ambient Sound Options
Active Noise Cancelling
+ Light Active Noise Cancelling
+ Transparency
Active Noise Cancelling Level
High
Low
diff --git a/app/src/main/res/xml/devicesettings_nothing_ear1.xml b/app/src/main/res/xml/devicesettings_nothing_ear1.xml
index 746624935..05dd62534 100644
--- a/app/src/main/res/xml/devicesettings_nothing_ear1.xml
+++ b/app/src/main/res/xml/devicesettings_nothing_ear1.xml
@@ -8,8 +8,8 @@
android:title="@string/nothing_prefs_inear_title" />