diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 96e9073bd0..3376b414d9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -552,6 +552,8 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_SONY_SURROUND_MODE = "pref_sony_surround_mode"; public static final String PREF_SONY_EQUALIZER = "pref_sony_equalizer"; public static final String PREF_SONY_EQUALIZER_MODE = "pref_sony_equalizer_mode"; + public static final String PREF_SONY_AUDIO_HD = "pref_sony_audio_hd"; + public static final String PREF_SONY_BUTTON_FUNCTION_NC_AMBIENT = "pref_sony_button_function_nc_ambient"; public static final String PREF_SONY_AUDIO_UPSAMPLING = "pref_sony_audio_upsampling"; public static final String PREF_SONY_EQUALIZER_BAND_400 = "pref_sony_equalizer_band_400"; public static final String PREF_SONY_EQUALIZER_BAND_1000 = "pref_sony_equalizer_band_1000"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 2ac30b8959..3cf1f7ec39 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -840,6 +840,8 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_6300); addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_16000); addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BASS); + addPreferenceHandlerFor(PREF_SONY_AUDIO_HD); + addPreferenceHandlerFor(PREF_SONY_BUTTON_FUNCTION_NC_AMBIENT); addPreferenceHandlerFor(PREF_SONY_AUDIO_UPSAMPLING); addPreferenceHandlerFor(PREF_SONY_TOUCH_SENSOR); addPreferenceHandlerFor(PREF_SONY_PAUSE_WHEN_TAKEN_OFF); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java index 3a10b11196..73f384cd96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java @@ -23,6 +23,7 @@ public enum SonyHeadphonesCapabilities { AmbientSoundControlButtonMode, AncOptimizer, AudioSettingsOnlyOnSbcCodec, + AudioLDAC, AudioUpsampling, AutomaticPowerOffByTime, AutomaticPowerOffWhenTakenOff, @@ -31,6 +32,7 @@ public enum SonyHeadphonesCapabilities { BatteryDual2, BatterySingle, ButtonModesLeftRight, + ButtonFunctionNcAmbient, EqualizerSimple, EqualizerWithCustomBands, NoNoiseCancelling, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java index f79db1e357..fcbf149260 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java @@ -146,6 +146,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC addSettingsUnderHeader(deviceSpecificSettings, device, R.xml.devicesettings_header_other, new LinkedHashMap<>() {{ put(SonyHeadphonesCapabilities.AudioSettingsOnlyOnSbcCodec, R.xml.devicesettings_sony_warning_wh1000xm3); + put(SonyHeadphonesCapabilities.AudioLDAC, R.xml.devicesettings_sony_headphones_audio_hd); put(SonyHeadphonesCapabilities.EqualizerSimple, R.xml.devicesettings_sony_headphones_equalizer); put(SonyHeadphonesCapabilities.EqualizerWithCustomBands, R.xml.devicesettings_sony_headphones_equalizer_with_custom_bands); put(SonyHeadphonesCapabilities.SoundPosition, R.xml.devicesettings_sony_headphones_sound_position); @@ -162,6 +163,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC put(SonyHeadphonesCapabilities.ButtonModesLeftRight, R.xml.devicesettings_sony_headphones_button_modes_left_right); put(SonyHeadphonesCapabilities.AmbientSoundControlButtonMode, R.xml.devicesettings_sony_headphones_ambient_sound_control_button_modes); put(SonyHeadphonesCapabilities.QuickAccess, R.xml.devicesettings_sony_headphones_quick_access); + put(SonyHeadphonesCapabilities.ButtonFunctionNcAmbient, R.xml.devicesettings_sony_headphones_button_function_nc_ambient); put(SonyHeadphonesCapabilities.TouchSensorSingle, R.xml.devicesettings_sony_headphones_touch_sensor_single); put(SonyHeadphonesCapabilities.PauseWhenTakenOff, R.xml.devicesettings_sony_headphones_pause_when_taken_off); put(SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, R.xml.devicesettings_automatic_power_off_when_taken_off); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java index ad80a93f45..d8f9fe482f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java @@ -47,6 +47,8 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.WindNoiseReduction, SonyHeadphonesCapabilities.AncOptimizer, SonyHeadphonesCapabilities.AudioSettingsOnlyOnSbcCodec, + SonyHeadphonesCapabilities.AudioLDAC, + SonyHeadphonesCapabilities.ButtonFunctionNcAmbient, SonyHeadphonesCapabilities.EqualizerWithCustomBands, SonyHeadphonesCapabilities.SoundPosition, SonyHeadphonesCapabilities.SurroundMode, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioLDAC.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioLDAC.java new file mode 100644 index 0000000000..5c620b9218 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioLDAC.java @@ -0,0 +1,46 @@ +/* Copyright (C) 2026 + + 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.sony.headphones.prefs; + +import android.content.SharedPreferences; + +import java.util.HashMap; +import java.util.Map; + +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; + +public class AudioLDAC { + private final boolean enabled; + + public AudioLDAC(final boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } + + public Map toPreferences() { + return new HashMap() {{ + put(DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_HD, enabled); + }}; + } + + public static AudioLDAC fromPreferences(final SharedPreferences prefs) { + return new AudioLDAC(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_HD, false)); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/ButtonFunctionNcAmbient.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/ButtonFunctionNcAmbient.java new file mode 100644 index 0000000000..556b9fc8d6 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/ButtonFunctionNcAmbient.java @@ -0,0 +1,83 @@ +/* Copyright (C) 2026 + + 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.sony.headphones.prefs; + +import android.content.SharedPreferences; + +import java.util.HashMap; +import java.util.Map; + +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; + +public class ButtonFunctionNcAmbient { + public enum Mode { + SWITCH_AMBIENT_SOUND("switch_ambient_sound", 0x00), + GOOGLE_ASSISTANT("google_assistant", 0x01), + ALEXA_ASSISTANT("alexa_assistant", 0x02); + + private final String prefValue; + private final byte code; + + Mode(final String prefValue, final int code) { + this.prefValue = prefValue; + this.code = (byte) code; + } + + public String getPrefValue() { + return prefValue; + } + + public byte getCode() { + return code; + } + + public static Mode fromPrefValue(final String prefValue) { + for (final Mode mode : values()) { + if (mode.prefValue.equals(prefValue)) { + return mode; + } + } + + return SWITCH_AMBIENT_SOUND; + } + } + + private final Mode mode; + + public ButtonFunctionNcAmbient(final Mode mode) { + this.mode = mode; + } + + public Mode getMode() { + return mode; + } + + public Map toPreferences() { + return new HashMap() {{ + put(DeviceSettingsPreferenceConst.PREF_SONY_BUTTON_FUNCTION_NC_AMBIENT, mode.getPrefValue()); + }}; + } + + public static ButtonFunctionNcAmbient fromPreferences(final SharedPreferences prefs) { + final String pref = prefs.getString( + DeviceSettingsPreferenceConst.PREF_SONY_BUTTON_FUNCTION_NC_AMBIENT, + Mode.SWITCH_AMBIENT_SOUND.getPrefValue() + ); + + return new ButtonFunctionNcAmbient(Mode.fromPrefValue(pref)); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java index 6fcebafd06..b484b8bcda 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; @@ -35,8 +36,10 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePref import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonModes; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; @@ -228,6 +231,16 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol { case DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BASS: configRequest = protocolImpl.setEqualizerCustomBands(EqualizerCustomBands.fromPreferences(prefs)); break; + case DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_HD: + configRequest = protocolImpl.setAudioLDAC(AudioLDAC.fromPreferences(prefs)); + break; + case DeviceSettingsPreferenceConst.PREF_SONY_BUTTON_FUNCTION_NC_AMBIENT: + configRequest = protocolImpl.setButtonFunctionNcAmbient(ButtonFunctionNcAmbient.fromPreferences(prefs)); + final Request rebootRequest = protocolImpl.reboot(); + if (rebootRequest != null) { + enqueueRequests(Collections.singletonList(rebootRequest)); + } + break; case DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_UPSAMPLING: configRequest = protocolImpl.setAudioUpsampling(AudioUpsampling.fromPreferences(prefs)); break; @@ -302,6 +315,28 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol { return super.encodePowerOff(); } + @Override + public byte[] encodeReset(final int flags) { + if ((flags & RESET_FLAGS_REBOOT) == 0) { + return super.encodeReset(flags); + } + + if (protocolImpl == null) { + LOG.error("No protocol implementation, ignoring reboot request"); + return super.encodeReset(flags); + } + + final Request rebootRequest = protocolImpl.reboot(); + if (rebootRequest == null) { + LOG.warn("Failed to encode reboot request"); + return super.encodeReset(flags); + } + + pendingAcks++; + + return rebootRequest.encode(sequenceNumber); + } + public byte[] encodeAck(byte sequenceNumber) { return new Message(MessageType.ACK, (byte) (1 - sequenceNumber), new byte[0]).encode(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java index fadcadfae6..38706af440 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java @@ -24,8 +24,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphon import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonModes; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; @@ -86,6 +88,10 @@ public abstract class AbstractSonyProtocolImpl { public abstract Request getAudioUpsampling(); + public abstract Request setAudioLDAC(final AudioLDAC config); + + public abstract Request setButtonFunctionNcAmbient(final ButtonFunctionNcAmbient config); + public abstract Request setAudioUpsampling(final AudioUpsampling config); public abstract Request getAutomaticPowerOff(); @@ -138,6 +144,8 @@ public abstract class AbstractSonyProtocolImpl { public abstract Request powerOff(); + public abstract Request reboot(); + public abstract Request getVolume(); public abstract Request setVolume(final int volume); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java index b620a598e2..9e40280346 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java @@ -42,8 +42,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphon import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonModes; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; @@ -259,6 +261,32 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { ); } + @Override + public Request setAudioLDAC(final AudioLDAC config) { + return new Request( + PayloadTypeV1.AUDIO_UPSAMPLING_SET.getMessageType(), + new byte[]{ + PayloadTypeV1.AUDIO_UPSAMPLING_SET.getCode(), + (byte) 0x01, + (byte) 0x00, + (byte) (config.isEnabled() ? 0x00 : 0x01) + } + ); + } + + @Override + public Request setButtonFunctionNcAmbient(final ButtonFunctionNcAmbient config) { + return new Request( + PayloadTypeV1.TOUCH_SENSOR_SET.getMessageType(), + new byte[]{ + PayloadTypeV1.TOUCH_SENSOR_SET.getCode(), + (byte) 0xd1, + (byte) 0x02, + config.getMode().getCode() + } + ); + } + @Override public Request setAudioUpsampling(final AudioUpsampling config) { return new Request( @@ -546,6 +574,19 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { ); } + @Override + public Request reboot() { + return new Request( + MessageType.COMMAND_1, + new byte[]{ + (byte) 0x98, + (byte) 0x01, + (byte) 0x02, + (byte) 0x01 + } + ); + } + @Override public Request getVolume() { return new Request( diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java index e5e6b5aea0..552eb8bf2e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java @@ -33,8 +33,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphon import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonModes; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; @@ -223,6 +225,18 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { ); } + @Override + public Request setAudioLDAC(final AudioLDAC config) { + LOG.warn("Audio LDAC not implemented for V2"); + return null; + } + + @Override + public Request setButtonFunctionNcAmbient(final ButtonFunctionNcAmbient config) { + LOG.warn("Button function NC ambient not implemented for V2"); + return null; + } + @Override public Request setAudioUpsampling(final AudioUpsampling config) { return new Request( @@ -504,6 +518,19 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { ); } + @Override + public Request reboot() { + return new Request( + MessageType.COMMAND_1, + new byte[]{ + (byte) 0x98, + (byte) 0x00, + (byte) 0x16, + (byte) 0x01 + } + ); + } + @Override public Request getVolume() { LOG.warn("Volume not implemented for V2"); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 9365819710..be2e39827f 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -4473,6 +4473,18 @@ as_off + + @string/sony_button_function_nc_ambient_switch_ambient_sound + @string/sony_button_function_nc_ambient_google_assistant + @string/sony_button_function_nc_ambient_alexa_assistant + + + + switch_ambient_sound + google_assistant + alexa_assistant + + @string/sony_button_mode_off diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index afb3e45f85..29d1ca673a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3384,7 +3384,12 @@ 6.3k 16k Clear Bass + Audio HD Audio Upsampling + NC/Ambient Button Function + Switch ambient sound + Google Assistant + Alexa Assistant Touch sensor control Recognize taps between cheeks and ears Wide area tap diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_audio_hd.xml b/app/src/main/res/xml/devicesettings_sony_headphones_audio_hd.xml new file mode 100644 index 0000000000..f73cb7e0c2 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_sony_headphones_audio_hd.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_button_function_nc_ambient.xml b/app/src/main/res/xml/devicesettings_sony_headphones_button_function_nc_ambient.xml new file mode 100644 index 0000000000..8fbeab62d0 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_sony_headphones_button_function_nc_ambient.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1Test.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1Test.java index 5c3ce9a534..00cb14f726 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1Test.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1Test.java @@ -34,8 +34,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphon import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonModes; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; @@ -221,6 +223,29 @@ public class SonyProtocolImplV1Test { }}); } + @Test + public void setAudioLDAC() { + assertRequests(protocol::setAudioLDAC, new LinkedHashMap() {{ + put(new AudioLDAC(false), "e8:01:00:01"); + put(new AudioLDAC(true), "e8:01:00:00"); + }}); + } + + @Test + public void setButtonFunctionNcAmbient() { + assertRequests(protocol::setButtonFunctionNcAmbient, new LinkedHashMap() {{ + put(new ButtonFunctionNcAmbient(ButtonFunctionNcAmbient.Mode.SWITCH_AMBIENT_SOUND), "d8:d1:02:00"); + put(new ButtonFunctionNcAmbient(ButtonFunctionNcAmbient.Mode.GOOGLE_ASSISTANT), "d8:d1:02:01"); + put(new ButtonFunctionNcAmbient(ButtonFunctionNcAmbient.Mode.ALEXA_ASSISTANT), "d8:d1:02:02"); + }}); + } + + @Test + public void reboot() { + final Request request = protocol.reboot(); + assertRequest(request, 0x0c, "98:01:02:01"); + } + @Test public void getAutomaticPowerOff() { final Request request = protocol.getAutomaticPowerOff(); diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2Test.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2Test.java index 769c5cc637..ffbfb5fac4 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2Test.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2Test.java @@ -40,8 +40,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphon import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWF1000XM4Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioLDAC; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.ButtonFunctionNcAmbient; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.PauseWhenTakenOff; @@ -174,6 +176,22 @@ public class SonyProtocolImplV2Test { assertRequest(requestDisabled, "3e:0c:01:00:00:00:03:e8:01:00:f9:3c"); } + @Test + public void setAudioLDAC() { + // TODO + } + + @Test + public void setButtonFunctionNcAmbient() { + // TODO + } + + @Test + public void reboot() { + final Request request = protocol.reboot(); + assertRequest(request, 0x0c, "98:00:16:01"); + } + @Test public void getAutomaticPowerOff() { // TODO