diff --git a/CHANGELOG.md b/CHANGELOG.md
index 30e916659..f5f555c22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
#### Next Version
* Initial support for Amazfit GTR 3 Pro
+* Initial support for Sony WH-1000XM5
* Amazfit Bip U: Remove alarm snooze option
* Amazfit GTR 4 / GTS 4: Add watch Wi-Fi Hotspot and FTP Server
* Amazfit GTR 4 / GTS 4: Perform and receive phone calls on watch
diff --git a/README.md b/README.md
index 1b7733801..967d85fc6 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ vendor's servers.
- [SMA](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SMA) Q2 (SMA-Q2-OSS Firmware)
- [Sony Headphones](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Headphones)
- LinkBuds S
- - WH-1000XM2, WH-1000XM3, WH-1000XM4
+ - WH-1000XM2, WH-1000XM3, WH-1000XM4, WH-1000XM5
- WF-SP800N
- WF-1000XM3, WF-1000XM4
- Teclast H10, H30
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM5Coordinator.java
new file mode 100644
index 000000000..02879c796
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM5Coordinator.java
@@ -0,0 +1,65 @@
+/* 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.sony.headphones.coordinators;
+
+import androidx.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
+
+public class SonyWH1000XM5Coordinator extends SonyHeadphonesCoordinator {
+ @NonNull
+ @Override
+ public DeviceType getSupportedType(final GBDeviceCandidate candidate) {
+ if (candidate.getName().contains("WH-1000XM5")) {
+ return DeviceType.SONY_WH_1000XM5;
+ }
+
+ return DeviceType.UNKNOWN;
+ }
+
+ @Override
+ public DeviceType getDeviceType() {
+ return DeviceType.SONY_WH_1000XM5;
+ }
+
+ @Override
+ public List getCapabilities() {
+ return Arrays.asList(
+ // TODO R.xml.devicesettings_connect_two_devices,
+ // TODO automatic ANC depending on state (might need phone?)
+ SonyHeadphonesCapabilities.BatterySingle,
+ // TODO SonyHeadphonesCapabilities.PowerOffFromPhone,
+ SonyHeadphonesCapabilities.AmbientSoundControl,
+ SonyHeadphonesCapabilities.SpeakToChatEnabled,
+ SonyHeadphonesCapabilities.SpeakToChatConfig,
+ // TODO SonyHeadphonesCapabilities.AudioUpsampling,
+ // TODO SonyHeadphonesCapabilities.AmbientSoundControlButtonMode,
+ SonyHeadphonesCapabilities.VoiceNotifications,
+ SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff,
+ // TODO SonyHeadphonesCapabilities.TouchSensorSingle,
+ SonyHeadphonesCapabilities.EqualizerWithCustomBands,
+ SonyHeadphonesCapabilities.QuickAccess,
+ SonyHeadphonesCapabilities.PauseWhenTakenOff
+ );
+ }
+}
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 e8121df88..a7a32614c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -124,6 +124,7 @@ public enum DeviceType {
SONY_WH_1000XM2(434, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm2),
SONY_WF_1000XM4(435, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_sony_wf_1000xm4),
SONY_LINKBUDS_S(436, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_sony_linkbuds_s),
+ SONY_WH_1000XM5(437, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm5),
BOSE_QC35(440, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_bose_qc35),
VESC_NRF(500, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc),
VESC_HM10(501, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc),
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
index 7a27663fe..d5ba1829b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
@@ -353,6 +353,8 @@ public class DeviceSupportFactory {
return new ServiceDeviceSupport(new SonyHeadphonesSupport());
case SONY_LINKBUDS_S:
return new ServiceDeviceSupport(new SonyHeadphonesSupport());
+ case SONY_WH_1000XM5:
+ return new ServiceDeviceSupport(new SonyHeadphonesSupport());
case VESC_NRF:
case VESC_HM10:
return new ServiceDeviceSupport(new VescDeviceSupport(device.getType()));
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 56be60083..88d6eff2a 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
@@ -117,8 +117,11 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
break;
case 0x03:
// LinkBuds S 2.0.2: 01:00:03:00:00:07:00:00
- default:
+ // WH-1000XM5 1.1.3: 01:00:03:00:00:00:00:00
protocolImpl = new SonyProtocolImplV3(getDevice());
+ break;
+ default:
+ LOG.error("Unexpected version for payload of length 8: {}", message.getPayload()[2]);
return null;
}
} else {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3.java
index f006ba27d..8b542e791 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3.java
@@ -21,24 +21,22 @@ import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.Collections;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities;
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.ButtonModes;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.QuickAccess;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChatConfig;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChatEnabled;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.MessageType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.PayloadTypeV1;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.BatteryType;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v2.PayloadTypeV2;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v2.SonyProtocolImplV2;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@@ -62,7 +60,7 @@ public class SonyProtocolImplV3 extends SonyProtocolImplV2 {
@Override
public Request setAmbientSoundControl(final AmbientSoundControl ambientSoundControl) {
- final ByteBuffer buf = ByteBuffer.allocate(8);
+ final ByteBuffer buf = ByteBuffer.allocate(7);
buf.put(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getCode());
buf.put((byte) 0x17);
@@ -86,6 +84,54 @@ public class SonyProtocolImplV3 extends SonyProtocolImplV2 {
return new Request(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
}
+ @Override
+ public Request setSpeakToChatEnabled(final SpeakToChatEnabled config) {
+ return new Request(
+ PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
+ (byte) 0x0c,
+ (byte) (config.isEnabled() ? 0x00 : 0x01), // TODO it's reversed?
+ (byte) 0x01
+ }
+ );
+ }
+
+ @Override
+ public Request getSpeakToChatEnabled() {
+ return new Request(
+ PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
+ (byte) 0x0c
+ }
+ );
+ }
+
+ @Override
+ public Request setSpeakToChatConfig(final SpeakToChatConfig config) {
+ return new Request(
+ PayloadTypeV1.SPEAK_TO_CHAT_CONFIG_SET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.SPEAK_TO_CHAT_CONFIG_SET.getCode(),
+ (byte) 0x0c,
+ config.getSensitivity().getCode(),
+ config.getTimeout().getCode()
+ }
+ );
+ }
+
+ @Override
+ public Request getSpeakToChatConfig() {
+ return new Request(
+ PayloadTypeV1.SPEAK_TO_CHAT_CONFIG_GET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.SPEAK_TO_CHAT_CONFIG_GET.getCode(),
+ (byte) 0x0c
+ }
+ );
+ }
+
@Override
public Request getQuickAccess() {
return new Request(
@@ -138,6 +184,49 @@ public class SonyProtocolImplV3 extends SonyProtocolImplV2 {
);
}
+ @Override
+ public Request setEqualizerCustomBands(final EqualizerCustomBands config) {
+ final ByteBuffer buf = ByteBuffer.allocate(10);
+
+ buf.put(PayloadTypeV1.EQUALIZER_SET.getCode());
+ buf.put((byte) 0x00);
+ buf.put((byte) 0xa0);
+ buf.put((byte) 0x06);
+
+ buf.put((byte) (config.getBass() + 10));
+ for (final Integer band : config.getBands()) {
+ buf.put((byte) (band + 10));
+ }
+
+ return new Request(
+ PayloadTypeV1.EQUALIZER_SET.getMessageType(),
+ buf.array()
+ );
+ }
+
+ @Override
+ public Request getVoiceNotifications() {
+ return new Request(
+ PayloadTypeV1.VOICE_NOTIFICATIONS_GET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.VOICE_NOTIFICATIONS_GET.getCode(),
+ (byte) 0x01
+ }
+ );
+ }
+
+ @Override
+ public Request setVoiceNotifications(final VoiceNotifications config) {
+ return new Request(
+ PayloadTypeV1.VOICE_NOTIFICATIONS_SET.getMessageType(),
+ new byte[]{
+ PayloadTypeV1.VOICE_NOTIFICATIONS_SET.getCode(),
+ (byte) 0x01,
+ (byte) (config.isEnabled() ? 0x00 : 0x01) // reversed?
+ }
+ );
+ }
+
@Override
public List extends GBDeviceEvent> handlePayload(final MessageType messageType, final byte[] payload) {
final PayloadTypeV3 payloadType = PayloadTypeV3.fromCode(messageType, payload[0]);
@@ -261,6 +350,35 @@ public class SonyProtocolImplV3 extends SonyProtocolImplV2 {
return Collections.singletonList(event);
}
+ public List extends GBDeviceEvent> handleVoiceNotifications(final byte[] payload) {
+ if (payload.length != 4) {
+ LOG.warn("Unexpected payload length {}", payload.length);
+ return Collections.emptyList();
+ }
+
+ boolean enabled;
+
+ // reversed?
+ switch (payload[2]) {
+ case 0x00:
+ enabled = true;
+ break;
+ case 0x01:
+ enabled = false;
+ break;
+ default:
+ LOG.warn("Unknown voice notifications code {}", String.format("%02x", payload[3]));
+ return Collections.emptyList();
+ }
+
+ LOG.debug("Voice Notifications: {}", enabled);
+
+ final GBDeviceEventUpdatePreferences event = new GBDeviceEventUpdatePreferences()
+ .withPreferences(new VoiceNotifications(enabled).toPreferences());
+
+ return Collections.singletonList(event);
+ }
+
@Override
protected ButtonModes.Mode decodeButtonMode(final byte b) {
switch (b) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
index 64618bb3c..02806f8ac 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
@@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts4mini.Amazfi
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfittrex2.AmazfitTRex2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyLinkBudsSCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.soflow.SoFlowCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM5Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.supercars.SuperCarsCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
@@ -363,6 +364,7 @@ public class DeviceHelper {
result.add(new SonyWF1000XM3Coordinator());
result.add(new SonyWH1000XM2Coordinator());
result.add(new SonyWF1000XM4Coordinator());
+ result.add(new SonyWH1000XM5Coordinator());
result.add(new QC35Coordinator());
result.add(new BinarySensorCoordinator());
result.add(new FlipperZeroCoordinator());
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8a94db093..ef8801043 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1276,6 +1276,7 @@
Sony WH-1000XM2
Sony WH-1000XM3
Sony WH-1000XM4
+ Sony WH-1000XM5
Sony WF-SP800N
Sony WF-1000XM3
Sony WF-1000XM4
diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3Test.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3Test.java
index 4f3d7c71e..2fc5c74ae 100644
--- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3Test.java
+++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v3/SonyProtocolImplV3Test.java
@@ -20,10 +20,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.SonyTestUtils.assertPrefs;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.SonyTestUtils.assertRequest;
+import static nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.SonyTestUtils.assertRequests;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.SonyTestUtils.handleMessage;
+import org.junit.Before;
import org.junit.Test;
+import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -32,19 +35,69 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyLinkBudsSCoordinator;
+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.AutomaticPowerOff;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands;
+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.SpeakToChatConfig;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SpeakToChatEnabled;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Request;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.MockSonyCoordinator;
public class SonyProtocolImplV3Test {
+ private final MockSonyCoordinator coordinator = new MockSonyCoordinator();
private final SonyProtocolImplV3 protocol = new SonyProtocolImplV3(null) {
@Override
protected SonyHeadphonesCoordinator getCoordinator() {
- return new SonyLinkBudsSCoordinator();
+ return coordinator;
}
};
+ @Before
+ public void before() {
+ coordinator.getCapabilities().clear();
+ }
+
+ @Test
+ public void setAmbientSoundControl() {
+ final Map commands = new LinkedHashMap() {{
+ put(new AmbientSoundControl(AmbientSoundControl.Mode.AMBIENT_SOUND, false, 20), "68:17:01:01:01:00:14");
+ put(new AmbientSoundControl(AmbientSoundControl.Mode.OFF, false, 20), "68:17:01:00:00:00:14");
+ put(new AmbientSoundControl(AmbientSoundControl.Mode.AMBIENT_SOUND, false, 10), "68:17:01:01:01:00:0a");
+ put(new AmbientSoundControl(AmbientSoundControl.Mode.AMBIENT_SOUND, true, 20), "68:17:01:01:01:01:14");
+ put(new AmbientSoundControl(AmbientSoundControl.Mode.NOISE_CANCELLING, false, 20), "68:17:01:01:00:00:14");
+ }};
+
+ for (Map.Entry entry : commands.entrySet()) {
+ final Request request = protocol.setAmbientSoundControl(entry.getKey());
+ assertRequest(request, 0x0c, entry.getValue());
+ }
+ }
+
+ @Test
+ public void setSpeakToChatEnabled() {
+ assertRequests(protocol::setSpeakToChatEnabled, new LinkedHashMap() {{
+ put(new SpeakToChatEnabled(false), "f8:0c:01:01");
+ put(new SpeakToChatEnabled(true), "f8:0c:00:01");
+ }});
+ }
+
+ @Test
+ public void setSpeakToChatConfig() {
+ assertRequests(protocol::setSpeakToChatConfig, new LinkedHashMap() {{
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.HIGH, SpeakToChatConfig.Timeout.STANDARD), "fc:0c:01:01");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.LOW, SpeakToChatConfig.Timeout.STANDARD), "fc:0c:02:01");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.AUTO, SpeakToChatConfig.Timeout.STANDARD), "fc:0c:00:01");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.AUTO, SpeakToChatConfig.Timeout.SHORT), "fc:0c:00:00");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.AUTO, SpeakToChatConfig.Timeout.LONG), "fc:0c:00:02");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.AUTO, SpeakToChatConfig.Timeout.OFF), "fc:0c:00:03");
+ put(new SpeakToChatConfig(false, SpeakToChatConfig.Sensitivity.AUTO, SpeakToChatConfig.Timeout.STANDARD), "fc:0c:00:01");
+ }});
+ }
+
@Test
public void getQuickAccess() {
final Request request = protocol.getQuickAccess();
@@ -86,6 +139,42 @@ public class SonyProtocolImplV3Test {
}
}
+ @Test
+ public void setPauseWhenTakenOff() {
+ assertRequests(protocol::setPauseWhenTakenOff, new LinkedHashMap() {{
+ put(new PauseWhenTakenOff(false), "f8:01:01");
+ put(new PauseWhenTakenOff(true), "f8:01:00");
+ }});
+ }
+
+ @Test
+ public void setEqualizerCustomBands() {
+ assertRequests(protocol::setEqualizerCustomBands, new LinkedHashMap() {{
+ put(new EqualizerCustomBands(Arrays.asList(0, 1, 2, 3, 1), 0), "58:00:a0:06:0a:0a:0b:0c:0d:0b");
+ put(new EqualizerCustomBands(Arrays.asList(0, 1, 2, 3, 5), 0), "58:00:a0:06:0a:0a:0b:0c:0d:0f");
+ put(new EqualizerCustomBands(Arrays.asList(0, 1, 2, 4, 5), 0), "58:00:a0:06:0a:0a:0b:0c:0e:0f");
+ put(new EqualizerCustomBands(Arrays.asList(5, 1, 2, 3, 5), 0), "58:00:a0:06:0a:0f:0b:0c:0d:0f");
+ put(new EqualizerCustomBands(Arrays.asList(0, 1, 2, 3, 5), -6), "58:00:a0:06:04:0a:0b:0c:0d:0f");
+ put(new EqualizerCustomBands(Arrays.asList(0, 1, 2, 3, 5), 10), "58:00:a0:06:14:0a:0b:0c:0d:0f");
+ }});
+ }
+
+ @Test
+ public void setAutomaticPowerOff() {
+ assertRequests(protocol::setAutomaticPowerOff, new LinkedHashMap() {{
+ put(AutomaticPowerOff.OFF, "28:05:11:00");
+ put(AutomaticPowerOff.WHEN_TAKEN_OFF, "28:05:10:00");
+ }});
+ }
+
+ @Test
+ public void setVoiceNotifications() {
+ assertRequests(protocol::setVoiceNotifications, 0x0e, new LinkedHashMap() {{
+ put(new VoiceNotifications(false), "48:01:01");
+ put(new VoiceNotifications(true), "48:01:00");
+ }});
+ }
+
@Test
public void handleQuickAccess() {
final Map commands = new LinkedHashMap() {{