diff --git a/CHANGELOG.md b/CHANGELOG.md index 9667605e8..f78cd5ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ### NEXT * Initial Support for Sony WF-1000XM3 -* Huami: Add Toggle function for Open Tracks tracking to button actionss +* Initial Support for Galaxy Buds Pro +* Huami: Add Toggle function for Open Tracks tracking to button actions * Huami: Move inactivity warnings and goal notification to device-specific settings * Mi Band 6: set time on connect * Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration @@ -16,9 +17,9 @@ * VESC: added battery indicator * UM25: Add reset option to current accumulation * UM25: Add notification on below current threshold -* Fix crash when calender is accessed but permission is denied +* Fix crash when calendar is accessed but permission is denied * Add com.asus.asusincallui to blacklist -* New icons for Sony WF 800n and Mi Band 6 +* New icons for Sony overhead headphones, Sony WF 800n and Mi Band 6 ### 0.66.0 * Add basic support for Casio GBD-H1000 diff --git a/app/src/main/assets/buds_pro_case.svg b/app/src/main/assets/buds_pro_case.svg new file mode 100644 index 000000000..985c459da --- /dev/null +++ b/app/src/main/assets/buds_pro_case.svg @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/app/src/main/assets/buds_pro_left.svg b/app/src/main/assets/buds_pro_left.svg new file mode 100644 index 000000000..3fcbe9457 --- /dev/null +++ b/app/src/main/assets/buds_pro_left.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/buds_pro_right.svg b/app/src/main/assets/buds_pro_right.svg new file mode 100644 index 000000000..cd0075f58 --- /dev/null +++ b/app/src/main/assets/buds_pro_right.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_galaxy_buds_pro.svg b/app/src/main/assets/ic_device_galaxy_buds_pro.svg new file mode 100644 index 000000000..17cdc49e8 --- /dev/null +++ b/app/src/main/assets/ic_device_galaxy_buds_pro.svg @@ -0,0 +1,147 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg b/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg new file mode 100644 index 000000000..4f40a69bd --- /dev/null +++ b/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg @@ -0,0 +1,200 @@ + + + + + + + + image/svg+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 03f2cbf7d..1e59059d2 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 @@ -139,8 +139,25 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_GALAXY_BUDS_EQUALIZER_MODE = "pref_galaxy_buds_equalizer_mode"; public static final String PREF_GALAXY_BUDS_TOUCH_LEFT = "pref_galaxy_buds_touch_left"; public static final String PREF_GALAXY_BUDS_TOUCH_RIGHT = "pref_galaxy_buds_touch_right"; + public static final String PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH = "pref_galaxy_buds_touch_right_switch"; + public static final String PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH = "pref_galaxy_buds_touch_left_switch"; public static final String PREF_GALAXY_BUDS_LIVE_ANC = "pref_galaxy_buds_live_anc"; public static final String PREF_GALAXY_BUDS_PRESSURE_RELIEF = "pref_galaxy_buds_live_pressure_relief"; + public static final String PREF_GALAXY_BUDS_AMBIENT_SOUND = "pref_galaxy_buds_ambient_sound"; + public static final String PREF_GALAXY_BUDS_PRO_NOISE_CONTROL="pref_galaxy_buds_pro_noise_control"; + public static final String PREF_GALAXY_PRO_DOUBLE_TAP_EDGE ="pref_galaxy_pro_double_tap_edge"; + public static final String PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION ="pref_galaxy_buds_pro_in_ear_detection"; + public static final String PREF_GALAXY_BUDS_PRO_VOICE_DETECT ="pref_galaxy_buds_pro_voice_detect"; + public static final String PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION ="pref_galaxy_buds_pro_voice_detect_duration"; + public static final String PREF_GALAXY_BUDS_PRO_BALANCE="pref_galaxy_buds_pro_balance"; + public static final String PREF_GALAXY_BUDS_PRO_READ_NOTIFICATIONS_OUTLOUD ="pref_galaxy_buds_pro_read_notifications_outloud"; + public static final String PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL ="pref_galaxy_buds_ambient_mode_during_call"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT ="pref_galaxy_buds_pro_ambient_volume_right"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT="pref_galaxy_buds_pro_ambient_volume_left"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE ="pref_galaxy_buds_pro_ambient_sound_tone"; + public static final String PREFS_NOISE_CONTROL_WITH_ONE_EARBUD ="pref_galaxy_buds_noise_controls_with_one_earbud"; + public static final String PREF_GALAXY_BUDS_PRO_ANC_LEVEL="pref_galaxy_buds_pro_anc_level"; + public static final String PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION="prefs_galaxy_buds_seamless_connection"; public static final String PREF_SONY_AUDIO_CODEC = "pref_sony_audio_codec"; public static final String PREF_SONY_AMBIENT_SOUND_CONTROL = "pref_sony_ambient_sound_control"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java index fc948131a..40516ec96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java @@ -21,6 +21,7 @@ import android.os.Parcelable; import androidx.preference.Preference; import java.util.Set; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; /** * A device-specific preference handler, that allows for concrete implementations to customize the preferences in @@ -37,10 +38,10 @@ public interface DeviceSpecificSettingsCustomizer extends Parcelable { /** * Customize the settings on the {@link DeviceSpecificSettingsFragment}. - * * @param handler the {@link DeviceSpecificSettingsHandler} + * @param prefs the {@link android.content.SharedPreferences} */ - void customizeSettings(final DeviceSpecificSettingsHandler handler); + void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs); /** * Keys of preferences which should print its values as a summary below the preference name. 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 a8ca0648f..d4271d269 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 @@ -431,7 +431,6 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_NOTHING_EAR1_INEAR); addPreferenceHandlerFor(PREF_NOTHING_EAR1_AUDIOMODE); - addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE); addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS); addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_VOLUME); addPreferenceHandlerFor(PREF_GALAXY_BUDS_LOCK_TOUCH); @@ -443,6 +442,23 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_RIGHT); addPreferenceHandlerFor(PREF_GALAXY_BUDS_LIVE_ANC); addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRESSURE_RELIEF); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_ANC_LEVEL); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_SOUND); + addPreferenceHandlerFor(PREF_GALAXY_PRO_DOUBLE_TAP_EDGE); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_VOICE_DETECT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_BALANCE); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_READ_NOTIFICATIONS_OUTLOUD); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE); + addPreferenceHandlerFor(PREFS_NOISE_CONTROL_WITH_ONE_EARBUD); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE); + addPreferenceHandlerFor(PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH); addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL); addPreferenceHandlerFor(PREF_SONY_FOCUS_VOICE); @@ -731,7 +747,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } if (deviceSpecificSettingsCustomizer != null) { - deviceSpecificSettingsCustomizer.customizeSettings(this); + deviceSpecificSettingsCustomizer.customizeSettings(this, prefs); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java index 2149a3d97..c26965570 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java @@ -1,26 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; -import android.app.Activity; -import android.content.Context; -import android.net.Uri; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; -public class GalaxyBudsDeviceCoordinator extends AbstractDeviceCoordinator { +public class GalaxyBudsDeviceCoordinator extends GalaxyBudsGenericCoordinator { @NonNull @Override @@ -53,100 +41,6 @@ public class GalaxyBudsDeviceCoordinator extends AbstractDeviceCoordinator { return new BatteryConfig[]{battery1, battery2}; } - @Override - public int getBondingStyle() { - return BONDING_STYLE_BOND; - } - - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice - device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots() { - return false; - } - - @Override - public int getAlarmSlotCount() { - return 0; - } - - @Override - public boolean supportsSmartWakeup(GBDevice device) { - return false; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public String getManufacturer() { - return "Samsung"; - } - - @Override - public boolean supportsAppsManagement() { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return true; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device - device, @NonNull DaoSession session) throws GBException { - - } - - @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java new file mode 100644 index 000000000..78400c621 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java @@ -0,0 +1,114 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; + +public abstract class GalaxyBudsGenericCoordinator extends AbstractDeviceCoordinator { + + @Override + public int getBondingStyle() { + return BONDING_STYLE_BOND; + } + + @Nullable + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return false; + } + + @Override + public boolean supportsActivityTracking() { + return false; + } + + @Override + public SampleProvider getSampleProvider(GBDevice + device, DaoSession session) { + return null; + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public int getAlarmSlotCount() { + return 0; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return false; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return false; + } + + @Override + public String getManufacturer() { + return "Samsung"; + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return false; + } + + @Override + public boolean supportsWeather() { + return false; + } + + @Override + public boolean supportsFindDevice() { + return true; + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device + device, @NonNull DaoSession session) throws GBException { + + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java index 1b1f85b67..5d9cff134 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java @@ -1,26 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; -import android.app.Activity; -import android.content.Context; -import android.net.Uri; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; -public class GalaxyBudsLiveDeviceCoordinator extends AbstractDeviceCoordinator { +public class GalaxyBudsLiveDeviceCoordinator extends GalaxyBudsGenericCoordinator { @NonNull @Override @@ -54,99 +42,6 @@ public class GalaxyBudsLiveDeviceCoordinator extends AbstractDeviceCoordinator { return new BatteryConfig[]{battery1, battery2, battery3}; } - @Override - public int getBondingStyle() { - return BONDING_STYLE_BOND; - } - - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice - device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots() { - return false; - } - - @Override - public int getAlarmSlotCount() { - return 0; - } - - @Override - public boolean supportsSmartWakeup(GBDevice device) { - return false; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public String getManufacturer() { - return "Samsung"; - } - - @Override - public boolean supportsAppsManagement() { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return true; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device - device, @NonNull DaoSession session) throws GBException { - - } - @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java new file mode 100644 index 000000000..f3966a285 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java @@ -0,0 +1,57 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import androidx.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesSettingsCustomizer; +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 GalaxyBudsProDeviceCoordinator extends GalaxyBudsGenericCoordinator { + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + + String name = candidate.getName(); + + if (name != null && ( + name.startsWith("Galaxy Buds Pro (") + )) { + return DeviceType.GALAXY_BUDS_PRO; + } + return DeviceType.UNKNOWN; + } + + @Override + public DeviceSpecificSettingsCustomizer getDeviceSpecificSettingsCustomizer(final GBDevice device) { + return new GalaxyBudsSettingsCustomizer(device); + } + @Override + public DeviceType getDeviceType() { + return DeviceType.GALAXY_BUDS_PRO; + } + + @Override + public int getBatteryCount() { + return 3; + } + + @Override + public BatteryConfig[] getBatteryConfig() { + BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); + BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_buds_pro_left, R.string.left_earbud); + BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_buds_pro_right, R.string.right_earbud); + return new BatteryConfig[]{battery1, battery2, battery3}; + } + + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + return new int[]{ + R.xml.devicesettings_galaxy_buds_pro, + }; + } +} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java new file mode 100644 index 000000000..29a5d20e7 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java @@ -0,0 +1,241 @@ +/* Copyright (C) 2021 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH; + +import android.os.Parcel; + +import androidx.preference.Preference; + +import java.util.Collections; +import java.util.Set; + +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + +public class GalaxyBudsSettingsCustomizer implements DeviceSpecificSettingsCustomizer { + + final GBDevice device; + + public GalaxyBudsSettingsCustomizer(final GBDevice device) { + this.device = device; + } + + @Override + public void onPreferenceChange(final Preference preference, final DeviceSpecificSettingsHandler handler) { + } + + @Override + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { + + final Preference pref_galaxy_buds_pro_balance = handler.findPreference(PREF_GALAXY_BUDS_PRO_BALANCE); + if (pref_galaxy_buds_pro_balance != null) { + pref_galaxy_buds_pro_balance.setSummary(String.valueOf((prefs.getInt(PREF_GALAXY_BUDS_PRO_BALANCE, 16) - 16))); + + pref_galaxy_buds_pro_balance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + String newValue = String.valueOf((int) newVal - 16); + pref_galaxy_buds_pro_balance.setSummary(newValue); + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_PRO_BALANCE); + return true; + } + }); + } + + final Preference pref_galaxy_buds_pro_noise_control = handler.findPreference(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL); + String pref_galaxy_buds_pro_noise_control_value = prefs.getString(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL, "0"); + final Preference pref_galaxy_buds_pro_anc_level = handler.findPreference(PREF_GALAXY_BUDS_PRO_ANC_LEVEL); + final Preference pref_galaxy_buds_ambient_volume = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_VOLUME); + + if (pref_galaxy_buds_pro_noise_control != null) { + + switch (pref_galaxy_buds_pro_noise_control_value) { + case "0": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "1": + pref_galaxy_buds_pro_anc_level.setEnabled(true); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "2": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(true); + break; + } + + pref_galaxy_buds_pro_noise_control.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL); + switch (newVal.toString()) { + case "0": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "1": + pref_galaxy_buds_pro_anc_level.setEnabled(true); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "2": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(true); + break; + } + + return true; + } + }); + } + + + final Preference pref_galaxy_buds_touch_right = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_RIGHT); + String pref_galaxy_buds_touch_right_value = prefs.getString(PREF_GALAXY_BUDS_TOUCH_RIGHT, "1"); + final Preference pref_galaxy_buds_touch_right_switch = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH); + + if (pref_galaxy_buds_touch_right != null) { + + switch (pref_galaxy_buds_touch_right_value) { + case "2": + pref_galaxy_buds_touch_right_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_right_switch.setEnabled(false); + } + + pref_galaxy_buds_touch_right.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_TOUCH_RIGHT); + switch (newVal.toString()) { + case "2": + pref_galaxy_buds_touch_right_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_right_switch.setEnabled(false); + + } + + return true; + } + }); + } + + final Preference pref_galaxy_buds_touch_left = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_LEFT); + String pref_galaxy_buds_touch_left_value = prefs.getString(PREF_GALAXY_BUDS_TOUCH_LEFT, "1"); + final Preference pref_galaxy_buds_touch_left_switch = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH); + + if (pref_galaxy_buds_touch_left != null) { + + switch (pref_galaxy_buds_touch_left_value) { + case "2": + pref_galaxy_buds_touch_left_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_left_switch.setEnabled(false); + } + + pref_galaxy_buds_touch_left.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_TOUCH_LEFT); + switch (newVal.toString()) { + case "2": + pref_galaxy_buds_touch_left_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_left_switch.setEnabled(false); + + } + + return true; + } + }); + } + + +/* + final Preference pref_galaxy_buds_ambient_mode = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_SOUND); + boolean is_pref_galaxy_buds_ambient_mode_enabled = prefs.getBoolean(PREF_GALAXY_BUDS_AMBIENT_SOUND, false); + final Preference pref_galaxy_buds_ambient_voice_focus_preference = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS_PREFERENCE); + + if (pref_galaxy_buds_ambient_mode != null) { + if (is_pref_galaxy_buds_ambient_mode_enabled) { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(true); + } else { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(false); + } + + + pref_galaxy_buds_ambient_mode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_AMBIENT_SOUND); + if ((boolean) newVal) { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(true); + } else { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(false); + } + + return true; + } + }); + } + + */ + } + + @Override + public Set getPreferenceKeysWithSummary() { + return Collections.emptySet(); + } + + + public static final Creator CREATOR = new Creator() { + @Override + public GalaxyBudsSettingsCustomizer createFromParcel(final Parcel in) { + final GBDevice device = in.readParcelable(GalaxyBudsSettingsCustomizer.class.getClassLoader()); + return new GalaxyBudsSettingsCustomizer(device); + } + + @Override + public GalaxyBudsSettingsCustomizer[] newArray(final int size) { + return new GalaxyBudsSettingsCustomizer[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(final Parcel dest, final int flags) { + dest.writeParcelable(device, 0); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java index fef6626d2..566283399 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java @@ -18,7 +18,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huami; import android.os.Parcel; import android.text.InputType; -import android.widget.Toast; import androidx.preference.Preference; @@ -31,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpec import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class HuamiSettingsCustomizer implements DeviceSpecificSettingsCustomizer { final GBDevice device; @@ -45,7 +45,7 @@ public class HuamiSettingsCustomizer implements DeviceSpecificSettingsCustomizer } @Override - public void customizeSettings(final DeviceSpecificSettingsHandler handler) { + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { for (HuamiVibrationPatternNotificationType notificationType : HuamiVibrationPatternNotificationType.values()) { final String typeKey = notificationType.name().toLowerCase(Locale.ROOT); 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 0a8eb477d..7744b4a15 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 @@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Ambien import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsCustomizer { private ProgressDialog ancOptimizerProgressDialog; @@ -116,7 +117,7 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC } @Override - public void customizeSettings(final DeviceSpecificSettingsHandler handler) { + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { // Only enable the focus on voice check and voice level slider if the ambient sound control mode is ambient sound final ListPreference ambientSoundControl = handler.findPreference(PREF_SONY_AMBIENT_SOUND_CONTROL); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index c2d7a780a..f9bacf8fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -103,6 +103,7 @@ public enum DeviceType { UM25(350, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_um25), DOMYOS_T540(400, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_domyos_t540), NOTHING_EAR1(410, R.drawable.ic_device_nothingear, R.drawable.ic_device_nothingear_disabled, R.string.devicetype_nothingear1), + GALAXY_BUDS_PRO(418, R.drawable.ic_device_galaxy_buds_pro, R.drawable.ic_device_galaxy_buds_pro_disabled, R.string.devicetype_galaxybuds_pro), GALAXY_BUDS_LIVE(419, R.drawable.ic_device_galaxy_buds_live, R.drawable.ic_device_galaxy_buds_live_disabled, R.string.devicetype_galaxybuds_live), GALAXY_BUDS(420, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_galaxybuds), SONY_WH_1000XM3(430, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm3), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 420d558de..0172aef6c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -380,6 +380,9 @@ public class DeviceSupportFactory { case GALAXY_BUDS_LIVE: deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case GALAXY_BUDS_PRO: + deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case SONY_WH_1000XM3: deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java index 7d8aca91d..22dfbb3e7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java @@ -31,7 +31,8 @@ public class GalaxyBudsIOThread extends BtClassicIoThread { if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS)) { return galaxyBudsProtocol.UUID_GALAXY_BUDS_DEVICE_CTRL; } - if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS_LIVE)) { + if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS_LIVE) + || gbDevice.getType().equals(DeviceType.GALAXY_BUDS_PRO)) { return galaxyBudsProtocol.UUID_GALAXY_BUDS_LIVE_DEVICE_CTRL; } return galaxyBudsProtocol.UUID_GALAXY_BUDS_DEVICE_CTRL; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java index aaa2a2a4b..cfde9aa50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java @@ -8,6 +8,8 @@ import android.content.SharedPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; @@ -16,7 +18,6 @@ import java.util.List; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; @@ -32,18 +33,19 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { final UUID UUID_GALAXY_BUDS_DEVICE_CTRL = UUID.fromString("00001102-0000-1000-8000-00805f9b34fd"); final UUID UUID_GALAXY_BUDS_LIVE_DEVICE_CTRL = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); - private static final byte SOMBuds = (byte) 0xFE; - private static final byte EOMBuds = (byte) 0xEE; - private static final byte SOMPlus = (byte) 0xFD; - private static final byte EOMPlus = (byte) 0xDD; + private static final byte SOM_BUDS = (byte) 0xFE; + private static final byte EOM_BUDS = (byte) 0xEE; + private static final byte SOM_BUDS_PLUS = (byte) 0xFD; + private static final byte EOM_BUDS_PLUS = (byte) 0xDD; - private byte SOM = SOMBuds; - private byte EOM = EOMBuds; + private byte StartOfMessage = SOM_BUDS; + private byte EndOfMessage = EOM_BUDS; private boolean isFirstExchange = true; //incoming private static final byte battery_status = (byte) 0x60; + private static final byte battery_status2 = (byte) 0x61; //outgoing @@ -52,11 +54,14 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { private static final byte set_ambient_mode = (byte) 0x80; //0x0/0x1 private static final byte set_ambient_volume = (byte) 0x84; // 0x1-0x5 + private static final byte set_ambient_voice_focus = (byte) 0x85; // 0x0/0x1 private static final byte set_lock_touch = (byte) 0x90; // 0x0/0x1 - private static final byte set_game_mode = (byte) 0x87; // 0x0/0x2 no idea if this is doing anything - private static final byte set_equalizer = (byte) 0x86; // 0x0/0x1 + private static final byte set_game_mode = (byte) 0x87; // 0x0/0x2 no idea if this is doing anything... + // this is sent dynamically based on whether the current running app is a game or not + + private static final byte set_equalizer = (byte) 0x86; private static final byte set_reset = (byte) 0x50; @@ -69,9 +74,86 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { //Live private static final byte set_automatic_noise_cancelling = (byte) 0x98; //0x0/0x1 - private static final byte set_live_game_mode = (byte) 0x85; // 0x0/0x1 no idea if this is doing anything private static final byte set_pressure_relief = (byte) 0x9f; //0x0/0x1 + //Live and Pro + private static final byte set_live_pro_game_mode = (byte) 0x85; // 0x0/0x1 no idea if this is doing anything + + //Pro + // Comments thanks to phh as per https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2642#issuecomment-445962 + + private static final byte set_spatial_audio_control = (byte) 0xc3; //0x0/0x1 + // takes a boolean '1' or '0' to enable or disable 360 Audio (probably useless until someone + // manage to send Dolby Atmos to the headset). 360 audio is a feature where (Shown only on Samsung rom) + + private static final byte set_outside_double_tap = (byte) 0x95; //0x0/0x1 + // This is an option in "Labs", to detect double tap even when not taped on touch pad (so I presume it's using accelerometer) + + private static final byte set_adjust_sound_sync = (byte) 0x85; //0x0/0x1 + // This is an option in "Labs" available only on Samsung ROM, exposed to the user as "automatic game mode". + // This is used in confunction with GAME_MODE. My guess is that this says to the ear buds + // "yes, I know that the reported latency might change on the fly, I'm fine with that". + + private static final byte set_detect_conversations = (byte) 0x7a; //0x0/0x1 + // This is called "Voice detect -- Noise controls and sound settings go back to the previous state + // when your voice isn't detected for 10 seconds". This triggers the feature that when you talk, + // the ear buds automatically go into "ambient sound" mode, and enhance the sound of your interlocutor + + private static final byte set_detect_conversations_duration = (byte) 0x7b; //0x0/0x1/0x2 + // Takes {0,1,2}: 0 means 5 seconds, 1 means 10 seconds, 2 means 15s. This is the duration after + // which the ear buds go back to ANC after switching to ambient sound when the user talks. + + private static final byte set_ambient_mode_during_calls = (byte) 0x8b; //0x0/0x1 + // "Use ambient sound during calls" + + private static final byte set_noise_controls_with_one_earbud = (byte) 0x6f; //0x0/0x1 + // "Noise controls with one earbud" in Accessibility menu. I'm not exactly sure what it means, + // my guess is that it allows ANC even if only one earbuds is in-ear + + private static final byte set_balance = (byte) 0x8f; + // takes value in 0-32 range, it is used to change left/right balance + + private static final byte extra_high_ambient = (byte) 0x96; //0x0/0x1 + // "Maximize ambient sound volume"/"Amplify sounds from your surroundings so you can stay aware of what's going on around you. + + private static final byte set_seamless_connection = (byte) 0xaf; //0x0/0x1 + // It is used to allow the ear buds to roam across devices, like devices being allowed to take ear buds "focus". + + private static final byte set_voice_wake_up = (byte) 0x97; //0x0/0x1 + // Enables "Hey Bixby" wake up word. Shown only on Samsung ROM + + private static final byte set_speak_seamlessly = (byte) 0x7d; //0x0/0x1 + // "After Voice wake up, you can say the command you want right away without waiting for sound feedback." + + private static final byte voice_wake_up_language = (byte) 0x99; + // Language for "Hey bixby" wakeup - 1 = "de-DE", 2 = "en-GB", 3 = "en-US", 4 = "es-ES", 5 = "fr-FR", 6 = "it-IT", 7 = "ko-KR", 8 = "pt-BR", 9 = "zh-CN" + + private static final byte set_voice_noti_status = (byte) 0xa4; //0x0/0x1 + // I have no idea why it does that. It sends "1" when it starts reading notification aloud, and "0" when it finished. + + private static final byte set_noise_controls = (byte) 0x78; //Takes 0/1/2. + // 0 is Ambient Sound and ANC OFF, 1 is ANC on, 2 is Ambient sound ON + + private static final byte set_mute_earbud = (byte) 0xa2; + // Takes two booleans (left then right). This is used in conjuction with FIND_MY_EARBUDS_START to alternate between tweeting the left and the right earbud + + private static final byte set_customize_ambient_sound = (byte) 0x82; + //one byte for left volume 0-4, one byte for right volume 0-4, and one byte 0-4 for ambient sound tone from "soft" to "clear" + + private static final byte set_noise_reduction_level = (byte) 0x83; + // 1 means High noise reduction, 0 low noise reduction. + + private static final byte set_touch_and_hold_noise_controls = (byte) 0x79; + // Takes either 3 booleans or 6 booleans depending on earbuds revision. + // It is used when long press on touchpad is set in SET_TOUCHPAD_OPTION to "Switch noise control", + // to control whether the long press switches between ANC on <=> Ambient sound on, or to anc+ambient off, + // or ambient <=> off or anc <=> off, and when it's 6 bytes, it can have different behavior between right and left earbud. + + private static final byte voice_wake_up_event = (byte) 0x9a; + // Just a reponse. It's a ACK for when received "Hey bixby" command ? + + private static final byte in_ear_detection = (byte) 0x6e; + @Override public GBDeviceEvent[] decodeResponse(byte[] responseData) { List devEvts = new ArrayList<>(); @@ -90,12 +172,12 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte type = 0; byte sof = incoming.get(); - if (sof != SOM) { + if (sof != StartOfMessage) { LOG.error("Error in message, wrong start of frame: " + hexdump(responseData)); return null; } - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { length = (int) (incoming.get() & 0xff); type = incoming.get(); } else { @@ -130,9 +212,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command) { ByteBuffer msgBuf = ByteBuffer.allocate(7); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x3; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -141,7 +223,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { } msgBuf.put((byte) command); //command id msgBuf.putShort((short) crc16_ccitt(new byte[]{command})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } @@ -149,9 +231,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command, byte parameter) { ByteBuffer msgBuf = ByteBuffer.allocate(8); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x4; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -161,7 +243,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { msgBuf.put((byte) command); //command id msgBuf.put((byte) parameter); msgBuf.putShort((short) crc16_ccitt(new byte[]{command, parameter})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } @@ -169,9 +251,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command, byte parameter, byte value) { ByteBuffer msgBuf = ByteBuffer.allocate(9); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x5; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -182,11 +264,43 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { msgBuf.put((byte) parameter); msgBuf.put((byte) value); msgBuf.putShort((short) crc16_ccitt(new byte[]{command, parameter, value})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } + byte[] encodeMessage(byte command, byte[] payload) { + byte payload_size = (byte) (3 + payload.length); + ByteBuffer msgBuf = ByteBuffer.allocate(4 + payload_size); + msgBuf.order(ByteOrder.LITTLE_ENDIAN); + msgBuf.put(StartOfMessage); + + if (StartOfMessage == SOM_BUDS_PLUS) { + msgBuf.put((byte) payload_size); + msgBuf.put((byte) 0x0); //0x0 for sending + } else { + msgBuf.put((byte) 0x0); //0x0 for sending + msgBuf.put((byte) payload_size); //size + } + msgBuf.put((byte) command); + msgBuf.put(payload); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + try { + outputStream.write(command); + outputStream.write(payload); + } catch (IOException e) { + LOG.warn("Assembling message failed: " + e.getMessage()); + } + + msgBuf.putShort((short) crc16_ccitt(outputStream.toByteArray())); + msgBuf.put(EndOfMessage); + LOG.debug("DEBUG: " + hexdump(msgBuf.array())); + return msgBuf.array(); + } + + @Override public byte[] encodeFindDevice(boolean start) { byte command = (byte) (start ? find_device_start : find_device_stop); @@ -213,23 +327,76 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); switch (config) { + case DeviceSettingsPreferenceConst.PREF_GALAXY_PRO_DOUBLE_TAP_EDGE: + byte outside_double_tap = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_PRO_DOUBLE_TAP_EDGE, false) ? 0x01 : 0x00); + return encodeMessage(set_outside_double_tap, outside_double_tap); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT: + byte detect_conversations = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT, false) ? 0x01 : 0x00); + return encodeMessage(set_detect_conversations, detect_conversations); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION: + String voice_detect_duration = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION, "1"); + byte voice_detect_duration_b = (byte) Integer.parseInt(voice_detect_duration); + return encodeMessage(set_detect_conversations_duration, voice_detect_duration_b); + + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL: + byte ambient_mode_during_calls = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL, false) ? 0x01 : 0x00); + return encodeMessage(set_ambient_mode_during_calls, ambient_mode_during_calls); + + case DeviceSettingsPreferenceConst.PREFS_NOISE_CONTROL_WITH_ONE_EARBUD: + byte noise_controls_with_one_earbud = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREFS_NOISE_CONTROL_WITH_ONE_EARBUD, false) ? 0x01 : 0x00); + return encodeMessage(set_noise_controls_with_one_earbud, noise_controls_with_one_earbud); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION: + byte ear_detection = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION, false) ? 0x01 : 0x00); + return encodeMessage(in_ear_detection, ear_detection); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE: + int hearing_enhancements = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE, 16); + return encodeMessage(set_balance, (byte) hearing_enhancements); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL: + int noise_controls = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL, "0")); + return encodeMessage(set_noise_controls, (byte) noise_controls); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL: + int anc_level = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL, "0")); + return encodeMessage(set_noise_reduction_level, (byte) anc_level); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_SOUND: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE: + byte ambient_sound = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_SOUND, true) ? (byte) 1 : (byte) 0; + int ambient_right = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT, 1); + int ambient_left = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT, 1); + int sound_tone = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE, 1); + return encodeMessage(set_customize_ambient_sound, new byte[]{ambient_sound, (byte) ambient_left, (byte) ambient_right, (byte) sound_tone}); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE: byte enable_ambient = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE, false) ? 0x01 : 0x00); return encodeMessage(set_ambient_mode, enable_ambient); + + case DeviceSettingsPreferenceConst.PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION: + byte seamless_switch = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION, false) ? 0x01 : 0x00); + return encodeMessage(set_seamless_connection, seamless_switch); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS: byte enable_voice = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS, false) ? 0x01 : 0x00); return encodeMessage(set_ambient_voice_focus, enable_voice); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME: int ambient_volume = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME, 0); - byte ambient_volume_byte = (byte) (ambient_volume + 1); //seek bar is 0-4, we need 1-5 + byte ambient_volume_byte = (byte) (ambient_volume); return encodeMessage(set_ambient_volume, ambient_volume_byte); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LOCK_TOUCH: byte set_lock = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LOCK_TOUCH, false) ? 0x01 : 0x00); return encodeMessage(set_lock_touch, set_lock); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE: - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { byte game_mode = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE, false) ? 0x1 : 0x00); - return encodeMessage(set_live_game_mode, game_mode); + return encodeMessage(set_live_pro_game_mode, game_mode); } else { byte game_mode = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE, false) ? 0x2 : 0x00); return encodeMessage(set_game_mode, game_mode); @@ -246,7 +413,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { } String equalizer_mode = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_EQUALIZER_MODE, "0"); - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { return encodeMessage(set_equalizer, (byte) (Integer.parseInt(equalizer_mode))); } else { byte mode = (byte) (Integer.parseInt(equalizer_mode) + dolby); @@ -261,6 +428,22 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte touchmode_right = (byte) Integer.parseInt(touch_right); return encodeMessage(set_touchpad_options, touchmode_left, touchmode_right); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH: + String touch_right_switch = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH, "1"); + String touch_left_switch = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH, "1"); + byte[] touch_right_switch_b = encode_touch_switch(touch_right_switch); + byte[] touch_left_switch_b = encode_touch_switch(touch_left_switch); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + outputStream.write(touch_left_switch_b); + outputStream.write(touch_right_switch_b); + } catch (IOException e) { + LOG.warn("Assembling message failed: " + e.getMessage()); + } + return encodeMessage(set_touch_and_hold_noise_controls, outputStream.toByteArray()); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LIVE_ANC: byte enable_anc = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LIVE_ANC, false) ? 0x1 : 0x00); return encodeMessage(set_automatic_noise_cancelling, enable_anc); @@ -304,7 +487,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { deviceEvents.add(evBattery2); - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { GBDeviceEventBatteryInfo evBattery3 = new GBDeviceEventBatteryInfo(); // reorder for the non OG version evBattery1.batteryIndex = 1; //left @@ -320,11 +503,23 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { return deviceEvents; } + private byte[] encode_touch_switch(String input) { + switch (input) { + case "1": + return new byte[]{0x1, 0x0, 0x1}; + case "2": + return new byte[]{0x0, 0x1, 0x1}; + default: + return new byte[]{0x1, 0x1, 0x0}; + } + } + protected GalaxyBudsProtocol(GBDevice device) { super(device); - if (device.getType().equals(DeviceType.GALAXY_BUDS_LIVE)) { - SOM = SOMPlus; - EOM = EOMPlus; + if (device.getType().equals(DeviceType.GALAXY_BUDS_LIVE) + || device.getType().equals(DeviceType.GALAXY_BUDS_PRO)) { + StartOfMessage = SOM_BUDS_PLUS; + EndOfMessage = EOM_BUDS_PLUS; } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index eb0429c84..3328e952c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -51,6 +51,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100.CasioGBX100Devi import nodomain.freeyourgadget.gadgetbridge.devices.domyos.DomyosT540Cooridnator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsLiveDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsProDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.EXRIZUK8Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.MakibesF68Coordinator; @@ -323,6 +324,7 @@ public class DeviceHelper { result.add(new Ear1Coordinator()); result.add(new GalaxyBudsDeviceCoordinator()); result.add(new GalaxyBudsLiveDeviceCoordinator()); + result.add(new GalaxyBudsProDeviceCoordinator()); result.add(new VescCoordinator()); result.add(new SonyWH1000XM3Coordinator()); result.add(new SonyWH1000XM4Coordinator()); diff --git a/app/src/main/res/drawable/ic_buds_pro_case.xml b/app/src/main/res/drawable/ic_buds_pro_case.xml new file mode 100644 index 000000000..769645bac --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_case.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/drawable/ic_buds_pro_left.xml b/app/src/main/res/drawable/ic_buds_pro_left.xml new file mode 100644 index 000000000..12af00c73 --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_left.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_buds_pro_right.xml b/app/src/main/res/drawable/ic_buds_pro_right.xml new file mode 100644 index 000000000..0304040bb --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_right.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml b/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml new file mode 100644 index 000000000..4b5b21950 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml b/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml new file mode 100644 index 000000000..9d9584b39 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_switch_right.xml b/app/src/main/res/drawable/ic_switch_right.xml new file mode 100644 index 000000000..3fbf74610 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 73cea0d25..aa3c82889 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1957,10 +1957,85 @@ 5 - + + 0 + 1 + 2 + + + + @string/off + @string/prefs_active_noise_cancelling + @string/prefs_ambient_sound + + + + 0 + 1 + + + + @string/prefs_active_noise_cancelling_level_low + @string/prefs_active_noise_cancelling_level_high + + + + + @string/pref_switch_noise_control + @string/pref_title_touch_voice_assistant + @string/pref_media_volumedown + @string/pref_title_touch_spotify + + + + @string/pref_switch_noise_control + @string/pref_title_touch_voice_assistant + @string/pref_media_volumeup + @string/pref_title_touch_spotify + + + + 2 + 1 + 3 + 4 + + + + @string/pref_switch_controls_anc_ambient + @string/pref_switch_controls_anc_off + @string/pref_switch_controls_ambient_off + + + + 0 + 1 + 2 + + + + @string/pref_voice_detect_duration_5 + @string/pref_voice_detect_duration_10 + @string/pref_voice_detect_duration_15 + + + + 0 + 1 + 2 + + + @string/pref_title_touch_voice_assistant @string/pref_title_touch_quick_ambient - @string/pref_title_touch_volume + @string/pref_media_volumedown + @string/pref_title_touch_ambient + + + + @string/pref_title_touch_voice_assistant + @string/pref_title_touch_quick_ambient + @string/pref_media_volumeup @string/pref_title_touch_ambient @@ -1971,10 +2046,16 @@ 3 - + @string/pref_title_touch_voice_assistant @string/pref_title_touch_anc - @string/pref_title_touch_volume + @string/pref_media_volumedown + + + + @string/pref_title_touch_voice_assistant + @string/pref_title_touch_anc + @string/pref_media_volumeup diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29ca3d806..32f0ddada 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1411,8 +1411,10 @@ Nothing Ear (1) Galaxy Buds Galaxy Buds Live + Galaxy Buds Pro Play/pause the music depending if you wear the earbuds In-Ear detection + Play calls through your earbuds when they are in your ears Audio mode Equalizer Preset Normal @@ -1430,22 +1432,60 @@ Touch Lock Disable touch events Experimental + Seamless connection switch + Switches the buds between paired devices automatically Ambient volume + Ambient Volume Left + Ambient Volume Right Voice Focus Make voice stand out Ambient Sound + Customize Ambient Sound + Ambient Sound during call + Hear own voice during call Ambient Mode + Ambient Sound Options Active Noise Cancelling + Active Noise Cancelling Level + High + Low Block noises of the surroundings Pressure relief with ambient sound Prevent feeling of pressure in ears when not using Active Noise Cancelling Left Right + Switch control left + Switch control right Touch Options Battery case Left earbud Right earbud Audio Codec + Voice Assistant + Active Noise Cancelling + Quick Ambient Sound + Volume + Ambient Sound + Spotify + Switch Noise Control + Noise Control with one earbud + Allow noise control when using one earbud only + Ambient Sound Tone + From Soft to Clear + Balance + Noise cancelling ←→ Ambient + Noise cancelling ←→ Off + Ambient ←→ Off + Noise control + Voice detect + Enable Ambient sound and lower playback automatically after voice has been detected + Double tap edge + Detect double tap even when not taped on touch pad + End after quiet for: + 5 seconds + 10 seconds + 15 seconds + Ambient Sound Control Device Information Mode diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index e71663e87..994aa41ee 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -113,11 +113,6 @@ FITNESS_CONTROL_START FITNESS_CONTROL_STOP FITNESS_CONTROL_TOGGLE - Voice Assistant - Active Noise Cancelling - Quick Ambient Sound - Volume - Ambient Sound system light diff --git a/app/src/main/res/xml/devicesettings_galaxy_buds.xml b/app/src/main/res/xml/devicesettings_galaxy_buds.xml index a86a87a72..a44eb570f 100644 --- a/app/src/main/res/xml/devicesettings_galaxy_buds.xml +++ b/app/src/main/res/xml/devicesettings_galaxy_buds.xml @@ -1,5 +1,6 @@ - + + android:max="5" + android:title="@string/prefs_ambient_volume" + app:min="1" + app:showSeekBarValue="true" /> @@ -75,7 +78,7 @@ android:title="@string/prefs_touch_lock" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +