mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 09:01:55 +01:00
Initial GadgetBridge support for Sony WF-C510
This commit is contained in:
parent
8ece86c19b
commit
b00248ce45
@ -24,6 +24,7 @@ public enum SonyHeadphonesCapabilities {
|
|||||||
PowerOffFromPhone,
|
PowerOffFromPhone,
|
||||||
AmbientSoundControl,
|
AmbientSoundControl,
|
||||||
AmbientSoundControl2,
|
AmbientSoundControl2,
|
||||||
|
NoNoiseCancelling,
|
||||||
WindNoiseReduction,
|
WindNoiseReduction,
|
||||||
SpeakToChatEnabled,
|
SpeakToChatEnabled,
|
||||||
SpeakToChatConfig,
|
SpeakToChatConfig,
|
||||||
|
@ -119,6 +119,8 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC
|
|||||||
if (supports(SonyHeadphonesCapabilities.AmbientSoundControl) || supports(SonyHeadphonesCapabilities.AmbientSoundControl2)) {
|
if (supports(SonyHeadphonesCapabilities.AmbientSoundControl) || supports(SonyHeadphonesCapabilities.AmbientSoundControl2)) {
|
||||||
if (supports(SonyHeadphonesCapabilities.WindNoiseReduction)) {
|
if (supports(SonyHeadphonesCapabilities.WindNoiseReduction)) {
|
||||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction);
|
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 {
|
} else {
|
||||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control);
|
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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.SonyWF1000XM4Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWF1000XM5Coordinator;
|
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.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.SonyWFC700NCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFSP800NCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFSP800NCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM2Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM2Coordinator;
|
||||||
@ -524,6 +525,7 @@ public enum DeviceType {
|
|||||||
SONY_WH_1000XM5(SonyWH1000XM5Coordinator.class),
|
SONY_WH_1000XM5(SonyWH1000XM5Coordinator.class),
|
||||||
SONY_WF_1000XM5(SonyWF1000XM5Coordinator.class),
|
SONY_WF_1000XM5(SonyWF1000XM5Coordinator.class),
|
||||||
SONY_WF_C500(SonyWFC500Coordinator.class),
|
SONY_WF_C500(SonyWFC500Coordinator.class),
|
||||||
|
SONY_WF_C510(SonyWFC510Coordinator.class),
|
||||||
SONY_WF_C700N(SonyWFC700NCoordinator.class),
|
SONY_WF_C700N(SonyWFC700NCoordinator.class),
|
||||||
SOUNDCORE_LIBERTY3_PRO(SoundcoreLiberty3ProCoordinator.class),
|
SOUNDCORE_LIBERTY3_PRO(SoundcoreLiberty3ProCoordinator.class),
|
||||||
SOUNDCORE_LIBERTY4_NC(SoundcoreLiberty4NCCoordinator.class),
|
SOUNDCORE_LIBERTY4_NC(SoundcoreLiberty4NCCoordinator.class),
|
||||||
|
@ -545,17 +545,18 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends GBDeviceEvent> handleAmbientSoundControl(final byte[] payload) {
|
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);
|
LOG.warn("Unexpected payload length {}", payload.length);
|
||||||
return Collections.emptyList();
|
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]);
|
LOG.warn("Not ambient sound control, ignoring {}", payload[1]);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean includesWindNoiseReduction = payload[1] == 0x17 && payload.length > 7;
|
final boolean includesWindNoiseReduction = payload[1] == 0x17 && payload.length > 7;
|
||||||
|
final boolean noNoiseCancelling = payload[1] == 0x22;
|
||||||
|
|
||||||
AmbientSoundControl.Mode mode = null;
|
AmbientSoundControl.Mode mode = null;
|
||||||
|
|
||||||
@ -574,6 +575,8 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
|||||||
mode = AmbientSoundControl.Mode.AMBIENT_SOUND;
|
mode = AmbientSoundControl.Mode.AMBIENT_SOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (noNoiseCancelling) {
|
||||||
|
mode = AmbientSoundControl.Mode.AMBIENT_SOUND;
|
||||||
} else {
|
} else {
|
||||||
if (payload[4] == (byte) 0x00) {
|
if (payload[4] == (byte) 0x00) {
|
||||||
mode = AmbientSoundControl.Mode.NOISE_CANCELLING;
|
mode = AmbientSoundControl.Mode.NOISE_CANCELLING;
|
||||||
@ -588,7 +591,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = includesWindNoiseReduction ? 6 : 5;
|
int i = payload.length - 2;
|
||||||
final Boolean focusOnVoice = booleanFromByte(payload[i]);
|
final Boolean focusOnVoice = booleanFromByte(payload[i]);
|
||||||
if (focusOnVoice == null) {
|
if (focusOnVoice == null) {
|
||||||
LOG.warn("Unknown focus on voice mode {}", String.format("%02x", payload[i]));
|
LOG.warn("Unknown focus on voice mode {}", String.format("%02x", payload[i]));
|
||||||
@ -1078,7 +1081,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 {
|
|||||||
case OFF:
|
case OFF:
|
||||||
return (byte) 0xff;
|
return (byte) 0xff;
|
||||||
case AMBIENT_SOUND_CONTROL:
|
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:
|
case PLAYBACK_CONTROL:
|
||||||
return (byte) 0x20;
|
return (byte) 0x20;
|
||||||
case VOLUME_CONTROL:
|
case VOLUME_CONTROL:
|
||||||
|
@ -3560,6 +3560,16 @@
|
|||||||
<item>ambient_sound</item>
|
<item>ambient_sound</item>
|
||||||
</string-array>
|
</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">
|
<string-array name="sony_protocol_version_names">
|
||||||
<item>@string/automatic</item>
|
<item>@string/automatic</item>
|
||||||
<item>@string/sony_protocol_v1</item>
|
<item>@string/sony_protocol_v1</item>
|
||||||
|
@ -1844,6 +1844,7 @@
|
|||||||
<string name="devicetype_sony_wf_1000xm4">Sony WF-1000XM4</string>
|
<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_1000xm5">Sony WF-1000XM5</string>
|
||||||
<string name="devicetype_sony_wf_c500">Sony WF-C500</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_wf_c700n">Sony WF-C700N</string>
|
||||||
<string name="devicetype_sony_wi_c100">Sony WI-C100</string>
|
<string name="devicetype_sony_wi_c100">Sony WI-C100</string>
|
||||||
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>
|
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>
|
||||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user