mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 10:05:49 +01:00
Sony WH-1000XM4: Add speak-to-chat
This commit is contained in:
parent
da001544c5
commit
d7ecfcb16b
@ -23,6 +23,7 @@ public enum SonyHeadphonesCapabilities {
|
||||
PowerOffFromPhone,
|
||||
AmbientSoundControl,
|
||||
WindNoiseReduction,
|
||||
SpeakToChat,
|
||||
AncOptimizer,
|
||||
AudioSettingsOnlyOnSbcCodec,
|
||||
AudioUpsampling,
|
||||
|
@ -178,6 +178,10 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC
|
||||
settings.add(R.xml.devicesettings_sony_headphones_ambient_sound_control);
|
||||
}
|
||||
|
||||
if (supports(SonyHeadphonesCapabilities.SpeakToChat)) {
|
||||
settings.add(R.xml.devicesettings_sony_headphones_speak_to_chat_simple);
|
||||
}
|
||||
|
||||
if (supports(SonyHeadphonesCapabilities.AncOptimizer)) {
|
||||
settings.add(R.xml.devicesettings_sony_headphones_anc_optimizer);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ public class SonyWH1000XM4Coordinator extends SonyHeadphonesCoordinator {
|
||||
SonyHeadphonesCapabilities.BatterySingle,
|
||||
SonyHeadphonesCapabilities.AmbientSoundControl,
|
||||
SonyHeadphonesCapabilities.WindNoiseReduction,
|
||||
SonyHeadphonesCapabilities.SpeakToChat,
|
||||
SonyHeadphonesCapabilities.AncOptimizer,
|
||||
SonyHeadphonesCapabilities.EqualizerWithCustomBands,
|
||||
SonyHeadphonesCapabilities.AudioUpsampling,
|
||||
|
@ -0,0 +1,53 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
|
||||
public class SpeakToChat {
|
||||
private final boolean enabled;
|
||||
|
||||
public SpeakToChat(final boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format(Locale.getDefault(), "SpeakToChat{enabled=%s}", enabled);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Map<String, Object> toPreferences() {
|
||||
return new HashMap<String, Object>() {{
|
||||
put(DeviceSettingsPreferenceConst.PREF_SONY_SPEAK_TO_CHAT, enabled);
|
||||
}};
|
||||
}
|
||||
|
||||
public static SpeakToChat fromPreferences(final SharedPreferences prefs) {
|
||||
final boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_SPEAK_TO_CHAT, false);
|
||||
|
||||
return new SpeakToChat(enabled);
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Equali
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.PauseWhenTakenOff;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.QuickAccess;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChat;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SoundPosition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SurroundMode;
|
||||
@ -223,8 +224,8 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_SPEAK_TO_CHAT_SENSITIVITY:
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_SPEAK_TO_CHAT_FOCUS_ON_VOICE:
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_SPEAK_TO_CHAT_TIMEOUT:
|
||||
LOG.warn("Speak-to-chat is not implemented ('{}')", config);
|
||||
return super.encodeSendConfiguration(config);
|
||||
configRequest = protocolImpl.setSpeakToChat(SpeakToChat.fromPreferences(prefs));
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unknown config '{}'", config);
|
||||
return super.encodeSendConfiguration(config);
|
||||
|
@ -30,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Equali
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.PauseWhenTakenOff;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.QuickAccess;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SoundPosition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChat;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SurroundMode;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.TouchSensor;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
|
||||
@ -58,6 +59,10 @@ public abstract class AbstractSonyProtocolImpl {
|
||||
|
||||
public abstract Request setAmbientSoundControl(final AmbientSoundControl config);
|
||||
|
||||
public abstract Request setSpeakToChat(final SpeakToChat config);
|
||||
|
||||
public abstract Request getSpeakToChat();
|
||||
|
||||
public abstract Request getNoiseCancellingOptimizerState();
|
||||
|
||||
public abstract Request getAudioCodec();
|
||||
|
@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Equali
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.PauseWhenTakenOff;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.QuickAccess;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SoundPosition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChat;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SurroundMode;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.TouchSensor;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
|
||||
@ -139,6 +140,30 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return new Request(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request setSpeakToChat(final SpeakToChat config) {
|
||||
return new Request(
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
(byte) 0x05,
|
||||
(byte) 0x01,
|
||||
(byte) (config.isEnabled() ? 0x01 : 0x00)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getSpeakToChat() {
|
||||
return new Request(
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
(byte) 0x05
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getNoiseCancellingOptimizerState() {
|
||||
return new Request(
|
||||
@ -542,6 +567,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
put(SonyHeadphonesCapabilities.EqualizerWithCustomBands, getEqualizer());
|
||||
put(SonyHeadphonesCapabilities.SoundPosition, getSoundPosition());
|
||||
put(SonyHeadphonesCapabilities.SurroundMode, getSurroundMode());
|
||||
put(SonyHeadphonesCapabilities.SpeakToChat, getSpeakToChat());
|
||||
put(SonyHeadphonesCapabilities.PauseWhenTakenOff, getPauseWhenTakenOff());
|
||||
put(SonyHeadphonesCapabilities.AmbientSoundControlButtonMode, getAmbientSoundControlButtonMode());
|
||||
put(SonyHeadphonesCapabilities.QuickAccess, getQuickAccess());
|
||||
@ -707,6 +733,26 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.singletonList(event);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleSpeakToChat(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final Boolean enabled = booleanFromByte(payload[3]);
|
||||
if (enabled == null) {
|
||||
LOG.warn("Unknown speak to chat code {}", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.debug("Speak to chat: {}", enabled);
|
||||
|
||||
final GBDeviceEventUpdatePreferences event = new GBDeviceEventUpdatePreferences()
|
||||
.withPreferences(new SpeakToChat(enabled).toPreferences());
|
||||
|
||||
return Collections.singletonList(event);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleButtonModes(final byte[] payload) {
|
||||
if (payload.length != 5) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
@ -907,6 +953,8 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return handleAutomaticPowerOff(payload);
|
||||
case 0x03:
|
||||
return handlePauseWhenTakenOff(payload);
|
||||
case 0x05:
|
||||
return handleSpeakToChat(payload);
|
||||
case 0x06:
|
||||
return handleButtonModes(payload);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Equali
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.PauseWhenTakenOff;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.QuickAccess;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SoundPosition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChat;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SurroundMode;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.TouchSensor;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
|
||||
@ -104,6 +105,18 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
||||
return new Request(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request setSpeakToChat(SpeakToChat config) {
|
||||
LOG.warn("Speak-to-chat not implemented for V2");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getSpeakToChat() {
|
||||
LOG.warn("Speak-to-chat not implemented for V2");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getNoiseCancellingOptimizerState() {
|
||||
LOG.warn("Noise cancelling optimizer not implemented for V2");
|
||||
|
Loading…
Reference in New Issue
Block a user