From be9bf8f214a39f403fe833898b192fa4182cbd32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 28 Dec 2024 14:01:09 +0000 Subject: [PATCH] Sony Headphones: Allow overriding supported features --- .../DeviceSettingsPreferenceConst.java | 3 + .../DeviceSpecificSettingsFragment.java | 3 +- .../adapter/GBDeviceAdapterv2.java | 10 +- .../devices/AbstractDeviceCoordinator.java | 8 +- .../devices/DeviceCoordinator.java | 4 +- .../BandWPSeriesDeviceCoordinator.java | 2 +- .../coordinator/BinarySensorCoordinator.java | 2 +- .../colmi/AbstractColmiR0xCoordinator.java | 2 +- .../GalaxyBuds2DeviceCoordinator.java | 2 +- .../GalaxyBuds2ProDeviceCoordinator.java | 2 +- .../GalaxyBudsDeviceCoordinator.java | 2 +- .../GalaxyBudsLiveDeviceCoordinator.java | 2 +- .../GalaxyBudsProDeviceCoordinator.java | 2 +- .../huawei/HuaweiFreebudsCoordinator.java | 2 +- .../MiCompositionScaleCoordinator.java | 2 +- .../miscale/MiSmartScaleCoordinator.java | 2 +- .../MoondropSpaceTravelCoordinator.java | 2 +- .../nothing/AbstractEarCoordinator.java | 2 +- .../oppo/OppoHeadphonesCoordinator.java | 2 +- .../devices/roidmi/Roidmi1Coordinator.java | 3 +- .../scannable/ScannableDeviceCoordinator.java | 2 +- .../SonyHeadphonesCapabilities.java | 38 +++--- .../headphones/SonyHeadphonesCoordinator.java | 77 +++++++----- .../SonyHeadphonesSettingsCustomizer.java | 110 +++++++++++------- .../coordinators/SonyLinkBudsCoordinator.java | 9 +- .../SonyLinkBudsSCoordinator.java | 9 +- .../SonyWF1000XM3Coordinator.java | 13 +-- .../SonyWF1000XM4Coordinator.java | 9 +- .../SonyWF1000XM5Coordinator.java | 13 +-- .../coordinators/SonyWFC500Coordinator.java | 9 +- .../coordinators/SonyWFC510Coordinator.java | 9 +- .../coordinators/SonyWFC700NCoordinator.java | 9 +- .../coordinators/SonyWFSP800NCoordinator.java | 11 +- .../SonyWH1000XM2Coordinator.java | 13 +-- .../SonyWH1000XM3Coordinator.java | 13 +-- .../SonyWH1000XM4Coordinator.java | 9 +- .../SonyWH1000XM5Coordinator.java | 9 +- .../coordinators/SonyWIC100Coordinator.java | 9 +- .../coordinators/SonyWISP600NCoordinator.java | 13 +-- .../SoundcoreLiberty3ProCoordinator.java | 2 +- .../SoundcoreLiberty4NCCoordinator.java | 2 +- .../SoundcoreMotion300Coordinator.java | 4 +- .../supercars/SuperCarsCoordinator.java | 2 +- .../devices/test/TestDeviceCoordinator.java | 10 +- .../um25/Coordinator/UM25Coordinator.java | 2 +- .../AbstractRedmiBudsCoordinator.java | 2 +- .../impl/AbstractSonyProtocolImpl.java | 5 + .../protocol/impl/v1/SonyProtocolImplV1.java | 11 +- .../protocol/impl/v2/SonyProtocolImplV2.java | 8 +- app/src/main/res/values/strings.xml | 2 + .../xml/devicesettings_header_intent_api.xml | 6 + .../xml/devicesettings_override_features.xml | 20 ++++ .../protocol/impl/MockSonyCoordinator.java | 11 +- 53 files changed, 299 insertions(+), 231 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_header_intent_api.xml create mode 100644 app/src/main/res/xml/devicesettings_override_features.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 79596e55c..96bece172 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -486,6 +486,9 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_SONY_ADAPTIVE_VOLUME_CONTROL = "pref_adaptive_volume_control"; public static final String PREF_SONY_WIDE_AREA_TAP = "pref_wide_area_tap"; + public static final String PREF_OVERRIDE_FEATURES_ENABLED = "override_features_enabled"; + public static final String PREF_OVERRIDE_FEATURES_LIST = "override_features_list"; + public static final String PREF_MOONDROP_EQUALIZER_PRESET = "pref_moondrop_equalizer_preset"; public static final String PREF_MOONDROP_TOUCH_PLAY_PAUSE_EARBUD = "pref_moondrop_touch_play_pause_earbud"; public static final String PREF_MOONDROP_TOUCH_PLAY_PAUSE_TRIGGER = "pref_moondrop_touch_play_pause_trigger"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 591d1e5ba..e7c744453 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -1382,7 +1382,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i coordinator.getSupportedDeviceSpecificConnectionSettings() ); - if (coordinator.getBatteryCount() > 0) { + if (coordinator.getBatteryCount(device) > 0) { deviceSpecificSettings.addRootScreen( DeviceSpecificSettingsScreen.BATTERY ); @@ -1398,6 +1398,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i deviceSpecificSettings.addRootScreen( DeviceSpecificSettingsScreen.DEVELOPER, + R.xml.devicesettings_header_intent_api, R.xml.devicesettings_settings_third_party_apps ); if (coordinator.getConnectionType().usesBluetoothLE()) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index aab204dfc..88457164b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -353,15 +353,15 @@ public class GBDeviceAdapterv2 extends ListAdapter 0 ? View.VISIBLE : View.GONE); - holder.batteryStatusBox1.setVisibility(coordinator.getBatteryCount() > 1 ? View.VISIBLE : View.GONE); - holder.batteryStatusBox2.setVisibility(coordinator.getBatteryCount() > 2 ? View.VISIBLE : View.GONE); + holder.batteryStatusBox0.setVisibility(coordinator.getBatteryCount(device) > 0 ? View.VISIBLE : View.GONE); + holder.batteryStatusBox1.setVisibility(coordinator.getBatteryCount(device) > 1 ? View.VISIBLE : View.GONE); + holder.batteryStatusBox2.setVisibility(coordinator.getBatteryCount(device) > 2 ? View.VISIBLE : View.GONE); LinearLayout[] batteryStatusBoxes = {holder.batteryStatusBox0, holder.batteryStatusBox1, holder.batteryStatusBox2}; TextView[] batteryStatusLabels = {holder.batteryStatusLabel0, holder.batteryStatusLabel1, holder.batteryStatusLabel2}; ImageView[] batteryIcons = {holder.batteryIcon0, holder.batteryIcon1, holder.batteryIcon2}; - for (int batteryIndex = 0; batteryIndex < coordinator.getBatteryCount(); batteryIndex++) { + for (int batteryIndex = 0; batteryIndex < coordinator.getBatteryCount(device); batteryIndex++) { int batteryLevel = device.getBatteryLevel(batteryIndex); float batteryVoltage = device.getBatteryVoltage(batteryIndex); @@ -823,7 +823,7 @@ public class GBDeviceAdapterv2 extends ListAdapter batteries = new ArrayList<>(3); - if (supports(SonyHeadphonesCapabilities.BatterySingle)) { + if (supports(device, SonyHeadphonesCapabilities.BatterySingle)) { batteries.add(new BatteryConfig(batteries.size(), GBDevice.BATTERY_ICON_DEFAULT, GBDevice.BATTERY_LABEL_DEFAULT, getBatteryDefaultLowThreshold(), getBatteryDefaultFullThreshold())); } - if (supports(SonyHeadphonesCapabilities.BatteryCase)) { + if (supports(device, SonyHeadphonesCapabilities.BatteryCase)) { batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_tws_case, R.string.battery_case, getBatteryDefaultLowThreshold(), getBatteryDefaultFullThreshold())); } - if (supports(SonyHeadphonesCapabilities.BatteryDual) || supports(SonyHeadphonesCapabilities.BatteryDual2)) { + if (supports(device, SonyHeadphonesCapabilities.BatteryDual) || supports(device, SonyHeadphonesCapabilities.BatteryDual2)) { batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_galaxy_buds_l, R.string.left_earbud, getBatteryDefaultLowThreshold(), getBatteryDefaultFullThreshold())); batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_galaxy_buds_r, R.string.right_earbud, getBatteryDefaultLowThreshold(), getBatteryDefaultFullThreshold())); } @@ -116,31 +120,31 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); - if (supports(SonyHeadphonesCapabilities.AmbientSoundControl) || supports(SonyHeadphonesCapabilities.AmbientSoundControl2)) { - if (supports(SonyHeadphonesCapabilities.WindNoiseReduction)) { + if (supports(device, SonyHeadphonesCapabilities.AmbientSoundControl) || supports(device, SonyHeadphonesCapabilities.AmbientSoundControl2)) { + if (supports(device, SonyHeadphonesCapabilities.WindNoiseReduction)) { deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction); - } else if (supports(SonyHeadphonesCapabilities.NoNoiseCancelling)) { + } else if (supports(device, 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); } - if (supports(SonyHeadphonesCapabilities.AncOptimizer)) { + if (supports(device, SonyHeadphonesCapabilities.AncOptimizer)) { deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_anc_optimizer); } } - if (supports(SonyHeadphonesCapabilities.AdaptiveVolumeControl)) { + if (supports(device, SonyHeadphonesCapabilities.AdaptiveVolumeControl)) { deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_adaptive_volume_control); } - if (supports(SonyHeadphonesCapabilities.SpeakToChatConfig)) { + if (supports(device, SonyHeadphonesCapabilities.SpeakToChatConfig)) { deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_speak_to_chat_with_settings); - } else if (supports(SonyHeadphonesCapabilities.SpeakToChatEnabled)) { + } else if (supports(device, SonyHeadphonesCapabilities.SpeakToChatEnabled)) { deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_speak_to_chat_simple); } - addSettingsUnderHeader(deviceSpecificSettings, R.xml.devicesettings_header_other, new LinkedHashMap() {{ + addSettingsUnderHeader(deviceSpecificSettings, device, R.xml.devicesettings_header_other, new LinkedHashMap() {{ put(SonyHeadphonesCapabilities.AudioSettingsOnlyOnSbcCodec, R.xml.devicesettings_sony_warning_wh1000xm3); put(SonyHeadphonesCapabilities.EqualizerSimple, R.xml.devicesettings_sony_headphones_equalizer); put(SonyHeadphonesCapabilities.EqualizerWithCustomBands, R.xml.devicesettings_sony_headphones_equalizer_with_custom_bands); @@ -153,7 +157,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC final List callsAndNotif = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.CALLS_AND_NOTIFICATIONS); callsAndNotif.add(R.xml.devicesettings_headphones); - addSettingsUnderHeader(deviceSpecificSettings, R.xml.devicesettings_header_system, new LinkedHashMap() {{ + addSettingsUnderHeader(deviceSpecificSettings, device, R.xml.devicesettings_header_system, new LinkedHashMap() {{ put(SonyHeadphonesCapabilities.WideAreaTap, R.xml.devicesettings_sony_headphones_wide_area_tap); put(SonyHeadphonesCapabilities.ButtonModesLeftRight, R.xml.devicesettings_sony_headphones_button_modes_left_right); put(SonyHeadphonesCapabilities.AmbientSoundControlButtonMode, R.xml.devicesettings_sony_headphones_ambient_sound_control_button_modes); @@ -165,20 +169,30 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC put(SonyHeadphonesCapabilities.VoiceNotifications, R.xml.devicesettings_sony_headphones_notifications_voice_guide); }}); - deviceSpecificSettings.addRootScreen(R.xml.devicesettings_header_developer); - deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_protocol_version); - - deviceSpecificSettings.addRootScreen(R.xml.devicesettings_sony_headphones_device_info); + final List developer = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DEVELOPER); + developer.add(R.xml.devicesettings_override_features); + developer.add(R.xml.devicesettings_sony_headphones_protocol_version); + developer.add(R.xml.devicesettings_sony_headphones_device_info); return deviceSpecificSettings; } - public List getCapabilities() { - return Collections.emptyList(); + public Set getCapabilities() { + return Collections.emptySet(); } - public boolean supports(final SonyHeadphonesCapabilities capability) { - return getCapabilities().contains(capability); + public Set getCapabilities(final GBDevice device) { + DevicePrefs devicePrefs = GBApplication.getDevicePrefs(device); + final boolean overrideFeatures = devicePrefs.getBoolean(DeviceSettingsPreferenceConst.PREF_OVERRIDE_FEATURES_ENABLED, false); + if (overrideFeatures) { + final Set stringList = devicePrefs.getStringSet(DeviceSettingsPreferenceConst.PREF_OVERRIDE_FEATURES_LIST, Collections.emptySet()); + return stringList.stream().map(SonyHeadphonesCapabilities::valueOf).collect(Collectors.toSet()); + } + return getCapabilities(); + } + + public boolean supports(final GBDevice device, final SonyHeadphonesCapabilities capability) { + return getCapabilities(device).contains(capability); } /** @@ -189,11 +203,12 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC * @param capabilities the map of capability to preference screen */ private void addSettingsUnderHeader(final DeviceSpecificSettings deviceSpecificSettings, + final GBDevice device, final int header, final Map capabilities) { final Set supportedCapabilities = new HashSet<>(capabilities.keySet()); for (SonyHeadphonesCapabilities capability : capabilities.keySet()) { - if (!supports(capability)) { + if (!supports(device, capability)) { supportedCapabilities.remove(capability); } } @@ -206,7 +221,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC deviceSpecificSettings.addRootScreen(header); for (Map.Entry capabilitiesSetting : capabilities.entrySet()) { - if (supports(capabilitiesSetting.getKey())) { + if (supports(device, capabilitiesSetting.getKey())) { deviceSpecificSettings.addRootScreen(capabilitiesSetting.getValue()); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java index 20d072c3b..7785b3af1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java @@ -16,6 +16,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_OVERRIDE_FEATURES_LIST; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_CONTROL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_CODEC; @@ -40,8 +41,10 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Parcel; +import androidx.annotation.NonNull; import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; +import androidx.preference.MultiSelectListPreference; import androidx.preference.Preference; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -75,7 +78,7 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC // Disable equalizer, sound position and surround mode if not in SBC codec, for WH-1000XM3 // TODO: Should the coordinator be responsible for this compatibility check? if (preference.getKey().equals(PREF_SONY_AUDIO_CODEC) && device.getType().equals(DeviceType.SONY_WH_1000XM3)) { - final boolean isSbcCodec = ((EditTextPreference) preference).getText().equalsIgnoreCase("sbc"); + final boolean isSbcCodec = "sbc".equalsIgnoreCase(((EditTextPreference) preference).getText()); final List prefsToDisable = Arrays.asList( handler.findPreference(PREF_SONY_EQUALIZER), @@ -146,54 +149,81 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC final Preference ancOptimizer = handler.findPreference("pref_sony_anc_optimizer"); if (ancOptimizer != null) { - ancOptimizer.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(final Preference preference) { - if (ancOptimizerProgressDialog != null) { - // Already optimizing - return true; - } - - final Context context = preference.getContext(); - - new MaterialAlertDialogBuilder(context) - .setTitle(R.string.sony_anc_optimize_confirmation_title) - .setMessage(R.string.sony_anc_optimize_confirmation_description) - .setIcon(R.drawable.ic_hearing) - .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { - public void onClick(final DialogInterface dialog, final int whichButton) { - handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_START); - - ancOptimizerProgressDialog = new ProgressDialog(context); - ancOptimizerProgressDialog.setCancelable(false); - ancOptimizerProgressDialog.setMessage(context.getString(R.string.sony_anc_optimizer_status_starting)); - ancOptimizerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - ancOptimizerProgressDialog.setProgress(0); - ancOptimizerProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.Cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - ancOptimizerProgressDialog = null; - handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_CANCEL); - } - }); - - ancOptimizerProgressDialog.show(); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - + ancOptimizer.setOnPreferenceClickListener(preference -> { + if (ancOptimizerProgressDialog != null) { + // Already optimizing return true; } + + final Context context = preference.getContext(); + + new MaterialAlertDialogBuilder(context) + .setTitle(R.string.sony_anc_optimize_confirmation_title) + .setMessage(R.string.sony_anc_optimize_confirmation_description) + .setIcon(R.drawable.ic_hearing) + .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { + public void onClick(final DialogInterface dialog, final int whichButton) { + handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_START); + + ancOptimizerProgressDialog = new ProgressDialog(context); + ancOptimizerProgressDialog.setCancelable(false); + ancOptimizerProgressDialog.setMessage(context.getString(R.string.sony_anc_optimizer_status_starting)); + ancOptimizerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + ancOptimizerProgressDialog.setProgress(0); + ancOptimizerProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.Cancel), (dialog1, which) -> { + dialog1.dismiss(); + ancOptimizerProgressDialog = null; + handler.notifyPreferenceChanged(PREF_SONY_NOISE_OPTIMIZER_CANCEL); + }); + + ancOptimizerProgressDialog.show(); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + + return true; }); } // Hide unsupported preferences final Preference speakToChatFocusVoice = handler.findPreference(PREF_SONY_SPEAK_TO_CHAT_FOCUS_ON_VOICE); - if (speakToChatFocusVoice != null && !coordinator.supports(SonyHeadphonesCapabilities.SpeakToChatFocusOnVoice)) { + if (speakToChatFocusVoice != null && !coordinator.supports(device, SonyHeadphonesCapabilities.SpeakToChatFocusOnVoice)) { speakToChatFocusVoice.setVisible(false); } + + // Override features + final MultiSelectListPreference overrideFeaturesList = handler.findPreference(PREF_OVERRIDE_FEATURES_LIST); + if (overrideFeaturesList != null) { + final Set defaultCapabilities = coordinator.getCapabilities(); + + // Populate the preference directly from the enum + final CharSequence[] entries = new CharSequence[SonyHeadphonesCapabilities.values().length]; + final CharSequence[] values = new CharSequence[SonyHeadphonesCapabilities.values().length]; + int i = 0; + for (SonyHeadphonesCapabilities capability : SonyHeadphonesCapabilities.values()) { + // Defaults first + if (defaultCapabilities.contains(capability)) { + entries[i] = "*" + capability.name(); + values[i] = capability.name(); + i++; + } + } + for (SonyHeadphonesCapabilities capability : SonyHeadphonesCapabilities.values()) { + if (!defaultCapabilities.contains(capability)) { + entries[i] = capability.name(); + values[i] = capability.name(); + i++; + } + } + overrideFeaturesList.setEntries(entries); + overrideFeaturesList.setEntryValues(values); + + overrideFeaturesList.setOnPreferenceClickListener(preference -> { + device.sendDeviceUpdateIntent(handler.getContext()); + return false; + }); + } } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsCoordinator.java index 43116c0d3..0daca818e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsCoordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -32,8 +33,8 @@ public class SonyLinkBudsCoordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.SpeakToChatEnabled, @@ -48,7 +49,7 @@ public class SonyLinkBudsCoordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.VoiceNotifications // TODO spacial sound optimization // TODO factory reset - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsSCoordinator.java index e2dc00f87..54bd2b7cf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyLinkBudsSCoordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -31,8 +32,8 @@ public class SonyLinkBudsSCoordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.AmbientSoundControl, @@ -47,7 +48,7 @@ public class SonyLinkBudsSCoordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.SpeakToChatConfig, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.EqualizerWithCustomBands - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java index dbec95e60..f341f2736 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java @@ -16,19 +16,16 @@ 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 java.util.HashSet; +import java.util.Set; 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; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWF1000XM3Coordinator extends SonyHeadphonesCoordinator { @Override @@ -46,8 +43,8 @@ public class SonyWF1000XM3Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.PowerOffFromPhone, @@ -59,7 +56,7 @@ public class SonyWF1000XM3Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.PauseWhenTakenOff, SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, SonyHeadphonesCapabilities.VoiceNotifications - ); + )); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java index 3eaddac4e..c54edf519 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -42,8 +43,8 @@ public class SonyWF1000XM4Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.AmbientSoundControl, @@ -53,7 +54,7 @@ public class SonyWF1000XM4Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.ButtonModesLeftRight, SonyHeadphonesCapabilities.PauseWhenTakenOff, SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff - ); + )); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java index 284e8d086..ddea69954 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java @@ -16,19 +16,16 @@ 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 java.util.HashSet; +import java.util.Set; 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; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWF1000XM5Coordinator extends SonyHeadphonesCoordinator { @Override @@ -46,8 +43,8 @@ public class SonyWF1000XM5Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.AmbientSoundControl, @@ -57,7 +54,7 @@ public class SonyWF1000XM5Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.ButtonModesLeftRight, SonyHeadphonesCapabilities.PauseWhenTakenOff, SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff - ); + )); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC500Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC500Coordinator.java index 0ae78f478..3bd8b0f8c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC500Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC500Coordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -31,15 +32,15 @@ public class SonyWFC500Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual2, SonyHeadphonesCapabilities.EqualizerSimple, SonyHeadphonesCapabilities.EqualizerWithCustomBands, SonyHeadphonesCapabilities.AudioUpsampling, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.PowerOffFromPhone - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC510Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC510Coordinator.java index 54b45ee55..f7f89a126 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC510Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC510Coordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -32,8 +33,8 @@ public class SonyWFC510Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual2, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.AmbientSoundControl2, @@ -43,7 +44,7 @@ public class SonyWFC510Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.AudioUpsampling, SonyHeadphonesCapabilities.ButtonModesLeftRight, SonyHeadphonesCapabilities.PowerOffFromPhone - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC700NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC700NCoordinator.java index 492dba31e..0be1ce4b4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC700NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFC700NCoordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -32,8 +33,8 @@ public class SonyWFC700NCoordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual2, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.AmbientSoundControl2, @@ -46,7 +47,7 @@ public class SonyWFC700NCoordinator extends SonyHeadphonesCoordinator { // AutoOff is supported, but current Payload is incorrect. // Available options in Sony App: 15min, 30min, 1h, 3h, off // TODO: SonyHeadphonesCapabilities.AutomaticPowerOffByTime - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java index f1299617d..bd84d80da 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java @@ -16,10 +16,9 @@ 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 java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -44,8 +43,8 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatteryDual, SonyHeadphonesCapabilities.BatteryCase, SonyHeadphonesCapabilities.PowerOffFromPhone, @@ -56,7 +55,7 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.Volume - ); + )); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM2Coordinator.java index e06c4fdce..52c0a06b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM2Coordinator.java @@ -16,17 +16,14 @@ 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 java.util.HashSet; +import java.util.Set; 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; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWH1000XM2Coordinator extends SonyHeadphonesCoordinator { @Override @@ -40,8 +37,8 @@ public class SonyWH1000XM2Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatterySingle, SonyHeadphonesCapabilities.AmbientSoundControl, SonyHeadphonesCapabilities.WindNoiseReduction, @@ -51,6 +48,6 @@ public class SonyWH1000XM2Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.SoundPosition, SonyHeadphonesCapabilities.SurroundMode, SonyHeadphonesCapabilities.AudioUpsampling - ); + )); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java index b533c878c..5b938b685 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java @@ -16,17 +16,14 @@ 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 java.util.HashSet; +import java.util.Set; 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; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator { @Override @@ -39,8 +36,8 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatterySingle, SonyHeadphonesCapabilities.AmbientSoundControl, SonyHeadphonesCapabilities.WindNoiseReduction, @@ -54,6 +51,6 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.AutomaticPowerOffByTime, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.Volume - ); + )); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java index 0ed65d3f3..91d6a3104 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -36,8 +37,8 @@ public class SonyWH1000XM4Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( // TODO: Function of [CUSTOM] button // TODO R.xml.devicesettings_connect_two_devices, SonyHeadphonesCapabilities.BatterySingle, @@ -53,6 +54,6 @@ public class SonyWH1000XM4Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.PauseWhenTakenOff, SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, SonyHeadphonesCapabilities.VoiceNotifications - ); + )); } } 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 index c137ebef0..054c9dc09 100644 --- 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 @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -36,8 +37,8 @@ public class SonyWH1000XM5Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( // TODO R.xml.devicesettings_connect_two_devices, // TODO automatic ANC depending on state (might need phone?) SonyHeadphonesCapabilities.BatterySingle, @@ -54,6 +55,6 @@ public class SonyWH1000XM5Coordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.EqualizerWithCustomBands, SonyHeadphonesCapabilities.QuickAccess, SonyHeadphonesCapabilities.PauseWhenTakenOff - ); + )); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWIC100Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWIC100Coordinator.java index 372e9f3d3..4889e2296 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWIC100Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWIC100Coordinator.java @@ -17,7 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; @@ -31,15 +32,15 @@ public class SonyWIC100Coordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatterySingle, SonyHeadphonesCapabilities.EqualizerSimple, SonyHeadphonesCapabilities.EqualizerWithCustomBands, SonyHeadphonesCapabilities.AudioUpsampling, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.PowerOffFromPhone - ); + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWISP600NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWISP600NCoordinator.java index c1c4800b4..c4963f23b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWISP600NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWISP600NCoordinator.java @@ -16,17 +16,14 @@ 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 java.util.HashSet; +import java.util.Set; 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; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWISP600NCoordinator extends SonyHeadphonesCoordinator { @Override @@ -39,8 +36,8 @@ public class SonyWISP600NCoordinator extends SonyHeadphonesCoordinator { } @Override - public List getCapabilities() { - return Arrays.asList( + public Set getCapabilities() { + return new HashSet<>(Arrays.asList( SonyHeadphonesCapabilities.BatterySingle, SonyHeadphonesCapabilities.AmbientSoundControl, SonyHeadphonesCapabilities.WindNoiseReduction, @@ -51,6 +48,6 @@ public class SonyWISP600NCoordinator extends SonyHeadphonesCoordinator { SonyHeadphonesCapabilities.AutomaticPowerOffByTime, SonyHeadphonesCapabilities.VoiceNotifications, SonyHeadphonesCapabilities.Volume - ); + )); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty3_pro/SoundcoreLiberty3ProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty3_pro/SoundcoreLiberty3ProCoordinator.java index 586de14f1..d0d12fe35 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty3_pro/SoundcoreLiberty3ProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty3_pro/SoundcoreLiberty3ProCoordinator.java @@ -53,7 +53,7 @@ public class SoundcoreLiberty3ProCoordinator extends AbstractDeviceCoordinator { @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 3; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty4_nc/SoundcoreLiberty4NCCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty4_nc/SoundcoreLiberty4NCCoordinator.java index a6300713c..329ad7579 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty4_nc/SoundcoreLiberty4NCCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/liberty4_nc/SoundcoreLiberty4NCCoordinator.java @@ -53,7 +53,7 @@ public class SoundcoreLiberty4NCCoordinator extends AbstractDeviceCoordinator { @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 3; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/motion300/SoundcoreMotion300Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/motion300/SoundcoreMotion300Coordinator.java index 1299e86d1..fdf4a2f69 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/motion300/SoundcoreMotion300Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/motion300/SoundcoreMotion300Coordinator.java @@ -54,12 +54,12 @@ public class SoundcoreMotion300Coordinator extends AbstractBLClassicDeviceCoordi } @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 1; } @Override - public boolean supportsPowerOff() { + public boolean supportsPowerOff(final GBDevice device) { return true; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/supercars/SuperCarsCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/supercars/SuperCarsCoordinator.java index f5f4b58ea..5a53dabbb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/supercars/SuperCarsCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/supercars/SuperCarsCoordinator.java @@ -62,7 +62,7 @@ public class SuperCarsCoordinator extends AbstractDeviceCoordinator { } @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 1; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java index 9e4459fa8..e5ed6b99a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java @@ -552,19 +552,19 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator { } @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return supports(getTestDevice(), TestFeature.BATTERIES_MULTIPLE) ? 3 : 1; } @Override public BatteryConfig[] getBatteryConfig(final GBDevice device) { - if (getBatteryCount() == 1) { + if (getBatteryCount(device) == 1) { return super.getBatteryConfig(device); } - final BatteryConfig[] ret = new BatteryConfig[getBatteryCount()]; + final BatteryConfig[] ret = new BatteryConfig[getBatteryCount(device)]; - for (int i = 0; i < getBatteryCount(); i++) { + for (int i = 0; i < getBatteryCount(device); i++) { ret[i] = new BatteryConfig(i, R.drawable.ic_battery_full, R.string.battery); } @@ -572,7 +572,7 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator { } @Override - public boolean supportsPowerOff() { + public boolean supportsPowerOff(final GBDevice device) { return supports(getTestDevice(), TestFeature.POWER_OFF); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/um25/Coordinator/UM25Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/um25/Coordinator/UM25Coordinator.java index 122bd055b..c03e82e86 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/um25/Coordinator/UM25Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/um25/Coordinator/UM25Coordinator.java @@ -98,7 +98,7 @@ public class UM25Coordinator extends AbstractBLEDeviceCoordinator { } @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 0; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmibuds5pro/AbstractRedmiBudsCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmibuds5pro/AbstractRedmiBudsCoordinator.java index 97e592a97..389cbe747 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmibuds5pro/AbstractRedmiBudsCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmibuds5pro/AbstractRedmiBudsCoordinator.java @@ -51,7 +51,7 @@ public abstract class AbstractRedmiBudsCoordinator extends AbstractDeviceCoordin } @Override - public int getBatteryCount() { + public int getBatteryCount(final GBDevice device) { return 3; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java index 884b4dfd7..fadcadfae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/AbstractSonyProtocolImpl.java @@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.pro import java.util.List; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; @@ -142,4 +143,8 @@ public abstract class AbstractSonyProtocolImpl { public abstract Request setVolume(final int volume); public abstract List handlePayload(final MessageType messageType, final byte[] payload); + + protected boolean supports(final SonyHeadphonesCapabilities capability) { + return getCoordinator().supports(device, capability); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java index 4d3e3827b..500405d5f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java @@ -39,7 +39,6 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdateDevi import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; -import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AdaptiveVolumeControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode; @@ -627,8 +626,6 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { } public List handleInitResponse(final byte[] payload) { - final SonyHeadphonesCoordinator coordinator = getCoordinator(); - // Populate the init requests final List capabilityRequests = new ArrayList<>(); @@ -664,7 +661,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { }}; for (Map.Entry capabilityEntry : capabilityRequestMap.entrySet()) { - if (coordinator.supports(capabilityEntry.getKey())) { + if (supports(capabilityEntry.getKey())) { capabilityRequests.add(capabilityEntry.getValue()); } } @@ -945,7 +942,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { // Dual Battery (L / R) LOG.debug("Battery Level: {}: L: {}, R: {}", batteryType, payload[2], payload[4]); - boolean hasCaseBattery = getCoordinator().supports(SonyHeadphonesCapabilities.BatteryCase); + boolean hasCaseBattery = supports(SonyHeadphonesCapabilities.BatteryCase); if (payload[2] != 0) { final GBDeviceEventBatteryInfo gbDeviceEventBatteryInfoLeft = new GBDeviceEventBatteryInfo(); @@ -1277,9 +1274,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { } protected boolean supportsWindNoiseCancelling() { - final SonyHeadphonesCoordinator coordinator = getCoordinator(); - - return coordinator.supports(SonyHeadphonesCapabilities.WindNoiseReduction); + return supports(SonyHeadphonesCapabilities.WindNoiseReduction); } protected BatteryType decodeBatteryType(final byte b) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java index ba3ada3c4..b48ab6a87 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v2/SonyProtocolImplV2.java @@ -69,7 +69,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { PayloadTypeV1.AMBIENT_SOUND_CONTROL_GET.getMessageType(), new byte[]{ PayloadTypeV1.AMBIENT_SOUND_CONTROL_GET.getCode(), - (byte) (supportsWindNoiseCancelling() || getCoordinator().supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x17 : 0x15) + (byte) (supportsWindNoiseCancelling() || supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x17 : 0x15) } ); } @@ -79,7 +79,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { final ByteBuffer buf = ByteBuffer.allocate(supportsWindNoiseCancelling() ? 8 : 7); buf.put(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getCode()); - buf.put((byte) (supportsWindNoiseCancelling() || getCoordinator().supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x17 : 0x15)); + buf.put((byte) (supportsWindNoiseCancelling() || supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x17 : 0x15)); buf.put((byte) 0x01); // 0x00 while dragging the slider? if (AmbientSoundControl.Mode.OFF.equals(ambientSoundControl.getMode())) { @@ -352,7 +352,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { PayloadTypeV2.AMBIENT_SOUND_CONTROL_BUTTON_MODE_SET.getCode(), (byte) 0x03, (byte) 0x01, - (byte) (getCoordinator().supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x00 : 0x35), + (byte) (supports(SonyHeadphonesCapabilities.AmbientSoundControl2) ? 0x00 : 0x35), (byte) 0x01, (byte) 0x00, ambientSoundControlButtonMode.getCode() @@ -1081,7 +1081,7 @@ public class SonyProtocolImplV2 extends SonyProtocolImplV1 { case OFF: return (byte) 0xff; case AMBIENT_SOUND_CONTROL: - return (byte) (supportsWindNoiseCancelling() || getCoordinator().supports(SonyHeadphonesCapabilities.NoNoiseCancelling) ? 0x35 : 0x00); // Seems to be the only one that differs? + return (byte) (supportsWindNoiseCancelling() || supports(SonyHeadphonesCapabilities.NoNoiseCancelling) ? 0x35 : 0x00); // Seems to be the only one that differs? case PLAYBACK_CONTROL: return (byte) 0x20; case VOLUME_CONTROL: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38a8513df..2bcdf27d4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3277,6 +3277,8 @@ BT_CLASSIC Activity info Could not post ongoing notification due to missing permission + Override supported features + Enable/disable specific device features. This can cause issues and/or make your device work incorrectly Features Enabled features for this test device Add test activities diff --git a/app/src/main/res/xml/devicesettings_header_intent_api.xml b/app/src/main/res/xml/devicesettings_header_intent_api.xml new file mode 100644 index 000000000..6ae638fc1 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_header_intent_api.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/xml/devicesettings_override_features.xml b/app/src/main/res/xml/devicesettings_override_features.xml new file mode 100644 index 000000000..15da77a7c --- /dev/null +++ b/app/src/main/res/xml/devicesettings_override_features.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/MockSonyCoordinator.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/MockSonyCoordinator.java index 4ef079914..7dee4feaf 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/MockSonyCoordinator.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/MockSonyCoordinator.java @@ -16,10 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl; -import androidx.annotation.NonNull; - -import java.util.ArrayList; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; @@ -30,9 +28,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class MockSonyCoordinator extends SonyHeadphonesCoordinator { private final DeviceType deviceType = DeviceType.SONY_WH_1000XM3; - private final List capabilities = new ArrayList<>(); + private final Set capabilities = new LinkedHashSet<>(); - @NonNull @Override public boolean supports(final GBDeviceCandidate candidate) { return true; @@ -47,7 +44,7 @@ public class MockSonyCoordinator extends SonyHeadphonesCoordinator { capabilities.add(capability); } - public List getCapabilities() { + public Set getCapabilities() { return capabilities; } }