mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 09:01:55 +01:00
Sony WH-1000XM3/WF-SP800N: Add volume setting
This commit is contained in:
parent
059b857e45
commit
702651c119
@ -12,6 +12,7 @@
|
||||
* Huami: Persist workout raw details even if gpx has no points
|
||||
* Mi Band 5: Fix activity fetch error toast when stress monitoring is enabled
|
||||
* LeFun: Fix heart rate popup when measurement is triggered from phone
|
||||
* Sony WH-1000XM3/WF-SP800N: Add volume setting
|
||||
* Sony WH-1000XM5: Fix speak-to-chat enable/disable
|
||||
* Zepp OS: Add loyalty cards integration with Catima
|
||||
* Zepp OS: Fix reminder creation
|
||||
|
@ -39,5 +39,6 @@ public enum SonyHeadphonesCapabilities {
|
||||
SoundPosition,
|
||||
SurroundMode,
|
||||
QuickAccess,
|
||||
PauseWhenTakenOff
|
||||
PauseWhenTakenOff,
|
||||
Volume,
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC
|
||||
put(SonyHeadphonesCapabilities.SoundPosition, R.xml.devicesettings_sony_headphones_sound_position);
|
||||
put(SonyHeadphonesCapabilities.SurroundMode, R.xml.devicesettings_sony_headphones_surround_mode);
|
||||
put(SonyHeadphonesCapabilities.AudioUpsampling, R.xml.devicesettings_sony_headphones_audio_upsampling);
|
||||
put(SonyHeadphonesCapabilities.Volume, R.xml.devicesettings_volume);
|
||||
}});
|
||||
|
||||
addSettingsUnderHeader(settings, R.xml.devicesettings_header_system, new LinkedHashMap<SonyHeadphonesCapabilities, Integer>() {{
|
||||
|
@ -64,7 +64,8 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator {
|
||||
SonyHeadphonesCapabilities.ButtonModesLeftRight,
|
||||
SonyHeadphonesCapabilities.PauseWhenTakenOff,
|
||||
SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff,
|
||||
SonyHeadphonesCapabilities.VoiceNotifications
|
||||
SonyHeadphonesCapabilities.VoiceNotifications,
|
||||
SonyHeadphonesCapabilities.Volume
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator {
|
||||
SonyHeadphonesCapabilities.AudioUpsampling,
|
||||
SonyHeadphonesCapabilities.TouchSensorSingle,
|
||||
SonyHeadphonesCapabilities.AutomaticPowerOffByTime,
|
||||
SonyHeadphonesCapabilities.VoiceNotifications
|
||||
SonyHeadphonesCapabilities.VoiceNotifications,
|
||||
SonyHeadphonesCapabilities.Volume
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +201,9 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_UPSAMPLING:
|
||||
configRequest = protocolImpl.setAudioUpsampling(AudioUpsampling.fromPreferences(prefs));
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_VOLUME:
|
||||
configRequest = protocolImpl.setVolume(prefs.getInt(config, 15));
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_TOUCH_SENSOR:
|
||||
configRequest = protocolImpl.setTouchSensor(TouchSensor.fromPreferences(prefs));
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 José Rebelo
|
||||
/* Copyright (C) 2023 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.deviceevents.SonyHeadphonesEnqueueRequestEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
|
@ -126,5 +126,9 @@ public abstract class AbstractSonyProtocolImpl {
|
||||
|
||||
public abstract Request powerOff();
|
||||
|
||||
public abstract Request getVolume();
|
||||
|
||||
public abstract Request setVolume(final int volume);
|
||||
|
||||
public abstract List<? extends GBDeviceEvent> handlePayload(final MessageType messageType, final byte[] payload);
|
||||
}
|
||||
|
@ -53,6 +53,11 @@ public enum PayloadTypeV1 {
|
||||
AMBIENT_SOUND_CONTROL_SET(MessageType.COMMAND_1, 0x68),
|
||||
AMBIENT_SOUND_CONTROL_NOTIFY(MessageType.COMMAND_1, 0x69),
|
||||
|
||||
VOLUME_GET(MessageType.COMMAND_1, 0xa6),
|
||||
VOLUME_RET(MessageType.COMMAND_1, 0xa7),
|
||||
VOLUME_SET(MessageType.COMMAND_1, 0xa8),
|
||||
VOLUME_NOTIFY(MessageType.COMMAND_1, 0xa9),
|
||||
|
||||
NOISE_CANCELLING_OPTIMIZER_START(MessageType.COMMAND_1, 0x84),
|
||||
NOISE_CANCELLING_OPTIMIZER_STATUS(MessageType.COMMAND_1, 0x85),
|
||||
|
||||
|
@ -519,6 +519,31 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getVolume() {
|
||||
return new Request(
|
||||
PayloadTypeV1.VOLUME_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadTypeV1.VOLUME_GET.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x20
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request setVolume(final int volume) {
|
||||
return new Request(
|
||||
PayloadTypeV1.VOLUME_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadTypeV1.VOLUME_SET.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x20,
|
||||
(byte) volume
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends GBDeviceEvent> handlePayload(final MessageType messageType, final byte[] payload) {
|
||||
final PayloadTypeV1 payloadType = PayloadTypeV1.fromCode(messageType, payload[0]);
|
||||
@ -543,6 +568,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
case AMBIENT_SOUND_CONTROL_RET:
|
||||
case AMBIENT_SOUND_CONTROL_NOTIFY:
|
||||
return handleAmbientSoundControl(payload);
|
||||
case VOLUME_RET:
|
||||
case VOLUME_NOTIFY:
|
||||
return handleVolume(payload);
|
||||
case NOISE_CANCELLING_OPTIMIZER_STATUS:
|
||||
return handleNoiseCancellingOptimizerStatus(payload);
|
||||
case NOISE_CANCELLING_OPTIMIZER_STATE_RET:
|
||||
@ -602,6 +630,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
put(SonyHeadphonesCapabilities.PauseWhenTakenOff, getPauseWhenTakenOff());
|
||||
put(SonyHeadphonesCapabilities.AmbientSoundControlButtonMode, getAmbientSoundControlButtonMode());
|
||||
put(SonyHeadphonesCapabilities.QuickAccess, getQuickAccess());
|
||||
put(SonyHeadphonesCapabilities.Volume, getVolume());
|
||||
}};
|
||||
|
||||
for (Map.Entry<SonyHeadphonesCapabilities, Request> capabilityEntry : capabilityRequestMap.entrySet()) {
|
||||
@ -667,7 +696,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
|
||||
final AmbientSoundControl ambientSoundControl = new AmbientSoundControl(mode, focusOnVoice, ambientSound);
|
||||
|
||||
LOG.warn("Ambient sound control: {}", ambientSoundControl);
|
||||
LOG.debug("Ambient sound control: {}", ambientSoundControl);
|
||||
|
||||
final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences()
|
||||
.withPreferences(ambientSoundControl.toPreferences());
|
||||
@ -675,6 +704,37 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.singletonList(eventUpdatePreferences);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleVolume(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
AmbientSoundControl.Mode mode = null;
|
||||
|
||||
if (payload[1] != (byte) 0x01) {
|
||||
LOG.warn("Unexpected byte at position 1 for volume: {}", payload[1]);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (payload[2] != (byte) 0x20) {
|
||||
LOG.warn("Unexpected byte at position 2 for volume: {}", payload[1]);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final int volume = payload[3];
|
||||
if (volume < 0 || volume > 30) {
|
||||
LOG.warn("Volume {} is out of range", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.debug("Volume: {}", volume);
|
||||
|
||||
final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences()
|
||||
.withPreference(DeviceSettingsPreferenceConst.PREF_VOLUME, volume);
|
||||
|
||||
return Collections.singletonList(eventUpdatePreferences);
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleNoiseCancellingOptimizerStatus(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
|
@ -375,6 +375,18 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getVolume() {
|
||||
LOG.warn("Volume not implemented for V2");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request setVolume(final int volume) {
|
||||
LOG.warn("Volume not implemented for V2");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends GBDeviceEvent> handlePayload(final MessageType messageType, final byte[] payload) {
|
||||
final PayloadTypeV2 payloadType = PayloadTypeV2.fromCode(messageType, payload[0]);
|
||||
|
9
app/src/main/res/xml/devicesettings_volume.xml
Normal file
9
app/src/main/res/xml/devicesettings_volume.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<SeekBarPreference
|
||||
android:defaultValue="15"
|
||||
android:icon="@drawable/ic_volume_up"
|
||||
android:key="volume"
|
||||
android:max="30"
|
||||
android:title="@string/menuitem_volume" />
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user