Initial GadgetBridge support for Sony WF-C510

This commit is contained in:
Marcel 2024-12-21 10:06:38 +01:00 committed by marzn
parent 8ece86c19b
commit b00248ce45
8 changed files with 118 additions and 4 deletions

View File

@ -24,6 +24,7 @@ public enum SonyHeadphonesCapabilities {
PowerOffFromPhone,
AmbientSoundControl,
AmbientSoundControl2,
NoNoiseCancelling,
WindNoiseReduction,
SpeakToChatEnabled,
SpeakToChatConfig,

View File

@ -119,6 +119,8 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC
if (supports(SonyHeadphonesCapabilities.AmbientSoundControl) || supports(SonyHeadphonesCapabilities.AmbientSoundControl2)) {
if (supports(SonyHeadphonesCapabilities.WindNoiseReduction)) {
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction);
} else if (supports(SonyHeadphonesCapabilities.NoNoiseCancelling)) {
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control_no_noise_cancelling);
} else {
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control);
}

View File

@ -0,0 +1,63 @@
/* Copyright (C) 2024 Marcel
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator;
public class SonyWFC510Coordinator extends SonyHeadphonesCoordinator {
@Override
protected Pattern getSupportedDeviceName() {
return Pattern.compile("WF-C510");
}
@Override
public List<SonyHeadphonesCapabilities> getCapabilities() {
return Arrays.asList(
SonyHeadphonesCapabilities.BatteryDual2,
SonyHeadphonesCapabilities.BatteryCase,
SonyHeadphonesCapabilities.AmbientSoundControl2,
SonyHeadphonesCapabilities.NoNoiseCancelling,
SonyHeadphonesCapabilities.EqualizerSimple,
SonyHeadphonesCapabilities.EqualizerWithCustomBands,
SonyHeadphonesCapabilities.AudioUpsampling,
SonyHeadphonesCapabilities.ButtonModesLeftRight,
SonyHeadphonesCapabilities.PowerOffFromPhone
);
}
@Override
public int getDeviceNameResource() {
return R.string.devicetype_sony_wf_c510;
}
@Override
public int getDefaultIconResource() {
return R.drawable.ic_device_galaxy_buds;
}
@Override
public int getDisabledIconResource() {
return R.drawable.ic_device_galaxy_buds_disabled;
}
}

View File

@ -252,6 +252,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWF1000XM4Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWF1000XM5Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFC500Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFC510Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFC700NCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFSP800NCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM2Coordinator;
@ -524,6 +525,7 @@ public enum DeviceType {
SONY_WH_1000XM5(SonyWH1000XM5Coordinator.class),
SONY_WF_1000XM5(SonyWF1000XM5Coordinator.class),
SONY_WF_C500(SonyWFC500Coordinator.class),
SONY_WF_C510(SonyWFC510Coordinator.class),
SONY_WF_C700N(SonyWFC700NCoordinator.class),
SOUNDCORE_LIBERTY3_PRO(SoundcoreLiberty3ProCoordinator.class),
SOUNDCORE_LIBERTY4_NC(SoundcoreLiberty4NCCoordinator.class),

View File

@ -545,17 +545,18 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
@Override
public List<? extends GBDeviceEvent> handleAmbientSoundControl(final byte[] payload) {
if (payload.length != 8 && payload.length != 7) {
if (payload.length < 6 || payload.length > 8) {
LOG.warn("Unexpected payload length {}", payload.length);
return Collections.emptyList();
}
if (payload[1] != 0x15 && payload[1] != 0x17) {
if (payload[1] != 0x15 && payload[1] != 0x17 && payload[1] != 0x22) {
LOG.warn("Not ambient sound control, ignoring {}", payload[1]);
return Collections.emptyList();
}
final boolean includesWindNoiseReduction = payload[1] == 0x17 && payload.length > 7;
final boolean noNoiseCancelling = payload[1] == 0x22;
AmbientSoundControl.Mode mode = null;
@ -574,6 +575,8 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
mode = AmbientSoundControl.Mode.AMBIENT_SOUND;
}
}
} else if (noNoiseCancelling) {
mode = AmbientSoundControl.Mode.AMBIENT_SOUND;
} else {
if (payload[4] == (byte) 0x00) {
mode = AmbientSoundControl.Mode.NOISE_CANCELLING;
@ -588,7 +591,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
return Collections.emptyList();
}
int i = includesWindNoiseReduction ? 6 : 5;
int i = payload.length - 2;
final Boolean focusOnVoice = booleanFromByte(payload[i]);
if (focusOnVoice == null) {
LOG.warn("Unknown focus on voice mode {}", String.format("%02x", payload[i]));
@ -1078,7 +1081,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
case OFF:
return (byte) 0xff;
case AMBIENT_SOUND_CONTROL:
return (byte) (supportsWindNoiseCancelling() ? 0x35 : 0x00); // Seems to be the only one that differs?
return (byte) (supportsWindNoiseCancelling() || getCoordinator().supports(SonyHeadphonesCapabilities.NoNoiseCancelling) ? 0x35 : 0x00); // Seems to be the only one that differs?
case PLAYBACK_CONTROL:
return (byte) 0x20;
case VOLUME_CONTROL:

View File

@ -3560,6 +3560,16 @@
<item>ambient_sound</item>
</string-array>
<string-array name="sony_ambient_sound_control_no_noise_cancelling_names">
<item>@string/sony_ambient_sound_off</item>
<item>@string/sony_ambient_sound_ambient_sound</item>
</string-array>
<string-array name="sony_ambient_sound_control_no_noise_cancelling_values">
<item>off</item>
<item>ambient_sound</item>
</string-array>
<string-array name="sony_protocol_version_names">
<item>@string/automatic</item>
<item>@string/sony_protocol_v1</item>

View File

@ -1844,6 +1844,7 @@
<string name="devicetype_sony_wf_1000xm4">Sony WF-1000XM4</string>
<string name="devicetype_sony_wf_1000xm5">Sony WF-1000XM5</string>
<string name="devicetype_sony_wf_c500">Sony WF-C500</string>
<string name="devicetype_sony_wf_c510">Sony WF-C510</string>
<string name="devicetype_sony_wf_c700n">Sony WF-C700N</string>
<string name="devicetype_sony_wi_c100">Sony WI-C100</string>
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="pref_key_header_sony_ambient_sound_control"
android:title="@string/pref_header_sony_ambient_sound_control">
<ListPreference
android:defaultValue="ambient_sound"
android:entries="@array/sony_ambient_sound_control_no_noise_cancelling_names"
android:entryValues="@array/sony_ambient_sound_control_no_noise_cancelling_values"
android:icon="@drawable/ic_hearing"
android:key="pref_sony_ambient_sound_control"
android:summary="%s"
android:title="@string/sony_ambient_sound" />
<!-- [0, 19], which maps to [1, 20] on the device, as we can't configure the min on the current API level -->
<SeekBarPreference
android:defaultValue="0"
android:icon="@drawable/ic_volume_up"
android:key="pref_sony_ambient_sound_level"
android:max="19"
android:title="@string/sony_ambient_sound_level" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:icon="@drawable/ic_voice"
android:key="pref_sony_focus_voice"
android:layout="@layout/preference_checkbox"
android:title="@string/sony_ambient_sound_focus_voice" />
</PreferenceCategory>
</androidx.preference.PreferenceScreen>