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 72eb79718..cda7bf042 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
@@ -112,34 +112,20 @@ public class DeviceSettingsPreferenceConst {
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_SONY_AUDIO_CODEC = "pref_sony_audio_codec";
public static final String PREF_SONY_AMBIENT_SOUND_CONTROL = "pref_sony_ambient_sound_control";
public static final String PREF_SONY_FOCUS_VOICE = "pref_sony_focus_voice";
public static final String PREF_SONY_AMBIENT_SOUND_LEVEL = "pref_sony_ambient_sound_level";
public static final String PREF_SONY_SOUND_POSITION = "pref_sony_sound_position";
public static final String PREF_SONY_SURROUND_MODE = "pref_sony_surround_mode";
public static final String PREF_SONY_EQUALIZER_MODE = "pref_sony_equalizer_mode";
- public static final String PREF_SONY_DSEE_HX = "pref_sony_dsee_hx";
- public static final String PREF_SONY_EQUALIZER_PRESET_MANUAL = "pref_sony_equalizer_preset_manual";
- public static final String PREF_SONY_EQUALIZER_PRESET_CUSTOM_1 = "pref_sony_equalizer_preset_custom_1";
- public static final String PREF_SONY_EQUALIZER_PRESET_CUSTOM_2 = "pref_sony_equalizer_preset_custom_2";
- public static final String PREF_SONY_EQUALIZER_MANUAL_BAND_400 = "pref_sony_equalizer_manual_band_400";
- public static final String PREF_SONY_EQUALIZER_MANUAL_BAND_1000 = "pref_sony_equalizer_manual_band_1000";
- public static final String PREF_SONY_EQUALIZER_MANUAL_BAND_2500 = "pref_sony_equalizer_manual_band_2500";
- public static final String PREF_SONY_EQUALIZER_MANUAL_BAND_6300 = "pref_sony_equalizer_manual_band_6300";
- public static final String PREF_SONY_EQUALIZER_MANUAL_BAND_16000 = "pref_sony_equalizer_manual_band_16000";
- public static final String PREF_SONY_EQUALIZER_MANUAL_CLEAR_BASS = "pref_sony_equalizer_manual_clear_bass";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_BAND_400 = "pref_sony_equalizer_custom_1_band_400";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_BAND_1000 = "pref_sony_equalizer_custom_1_band_1000";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_BAND_2500 = "pref_sony_equalizer_custom_1_band_2500";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_BAND_6300 = "pref_sony_equalizer_custom_1_band_6300";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_BAND_16000 = "pref_sony_equalizer_custom_1_band_16000";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_1_CLEAR_BASS = "pref_sony_equalizer_custom_1_clear_bass";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_BAND_400 = "pref_sony_equalizer_custom_2_band_400";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_BAND_1000 = "pref_sony_equalizer_custom_2_band_1000";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_BAND_2500 = "pref_sony_equalizer_custom_2_band_2500";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_BAND_6300 = "pref_sony_equalizer_custom_2_band_6300";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_BAND_16000 = "pref_sony_equalizer_custom_2_band_16000";
- public static final String PREF_SONY_EQUALIZER_CUSTOM_2_CLEAR_BASS = "pref_sony_equalizer_custom_2_clear_bass";
+ public static final String PREF_SONY_AUDIO_UPSAMPLING = "pref_sony_audio_upsampling";
+ public static final String PREF_SONY_EQUALIZER_BAND_400 = "pref_sony_equalizer_band_400";
+ public static final String PREF_SONY_EQUALIZER_BAND_1000 = "pref_sony_equalizer_band_1000";
+ public static final String PREF_SONY_EQUALIZER_BAND_2500 = "pref_sony_equalizer_band_2500";
+ public static final String PREF_SONY_EQUALIZER_BAND_6300 = "pref_sony_equalizer_band_6300";
+ public static final String PREF_SONY_EQUALIZER_BAND_16000 = "pref_sony_equalizer_band_16000";
+ public static final String PREF_SONY_EQUALIZER_BASS = "pref_sony_equalizer_bass";
public static final String PREF_SONY_TOUCH_SENSOR = "pref_sony_touch_sensor";
public static final String PREF_SONY_AUTOMATIC_POWER_OFF = "pref_sony_automatic_power_off";
public static final String PREF_SONY_NOTIFICATION_VOICE_GUIDE = "pref_sony_notification_voice_guide";
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 23bfed87a..63aab472b 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
@@ -51,7 +51,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
-import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
@@ -124,7 +123,6 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONYSWR12_STAMINA;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SOUNDS;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TIMEFORMAT;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_VIBRATION_STRENGH_PERCENTAGE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_WEARLOCATION;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_VIBRATION_ENABLE;
@@ -136,25 +134,13 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SURROUND_MODE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MODE;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_BAND_400;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_BAND_1000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_BAND_2500;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_BAND_6300;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_BAND_16000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MANUAL_CLEAR_BASS;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_BAND_400;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_BAND_1000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_BAND_2500;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_BAND_6300;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_BAND_16000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_1_CLEAR_BASS;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_BAND_400;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_BAND_1000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_BAND_2500;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_BAND_6300;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_BAND_16000;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_CUSTOM_2_CLEAR_BASS;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_DSEE_HX;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_400;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_1000;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_2500;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_6300;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_16000;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BASS;
+import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_UPSAMPLING;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_TOUCH_SENSOR;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_AUTOMATIC_POWER_OFF;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_NOTIFICATION_VOICE_GUIDE;
@@ -566,25 +552,13 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
addPreferenceHandlerFor(PREF_SONY_SOUND_POSITION);
addPreferenceHandlerFor(PREF_SONY_SURROUND_MODE);
addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MODE);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_BAND_400);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_BAND_1000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_BAND_2500);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_BAND_6300);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_BAND_16000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MANUAL_CLEAR_BASS);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_BAND_400);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_BAND_1000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_BAND_2500);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_BAND_6300);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_BAND_16000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_1_CLEAR_BASS);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_BAND_400);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_BAND_1000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_BAND_2500);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_BAND_6300);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_BAND_16000);
- addPreferenceHandlerFor(PREF_SONY_EQUALIZER_CUSTOM_2_CLEAR_BASS);
- addPreferenceHandlerFor(PREF_SONY_DSEE_HX);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_400);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_1000);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_2500);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_6300);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BAND_16000);
+ addPreferenceHandlerFor(PREF_SONY_EQUALIZER_BASS);
+ addPreferenceHandlerFor(PREF_SONY_AUDIO_UPSAMPLING);
addPreferenceHandlerFor(PREF_SONY_TOUCH_SENSOR);
addPreferenceHandlerFor(PREF_SONY_AUTOMATIC_POWER_OFF);
addPreferenceHandlerFor(PREF_SONY_NOTIFICATION_VOICE_GUIDE);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java
index 0ebb9e96f..bcd415b47 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java
@@ -97,6 +97,7 @@ public class AmazfitBipUCoordinator extends HuamiCoordinator {
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_amazfitbipu,
+ //R.xml.devicesettings_canned_dismisscall_16,
R.xml.devicesettings_timeformat,
R.xml.devicesettings_wearlocation,
R.xml.devicesettings_custom_emoji_font,
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AmbientSoundControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AmbientSoundControl.java
deleted file mode 100644
index 915fe5764..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AmbientSoundControl.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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.sony.headphones;
-
-public enum AmbientSoundControl {
- OFF,
- NOISE_CANCELLING,
- WIND_NOISE_REDUCTION,
- AMBIENT_SOUND
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerCustomBands.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerCustomBands.java
deleted file mode 100644
index d739cd2f8..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerCustomBands.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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.sony.headphones;
-
-import java.util.List;
-
-public class EqualizerCustomBands {
- private List bands;
- private int clearBass;
-
- public EqualizerCustomBands(List bands, int clearBass) {
- if (bands.size() != 5) {
- throw new IllegalArgumentException("Equalizer needs exactly 5 bands");
- }
-
- for (Integer band : bands) {
- if (band < -10 || band > 10) {
- throw new IllegalArgumentException(String.format("Bands should be between -10 and 10, got %d", band));
- }
- }
-
- if (clearBass < -10 || clearBass > 10) {
- throw new IllegalArgumentException(String.format("Clear Bass value shoulud be between -10 and 10, got %d", clearBass));
- }
-
- this.bands = bands;
- this.clearBass = clearBass;
- }
-
- public List getBands() {
- return bands;
- }
-
- public int getClearBass() {
- return clearBass;
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java
index 90f5f9a85..1834e462e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java
@@ -41,7 +41,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractDeviceCoordinato
@Override
public DeviceSpecificSettingsCustomizer getDeviceSpecificSettingsCustomizer(final GBDevice device) {
- return new SonySettingsCustomizer();
+ return new SonyHeadphonesSettingsCustomizer();
}
@Override
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
new file mode 100644
index 000000000..7cb85c9af
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java
@@ -0,0 +1,56 @@
+/* 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.sony.headphones;
+
+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_FOCUS_VOICE;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+import java.util.Locale;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl;
+
+public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
+ @Override
+ public void customizeSettings(final DeviceSpecificSettingsHandler handler) {
+ // 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);
+ if (ambientSoundControl != null) {
+ final Preference focusOnVoice = handler.findPreference(PREF_SONY_FOCUS_VOICE);
+ final Preference ambientSoundLevel = handler.findPreference(PREF_SONY_AMBIENT_SOUND_LEVEL);
+
+ final Preference.OnPreferenceChangeListener ambientSoundControlPrefListener = new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newVal) {
+ boolean isAmbientSoundEnabled = AmbientSoundControl.Mode.AMBIENT_SOUND.name().toLowerCase(Locale.getDefault()).equals(newVal);
+ focusOnVoice.setEnabled(isAmbientSoundEnabled);
+ ambientSoundLevel.setEnabled(isAmbientSoundEnabled);
+
+ return true;
+ }
+ };
+
+ ambientSoundControlPrefListener.onPreferenceChange(ambientSoundControl, ambientSoundControl.getValue());
+ handler.addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL, ambientSoundControlPrefListener);
+ }
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonySettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonySettingsCustomizer.java
deleted file mode 100644
index 03bf5919b..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonySettingsCustomizer.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/* 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.sony.headphones;
-
-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_EQUALIZER_MODE;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_PRESET_CUSTOM_1;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_PRESET_CUSTOM_2;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_PRESET_MANUAL;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_FOCUS_VOICE;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION;
-import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SURROUND_MODE;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-
-import java.util.Locale;
-
-import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
-import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
-
-public class SonySettingsCustomizer implements DeviceSpecificSettingsCustomizer {
- @Override
- public void customizeSettings(final DeviceSpecificSettingsHandler handler) {
- // 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);
- if (ambientSoundControl != null) {
- final Preference focusOnVoice = handler.findPreference(PREF_SONY_FOCUS_VOICE);
- final Preference ambientSoundLevel = handler.findPreference(PREF_SONY_AMBIENT_SOUND_LEVEL);
-
- final Preference.OnPreferenceChangeListener ambientSoundControlPrefListener = new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newVal) {
- boolean isAmbientSoundEnabled = AmbientSoundControl.AMBIENT_SOUND.name().toLowerCase(Locale.ROOT).equals(newVal);
- focusOnVoice.setEnabled(isAmbientSoundEnabled);
- ambientSoundLevel.setEnabled(isAmbientSoundEnabled);
-
- return true;
- }
- };
-
- ambientSoundControlPrefListener.onPreferenceChange(ambientSoundControl, ambientSoundControl.getValue());
- handler.addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL, ambientSoundControlPrefListener);
- }
-
- // Make the sound position and surround mode settings mutually exclusive
-
- final ListPreference soundPositionPref = handler.findPreference(PREF_SONY_SOUND_POSITION);
- final ListPreference surroundModePref = handler.findPreference(PREF_SONY_SURROUND_MODE);
-
- if (soundPositionPref != null && surroundModePref != null) {
- final Preference.OnPreferenceChangeListener soundPositionPrefListener = new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newVal) {
- SoundPosition soundPosition = SoundPosition.valueOf(newVal.toString().toUpperCase(Locale.ROOT));
- surroundModePref.setEnabled(SoundPosition.OFF.equals(soundPosition));
-
- return true;
- }
- };
-
- final Preference.OnPreferenceChangeListener surroundModePrefListener = new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newVal) {
- SurroundMode surroundMode = SurroundMode.valueOf(newVal.toString().toUpperCase(Locale.ROOT));
- soundPositionPref.setEnabled(SurroundMode.OFF.equals(surroundMode));
-
- return true;
- }
- };
-
- soundPositionPrefListener.onPreferenceChange(soundPositionPref, soundPositionPref.getValue());
- surroundModePrefListener.onPreferenceChange(surroundModePref, surroundModePref.getValue());
- handler.addPreferenceHandlerFor(PREF_SONY_SOUND_POSITION, soundPositionPrefListener);
- handler.addPreferenceHandlerFor(PREF_SONY_SURROUND_MODE, surroundModePrefListener);
- }
-
- // Only enable the equalizer preset if the corresponding mode is selected
-
- final ListPreference equalizerModePref = handler.findPreference(PREF_SONY_EQUALIZER_MODE);
-
- if (equalizerModePref != null) {
- handler.addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MODE);
-
- final Preference presetManual = handler.findPreference(PREF_SONY_EQUALIZER_PRESET_MANUAL);
- final Preference presetCustom1 = handler.findPreference(PREF_SONY_EQUALIZER_PRESET_CUSTOM_1);
- final Preference presetCustom2 = handler.findPreference(PREF_SONY_EQUALIZER_PRESET_CUSTOM_2);
-
- final Preference.OnPreferenceChangeListener equalizerModePrefListener = new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newVal) {
- final EqualizerPreset equalizerPreset = EqualizerPreset.valueOf(newVal.toString().toUpperCase(Locale.ROOT));
-
- presetManual.setEnabled(EqualizerPreset.MANUAL.equals(equalizerPreset));
- presetCustom1.setEnabled(EqualizerPreset.CUSTOM_1.equals(equalizerPreset));
- presetCustom2.setEnabled(EqualizerPreset.CUSTOM_2.equals(equalizerPreset));
-
- return true;
- }
- };
-
- equalizerModePrefListener.onPreferenceChange(equalizerModePref, equalizerModePref.getValue());
- handler.addPreferenceHandlerFor(PREF_SONY_EQUALIZER_MODE, equalizerModePrefListener);
- }
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/wh1000xm3/SonyWh1000Xm3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java
similarity index 75%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/wh1000xm3/SonyWh1000Xm3Coordinator.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java
index 71fb6de01..bfd9a6d4c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/wh1000xm3/SonyWh1000Xm3Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java
@@ -14,7 +14,7 @@
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.sony.headphones.wh1000xm3;
+package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators;
import androidx.annotation.NonNull;
@@ -24,13 +24,14 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
-public class SonyWh1000Xm3Coordinator extends SonyHeadphonesCoordinator {
+public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator {
@NonNull
@Override
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
if (candidate.getName().contains("WH-1000XM3")) {
return DeviceType.SONY_WH_1000XM3;
}
+
return DeviceType.UNKNOWN;
}
@@ -44,9 +45,15 @@ public class SonyWh1000Xm3Coordinator extends SonyHeadphonesCoordinator {
return new int[]{
R.xml.devicesettings_sony_warning_wh1000xm3,
R.xml.devicesettings_sony_headphones_ambient_sound_control,
+ R.xml.devicesettings_header_other,
R.xml.devicesettings_sony_headphones_equalizer,
- R.xml.devicesettings_sony_headphones_other,
- R.xml.devicesettings_sony_wh_1000xm3
+ R.xml.devicesettings_sony_headphones_sound_position,
+ R.xml.devicesettings_sony_headphones_surround_mode,
+ R.xml.devicesettings_sony_headphones_audio_upsampling,
+ R.xml.devicesettings_header_system,
+ R.xml.devicesettings_sony_headphones_touch_sensor_single,
+ R.xml.devicesettings_automatic_power_off,
+ R.xml.devicesettings_sony_headphones_notifications_voice_guide
};
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AmbientSoundControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AmbientSoundControl.java
new file mode 100644
index 000000000..ed4a6a067
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AmbientSoundControl.java
@@ -0,0 +1,87 @@
+/* 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.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public class AmbientSoundControl {
+ public enum Mode {
+ OFF,
+ NOISE_CANCELLING,
+ WIND_NOISE_REDUCTION,
+ AMBIENT_SOUND
+ }
+
+ private final Mode mode;
+ private final boolean focusOnVoice;
+ private final int ambientSound;
+
+ public AmbientSoundControl(Mode mode, boolean focusOnVoice, int ambientSound) {
+ if (ambientSound < 0 || ambientSound > 20) {
+ throw new IllegalArgumentException(String.format("Level must be between 0 and 20 (was %d)", ambientSound));
+ }
+
+ this.mode = mode;
+ this.focusOnVoice = focusOnVoice;
+ this.ambientSound = ambientSound;
+ }
+
+ public String toString() {
+ return String.format(Locale.getDefault(), "AmbientSoundControl{mode=%s, focusOnVoice=%s, ambientSound=%d}", mode, focusOnVoice, ambientSound);
+ }
+
+ public Mode getMode() {
+ return mode;
+ }
+
+ public boolean isFocusOnVoice() {
+ return focusOnVoice;
+ }
+
+ public int getAmbientSound() {
+ return ambientSound;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_CONTROL, mode.name().toLowerCase(Locale.getDefault()));
+
+ if (AmbientSoundControl.Mode.AMBIENT_SOUND.equals(mode)) {
+ // Only use the ambient sound levels and focus on voice if we're on ambient sound mode,
+ // to prevent overriding the user settings
+ put(DeviceSettingsPreferenceConst.PREF_SONY_FOCUS_VOICE, focusOnVoice);
+ // Level is offset by 1 because we can't configure the SeekBarPreference min level on the current api level
+ put(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL, ambientSound - 1);
+ }
+ }};
+ }
+
+ public static AmbientSoundControl fromPreferences(final SharedPreferences prefs) {
+ final String soundControl = prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_CONTROL, "noise_cancelling");
+ final boolean focusVoice = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_FOCUS_VOICE, false);
+ // Level is offset by 1 because we can't configure the SeekBarPreference min level on the current api level
+ final int ambientSound = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL, 0) + 1;
+
+ return new AmbientSoundControl(AmbientSoundControl.Mode.valueOf(soundControl.toUpperCase()), focusVoice, ambientSound);
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioUpsampling.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioUpsampling.java
new file mode 100644
index 000000000..4f4f1811c
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AudioUpsampling.java
@@ -0,0 +1,46 @@
+/* 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.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public class AudioUpsampling {
+ private final boolean enabled;
+
+ public AudioUpsampling(final boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_UPSAMPLING, enabled);
+ }};
+ }
+
+ public static AudioUpsampling fromPreferences(final SharedPreferences prefs) {
+ return new AudioUpsampling(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_AUDIO_UPSAMPLING, false));
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AutomaticPowerOff.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AutomaticPowerOff.java
similarity index 61%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AutomaticPowerOff.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AutomaticPowerOff.java
index 2c9c3fc20..325f4fe03 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/AutomaticPowerOff.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/AutomaticPowerOff.java
@@ -14,7 +14,15 @@
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.sony.headphones;
+package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
public enum AutomaticPowerOff {
OFF(new byte[]{(byte) 0x11, (byte) 0x00}),
@@ -24,9 +32,23 @@ public enum AutomaticPowerOff {
AFTER_3_HOUR(new byte[]{(byte) 0x03, (byte) 0x03}),
WHEN_TAKEN_OFF(new byte[]{(byte) 0x10, (byte) 0x00});
- public final byte[] code;
+ private final byte[] code;
AutomaticPowerOff(final byte[] code) {
this.code = code;
}
+
+ public byte[] getCode() {
+ return this.code;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_AUTOMATIC_POWER_OFF, name().toLowerCase(Locale.getDefault()));
+ }};
+ }
+
+ public static AutomaticPowerOff fromPreferences(final SharedPreferences prefs) {
+ return AutomaticPowerOff.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_AUTOMATIC_POWER_OFF, "off").toUpperCase());
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerCustomBands.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerCustomBands.java
new file mode 100644
index 000000000..ee61e1464
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerCustomBands.java
@@ -0,0 +1,85 @@
+/* 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.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public class EqualizerCustomBands {
+ private List bands;
+ private int bass;
+
+ public EqualizerCustomBands(final List bands, final int bass) {
+ if (bands.size() != 5) {
+ throw new IllegalArgumentException("Equalizer needs exactly 5 bands");
+ }
+
+ for (final Integer band : bands) {
+ if (band < -10 || band > 10) {
+ throw new IllegalArgumentException(String.format("Bands should be between -10 and 10, got %d", band));
+ }
+ }
+
+ if (bass < -10 || bass > 10) {
+ throw new IllegalArgumentException(String.format("Clear Bass value shoulud be between -10 and 10, got %d", bass));
+ }
+
+ this.bands = bands;
+ this.bass = bass;
+ }
+
+ public List getBands() {
+ return bands;
+ }
+
+ public int getBass() {
+ return bass;
+ }
+
+ public String toString() {
+ return String.format("EqualizerCustomBands{clearBass=%d, bands=%s}", bass, bands);
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_400, bands.get(0) + 10);
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_1000, bands.get(1) + 10);
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_2500, bands.get(2) + 10);
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_6300, bands.get(3) + 10);
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_16000, bands.get(4) + 10);
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BASS, bass + 10);
+ ;
+ }};
+ }
+
+ public static EqualizerCustomBands fromPreferences(final SharedPreferences prefs) {
+ int band1 = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_400, 10) - 10;
+ int band2 = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_1000, 10) - 10;
+ int band3 = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_2500, 10) - 10;
+ int band4 = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_6300, 10) - 10;
+ int band5 = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BAND_16000, 10) - 10;
+ int bass = prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_BASS, 10) - 10;
+
+ return new EqualizerCustomBands(Arrays.asList(band1, band2, band3, band4, band5), bass);
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerPreset.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerPreset.java
new file mode 100644
index 000000000..b0ac4883e
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/EqualizerPreset.java
@@ -0,0 +1,60 @@
+/* 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.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public enum EqualizerPreset {
+ OFF((byte) 0x00),
+ BRIGHT((byte) 0x10),
+ EXCITED((byte) 0x11),
+ MELLOW((byte) 0x12),
+ RELAXED((byte) 0x13),
+ VOCAL((byte) 0x14),
+ TREBLE_BOOST((byte) 0x15),
+ BASS_BOOST((byte) 0x16),
+ SPEECH((byte) 0x17),
+ MANUAL((byte) 0xa0),
+ CUSTOM_1((byte) 0xa1),
+ CUSTOM_2((byte) 0xa2);
+
+ private final byte code;
+
+ EqualizerPreset(final byte code) {
+ this.code = code;
+ }
+
+ public byte getCode() {
+ return this.code;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MODE, name().toLowerCase(Locale.getDefault()));
+ }};
+ }
+
+ public static EqualizerPreset fromPreferences(final SharedPreferences prefs) {
+ return EqualizerPreset.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MODE, "off").toUpperCase());
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SoundPosition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SoundPosition.java
similarity index 58%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SoundPosition.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SoundPosition.java
index eca7063aa..15b2bf4fd 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SoundPosition.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SoundPosition.java
@@ -14,7 +14,15 @@
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.sony.headphones;
+package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
public enum SoundPosition {
OFF((byte) 0x00),
@@ -24,9 +32,23 @@ public enum SoundPosition {
REAR_LEFT((byte) 0x11),
REAR_RIGHT((byte) 0x12);
- public final byte code;
+ private final byte code;
SoundPosition(final byte code) {
this.code = code;
}
+
+ public byte getCode() {
+ return this.code;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION, name().toLowerCase(Locale.getDefault()));
+ }};
+ }
+
+ public static SoundPosition fromPreferences(final SharedPreferences prefs) {
+ return SoundPosition.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION, "off").toUpperCase());
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SurroundMode.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SurroundMode.java
similarity index 57%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SurroundMode.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SurroundMode.java
index 0953c0e1c..a62fecea8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SurroundMode.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/SurroundMode.java
@@ -14,7 +14,15 @@
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.sony.headphones;
+package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
public enum SurroundMode {
OFF((byte) 0x00),
@@ -23,9 +31,23 @@ public enum SurroundMode {
OUTDOOR_STAGE((byte) 0x01),
CONCERT_HALL((byte) 0x03);
- public final byte code;
+ private final byte code;
SurroundMode(final byte code) {
this.code = code;
}
+
+ public byte getCode() {
+ return this.code;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_SURROUND_MODE, name().toLowerCase(Locale.getDefault()));
+ }};
+ }
+
+ public static SurroundMode fromPreferences(final SharedPreferences prefs) {
+ return SurroundMode.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION, "off").toUpperCase());
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerPreset.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/TouchSensor.java
similarity index 50%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerPreset.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/TouchSensor.java
index 94aa0a1df..3923edf3b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/EqualizerPreset.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/TouchSensor.java
@@ -14,25 +14,33 @@
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.sony.headphones;
+package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs;
-public enum EqualizerPreset {
- OFF(new byte[] {(byte) 0x00, (byte) 0x00}),
- BRIGHT(new byte[] {(byte) 0x10, (byte) 0x00}),
- EXCITED(new byte[] {(byte) 0x11, (byte) 0x00}),
- MELLOW(new byte[] {(byte) 0x12, (byte) 0x00}),
- RELAXED(new byte[] {(byte) 0x13, (byte) 0x00}),
- VOCAL(new byte[] {(byte) 0x14, (byte) 0x00}),
- TREBLE_BOOST(new byte[] {(byte) 0x15, (byte) 0x00}),
- BASS_BOOST(new byte[] {(byte) 0x16, (byte) 0x00}),
- SPEECH(new byte[] {(byte) 0x17, (byte) 0x00}),
- MANUAL(new byte[] {(byte) 0xa0, (byte) 0x00}),
- CUSTOM_1(new byte[] {(byte) 0xa1, (byte) 0x00}),
- CUSTOM_2(new byte[] {(byte) 0xa2, (byte) 0x00});
+import android.content.SharedPreferences;
- public final byte[] code;
+import java.util.HashMap;
+import java.util.Map;
- EqualizerPreset(final byte[] code) {
- this.code = code;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public class TouchSensor {
+ private final boolean enabled;
+
+ public TouchSensor(final boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_TOUCH_SENSOR, enabled);
+ }};
+ }
+
+ public static TouchSensor fromPreferences(final SharedPreferences prefs) {
+ return new TouchSensor(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_TOUCH_SENSOR, true));
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/VoiceNotifications.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/VoiceNotifications.java
new file mode 100644
index 000000000..8fbbc9a65
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/prefs/VoiceNotifications.java
@@ -0,0 +1,46 @@
+/* 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.sony.headphones.prefs;
+
+import android.content.SharedPreferences;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
+
+public class VoiceNotifications {
+ private final boolean enabled;
+
+ public VoiceNotifications(final boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public Map toPreferences() {
+ return new HashMap() {{
+ put(DeviceSettingsPreferenceConst.PREF_SONY_NOTIFICATION_VOICE_GUIDE, enabled);
+ }};
+ }
+
+ public static VoiceNotifications fromPreferences(final SharedPreferences prefs) {
+ return new VoiceNotifications(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SONY_NOTIFICATION_VOICE_GUIDE, true));
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java
index 6cda8596e..9f1c7312b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java
@@ -78,6 +78,7 @@ public class AppNotificationType extends HashMap {
// Telegram
put("org.telegram.messenger", NotificationType.TELEGRAM);
put("org.telegram.messenger.beta", NotificationType.TELEGRAM);
+ put("org.telegram.messenger.web", NotificationType.TELEGRAM);
put("org.telegram.plus", NotificationType.TELEGRAM); // "Plus Messenger"
put("org.thunderdog.challegram", NotificationType.TELEGRAM);
put("nekox.messenger", NotificationType.TELEGRAM);
@@ -170,6 +171,9 @@ public class AppNotificationType extends HashMap {
// Etar
put("ws.xsoh.etar", NotificationType.GENERIC_CALENDAR);
+
+ // Discord
+ put("com.discord", NotificationType.DISCORD);
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java
index 759a4a315..56389ab09 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java
@@ -63,6 +63,7 @@ public enum NotificationType {
THREEMA(PebbleIconID.NOTIFICATION_HIPCHAT, PebbleColor.JaegerGreen),
KONTALK(PebbleIconID.NOTIFICATION_HIPCHAT, PebbleColor.JaegerGreen),
ANTOX(PebbleIconID.NOTIFICATION_HIPCHAT, PebbleColor.JaegerGreen),
+ DISCORD(PebbleIconID.NOTIFICATION_HIPCHAT, PebbleColor.Purpureus),
TRANSIT(PebbleIconID.LOCATION, PebbleColor.JaegerGreen),
TWITTER(PebbleIconID.NOTIFICATION_TWITTER, PebbleColor.BlueMoon),
VIBER(PebbleIconID.NOTIFICATION_VIBER, PebbleColor.VividViolet),
@@ -122,6 +123,7 @@ public enum NotificationType {
case SLACK:
case LINE:
case VIBER:
+ case DISCORD:
return "generic_chat";
case GMAIL:
case GOOGLE_INBOX:
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java
index 6db2d9832..10dad1269 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java
@@ -82,7 +82,7 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
LOG.error("mOutStream is null");
return;
}
- LOG.debug("writing:" + GB.hexdump(bytes, 0, bytes.length));
+ LOG.debug("writing: {}", GB.hexdump(bytes, 0, bytes.length));
try {
mOutStream.write(bytes);
mOutStream.flush();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java
index 0a790a9db..72550e85b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiIcon.java
@@ -64,28 +64,28 @@ public class HuamiIcon {
public static byte mapToIconId(NotificationType type) {
switch (type) {
case UNKNOWN:
+ case GENERIC_NAVIGATION:
return APP_11;
case CONVERSATIONS:
case RIOT:
case HIPCHAT:
case KONTALK:
case ANTOX:
+ case GENERIC_SMS:
+ case WECHAT:
return WECHAT;
case GENERIC_EMAIL:
case GMAIL:
case YAHOO_MAIL:
case OUTLOOK:
return EMAIL;
- case GENERIC_NAVIGATION:
- return APP_11;
- case GENERIC_SMS:
- return WECHAT;
case GENERIC_CALENDAR:
case BUSINESS_CALENDAR:
return CALENDAR;
case FACEBOOK:
return FACEBOOK;
case FACEBOOK_MESSENGER:
+ case SIGNAL:
return FACEBOOK_MESSENGER;
case GOOGLE_HANGOUTS:
case GOOGLE_MESSENGER:
@@ -97,9 +97,8 @@ public class HuamiIcon {
return KAKAOTALK;
case LINE:
return LINE;
- case SIGNAL:
- return FACEBOOK_MESSENGER;
case WIRE:
+ case THREEMA:
return CHAT_BLUE_13;
case TWITTER:
return TWITTER;
@@ -109,12 +108,9 @@ public class HuamiIcon {
return SNAPCHAT;
case TELEGRAM:
return TELEGRAM;
- case THREEMA:
- return CHAT_BLUE_13;
case VIBER:
+ case DISCORD:
return VIBER;
- case WECHAT:
- return WECHAT;
case WHATSAPP:
return WHATSAPP;
case GENERIC_ALARM_CLOCK:
@@ -122,4 +118,30 @@ public class HuamiIcon {
}
return APP_11;
}
+
+ //amazfit workaround
+ public static boolean acceptsSender(byte iconId){
+ switch(iconId){
+ case WECHAT:
+ case PENGUIN_1:
+ case MI_CHAT_2:
+ case SNAPCHAT:
+ case WHATSAPP:
+ case RED_WHITE_FIRE_8:
+ case INSTAGRAM:
+ case CHAT_BLUE_13:
+ case COW_14:
+ case CHINESE_20:
+ case FACEBOOK_MESSENGER:
+ case VIBER:
+ case LINE:
+ case TELEGRAM:
+ case VKONTAKTE:
+ case CHINESE_32:
+ case EMAIL:
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java
index c927c1958..654927db9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java
@@ -1004,6 +1004,27 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
@Override
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
+ if (cannedMessagesSpec.type == CannedMessagesSpec.TYPE_REJECTEDCALLS) {
+ try {
+ TransactionBuilder builder = performInitialized("Set canned messages");
+
+ int handle = 0x12345678;
+ for (String cannedMessage : cannedMessagesSpec.cannedMessages) {
+ int length = cannedMessage.getBytes().length + 5;
+ ByteBuffer buf = ByteBuffer.allocate(length);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+
+ buf.put((byte) 0x05); // create
+ buf.putInt(handle++);
+ buf.put(cannedMessage.getBytes());
+
+ writeToChunked2021(builder, (short) 0x0013, getNextHandle(), buf.array(), false, false);
+ }
+ builder.queue(getQueue());
+ } catch (IOException ex) {
+ LOG.error("Unable to set time on Huami device", ex);
+ }
+ }
}
private boolean isAlarmClockRinging() {
@@ -2976,7 +2997,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
byte[] command = ArrayUtils.addAll(new byte[]{0x00, 0x00, (byte) (0xc0 | type), 0x00}, data);
- writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_COMPAT, getNextHandle(), command, encrypt);
+ writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_COMPAT, getNextHandle(), command, true, encrypt);
} else {
writeToChunkedOld(builder, type, data);
}
@@ -3010,13 +3031,17 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
}
- public void writeToChunked2021(TransactionBuilder builder, short type, byte handle, byte[] data, boolean encrypt) {
+ public void writeToChunked2021(TransactionBuilder builder, short type, byte handle, byte[] data, boolean extended_flags, boolean encrypt) {
int remaining = data.length;
int length = data.length;
byte count = 0;
- int header_size = 11;
+ int header_size = 10;
- if (encrypt) {
+ if (extended_flags) {
+ header_size++;
+ }
+
+ if (extended_flags && encrypt) {
byte[] messagekey = new byte[16];
for (int i = 0; i < 16; i++) {
messagekey[i] = (byte) (sharedSessionKey[i] ^ handle);
@@ -3060,26 +3085,40 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
if (count == 0) {
flags |= 0x01;
- chunk[5] = (byte) (length & 0xff);
- chunk[6] = (byte) ((length >> 8) & 0xff);
- chunk[7] = (byte) ((length >> 16) & 0xff);
- chunk[8] = (byte) ((length >> 24) & 0xff);
- chunk[9] = (byte) (type & 0xff);
- chunk[10] = (byte) ((type >> 8) & 0xff);
+ int i = 4;
+ if (extended_flags) {
+ i++;
+ }
+ chunk[i++] = (byte) (length & 0xff);
+ chunk[i++] = (byte) ((length >> 8) & 0xff);
+ chunk[i++] = (byte) ((length >> 16) & 0xff);
+ chunk[i++] = (byte) ((length >> 24) & 0xff);
+ chunk[i++] = (byte) (type & 0xff);
+ chunk[i] = (byte) ((type >> 8) & 0xff);
}
if (remaining <= MAX_CHUNKLENGTH) {
flags |= 0x06; // last chunk?
}
chunk[0] = 0x03;
chunk[1] = flags;
- chunk[2] = 0;
- chunk[3] = handle;
- chunk[4] = count;
+ if (extended_flags) {
+ chunk[2] = 0;
+ chunk[3] = handle;
+ chunk[4] = count;
+ } else {
+ chunk[2] = handle;
+ chunk[3] = count;
+ }
System.arraycopy(data, data.length - remaining, chunk, header_size, copybytes);
builder.write(characteristicChunked2021Write, chunk);
remaining -= copybytes;
- header_size = 5;
+ header_size = 4;
+
+ if (extended_flags) {
+ header_size++;
+ }
+
count++;
}
}
@@ -3087,7 +3126,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
public void writeToConfiguration(TransactionBuilder builder, byte[] data) {
if (force2021Protocol) {
data = ArrayUtils.insert(0, data, (byte) 1);
- writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_COMPAT, getNextHandle(), data, true);
+ writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_COMPAT, getNextHandle(), data, true, true);
} else {
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), data);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts2/AmazfitGTS2MiniSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts2/AmazfitGTS2MiniSupport.java
index 2730c7a99..612e94c8f 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts2/AmazfitGTS2MiniSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitgts2/AmazfitGTS2MiniSupport.java
@@ -18,17 +18,32 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts2;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts2.AmazfitGTS2MiniFWHelper;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
+import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
+import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts.AmazfitGTSSupport;
+import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class AmazfitGTS2MiniSupport extends AmazfitGTS2Support {
+ private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS2MiniSupport.class);
+
@Override
protected HuamiSupport setLanguage(TransactionBuilder builder) {
return setLanguageByIdNew(builder);
@@ -38,4 +53,122 @@ public class AmazfitGTS2MiniSupport extends AmazfitGTS2Support {
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
return new AmazfitGTS2MiniFWHelper(uri, context);
}
+
+ @Override
+ protected void sendNotificationNew(NotificationSpec notificationSpec, boolean hasExtraHeader, int maxLength) {
+ // step 1: bail out if this is an alarm clock notification
+
+ if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) {
+ onAlarmClock(notificationSpec);
+ return;
+ }
+
+ // step 2: (formerly in try block) get notification type
+ AlertCategory alertCategory = AlertCategory.CustomHuami;
+ byte customIconId = HuamiIcon.mapToIconId(notificationSpec.type);
+
+ // step 3: build notification (sender+body)
+ /*
+ * Format followed by the device:
+ * \0 \0
+ * sender will get ignored except for the icons
+ * specified on the HuamiIcon class.
+ * for email, App Suffix will be taken as sender
+ */
+ String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
+ boolean acceptsSender = HuamiIcon.acceptsSender(customIconId);
+ String message;
+
+ if (!acceptsSender && !senderOrTitle.equals(notificationSpec.sourceName)) {
+ // make sure we always include the notification sender/title
+ message = "-\0"; //leave title blank, it's useless
+ message += StringUtils.truncate(senderOrTitle, 64) + "\n";
+ } else {
+ message = StringUtils.truncate(senderOrTitle, 64) + "\0";
+ }
+
+ if (notificationSpec.subject != null) {
+ message += StringUtils.truncate(notificationSpec.subject, 128) + "\n\n";
+ }
+ if (notificationSpec.body != null) {
+ message += StringUtils.truncate(notificationSpec.body, 512);
+ }
+ if (notificationSpec.body == null && notificationSpec.subject == null) {
+ message += " "; // if we have no body we have to send at least something on some devices, else they reboot (Bip S)
+ }
+
+ try {
+ TransactionBuilder builder = performInitialized("new notification");
+
+ // step 4: append suffix
+ byte[] appSuffix = "\0 \0".getBytes();
+ int suffixlength = appSuffix.length;
+ // The SMS icon for AlertCategory.SMS is unique and not available as iconId
+ if (notificationSpec.type == NotificationType.GENERIC_SMS) {
+ alertCategory = AlertCategory.SMS;
+ }
+ // EMAIL icon does not work in FW 0.0.8.74, it did in 0.0.7.90 (old comment)
+ // EMAIL will take the sender from the suffix instead
+ else if (customIconId == HuamiIcon.EMAIL) {
+ alertCategory = AlertCategory.Email;
+ appSuffix = ("\0"+senderOrTitle+"\0").getBytes();
+ suffixlength = appSuffix.length;
+ }
+
+ // if I understood correctly, we don't need the extra logic for mi band 2 here
+ int prefixlength = 2;
+
+ if (alertCategory == AlertCategory.CustomHuami) {
+ String appName;
+ prefixlength = 3;
+ final PackageManager pm = getContext().getPackageManager();
+ ApplicationInfo ai = null;
+ try {
+ ai = pm.getApplicationInfo(notificationSpec.sourceAppId, 0);
+ } catch (PackageManager.NameNotFoundException ignored) {
+ }
+
+ if (ai == null) {
+ appName = "\0" + "UNKNOWN" + "\0";
+ } else {
+ appName = "\0" + pm.getApplicationLabel(ai) + "\0";
+ }
+ appSuffix = appName.getBytes();
+ suffixlength = appSuffix.length;
+ }
+ if (hasExtraHeader) {
+ prefixlength += 4;
+ }
+
+ // final step: build command
+ byte[] rawmessage = message.getBytes();
+ int length = Math.min(rawmessage.length, maxLength - prefixlength);
+ if (length < rawmessage.length) {
+ length = StringUtils.utf8ByteLength(message, length);
+ }
+
+ byte[] command = new byte[length + prefixlength + suffixlength];
+ int pos = 0;
+ command[pos++] = (byte) alertCategory.getId();
+ if (hasExtraHeader) {
+ command[pos++] = 0; // TODO
+ command[pos++] = 0;
+ command[pos++] = 0;
+ command[pos++] = 0;
+ }
+ command[pos++] = 1;
+ if (alertCategory == AlertCategory.CustomHuami) {
+ command[pos] = customIconId;
+ }
+
+ System.arraycopy(rawmessage, 0, command, prefixlength, length);
+ System.arraycopy(appSuffix, 0, command, prefixlength + length, appSuffix.length);
+
+ writeToChunked(builder, 0, command);
+
+ builder.queue(getQueue());
+ } catch (IOException ex) {
+ LOG.error("Unable to send notification to device", ex);
+ }
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation2021.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation2021.java
index a42ff6483..e4a5b17cc 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation2021.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation2021.java
@@ -87,7 +87,7 @@ public class InitOperation2021 extends InitOperation {
sendPubkeyCommand[3] = 0x02;
System.arraycopy(publicEC, 0, sendPubkeyCommand, 4, 48);
//testAuth();
- huamiSupport.writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_AUTH, huamiSupport.getNextHandle(), sendPubkeyCommand, false);
+ huamiSupport.writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_AUTH, huamiSupport.getNextHandle(), sendPubkeyCommand, true, false);
}
private native byte[] ecdh_generate_public(byte[] privateEC);
@@ -170,7 +170,7 @@ public class InitOperation2021 extends InitOperation {
System.arraycopy(encryptedRandom1, 0, command, 1, 16);
System.arraycopy(encryptedRandom2, 0, command, 17, 16);
TransactionBuilder builder = createTransactionBuilder("Sending double encryted random to device");
- huamiSupport.writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_AUTH, huamiSupport.getNextHandle(), command, false);
+ huamiSupport.writeToChunked2021(builder, HuamiService.CHUNKED2021_ENDPOINT_AUTH, huamiSupport.getNextHandle(), command, true, false);
huamiSupport.performImmediately(builder);
}
} catch (Exception e) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesIoThread.java
index 952e733d3..db80e8639 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesIoThread.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesIoThread.java
@@ -18,6 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
+import android.os.Handler;
import android.os.ParcelUuid;
import androidx.annotation.NonNull;
@@ -32,38 +33,80 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Message;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class SonyHeadphonesIoThread extends BtClassicIoThread {
private static final Logger LOG = LoggerFactory.getLogger(SonyHeadphonesIoThread.class);
+ private final SonyHeadphonesProtocol mProtocol;
+
+ // Track whether we got the first reply
+ private boolean firstReply = false;
+ private final Handler handler = new Handler();
+ private int initRetries = 0;
+
+ /**
+ * Sometimes the headphones will ignore the first init request, so we retry a few times
+ * TODO: Implement this in a more elegant way. Ideally, we should retry every command for which we didn't get an ACK.
+ */
+ private final Runnable initSendRunnable = new Runnable() {
+ public void run() {
+ // If we still haven't got any reply, re-send the init
+ if (!firstReply) {
+ if (initRetries++ < 2) {
+ LOG.warn("Init retry {}", initRetries);
+
+ write(mProtocol.encodeInit());
+ scheduleInitRetry();
+ } else {
+ LOG.error("Failed to start headphones init after {} tries", initRetries);
+ quit();
+ }
+ }
+ }
+ };
+
public SonyHeadphonesIoThread(GBDevice gbDevice, Context context, SonyHeadphonesProtocol protocol, SonyHeadphonesSupport support, BluetoothAdapter btAdapter) {
super(gbDevice, context, protocol, support, btAdapter);
+ mProtocol = protocol;
+ }
+
+ @Override
+ protected void initialize() {
+ write(mProtocol.encodeInit());
+ scheduleInitRetry();
+ setUpdateState(GBDevice.State.INITIALIZING);
+ }
+
+ @Override
+ public synchronized void write(byte[] bytes) {
+ // Log the human-readable message, for debugging
+ LOG.info("Writing {}", Message.fromBytes(bytes));
+
+ super.write(bytes);
}
@Override
protected byte[] parseIncoming(InputStream inputStream) throws IOException {
- ByteArrayOutputStream msgStream = new ByteArrayOutputStream();
- byte[] incoming = new byte[1];
+ final ByteArrayOutputStream msgStream = new ByteArrayOutputStream();
+ final byte[] incoming = new byte[1];
- while (true) {
+ do {
inputStream.read(incoming);
- if (incoming[0] == SonyHeadphonesProtocol.PACKET_HEADER) {
+ if (incoming[0] == Message.MESSAGE_HEADER) {
msgStream.reset();
- continue;
- }
-
- if (incoming[0] == SonyHeadphonesProtocol.PACKET_TRAILER) {
- break;
}
msgStream.write(incoming);
- }
+ } while (incoming[0] != Message.MESSAGE_TRAILER);
- byte[] msgArray = msgStream.toByteArray();
- LOG.debug("Received: " + GB.hexdump(msgArray, 0, msgArray.length));
- return msgArray;
+ firstReply = true;
+
+ LOG.trace("Raw message: {}", GB.hexdump(msgStream.toByteArray()));
+
+ return msgStream.toByteArray();
}
@NonNull
@@ -71,4 +114,10 @@ public class SonyHeadphonesIoThread extends BtClassicIoThread {
protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) {
return UUID.fromString("96CC203E-5068-46ad-B32D-E316F5E069BA");
}
+
+ private void scheduleInitRetry() {
+ LOG.info("Scheduling init retry");
+
+ handler.postDelayed(initSendRunnable, 1250);
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java
index e203fd537..4ec87f4db 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/SonyHeadphonesProtocol.java
@@ -21,386 +21,233 @@ 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.Arrays;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.AmbientSoundControl;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.AutomaticPowerOff;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.EqualizerCustomBands;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.EqualizerPreset;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SoundPosition;
-import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SurroundMode;
+import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdateDeviceState;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerCustomBands;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.EqualizerPreset;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SoundPosition;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.SurroundMode;
+import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.TouchSensor;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Request;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Message;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.MessageType;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.AbstractSonyProtocolImpl;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.SonyProtocolImplV1;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
-import nodomain.freeyourgadget.gadgetbridge.util.GB;
-public abstract class SonyHeadphonesProtocol extends GBDeviceProtocol {
+public class SonyHeadphonesProtocol extends GBDeviceProtocol {
private static final Logger LOG = LoggerFactory.getLogger(SonyHeadphonesProtocol.class);
- /**
- * Packet format:
- *
- * - PACKET_HEADER
- * - Command type? - almost always 0x0c or 0x0e?
- * - Sequence Number - needs to be updated with the one sent in the ACK responses
- * - 4-byte big endian int with number of bytes that will follow
- * - N bytes of data
- * - Checksum (1-byte sum, excluding header)
- * - PACKET_TRAILER
- *
- * Data between PACKET_HEADER and PACKET_TRAILER is escaped with PACKET_ESCAPE, and the
- * following byte masked with PACKET_ESCAPE_MASK.
- */
-
- public static final byte PACKET_HEADER = 0x3e;
- public static final byte PACKET_TRAILER = 0x3c;
- public static final byte PACKET_ESCAPE = 0x3d;
- public static final byte PACKET_ESCAPE_MASK = (byte) 0b11101111;
-
- private static final byte MSG_TYPE_ACK = 0x01;
-
- private static final byte CMD_SOUND_SURROUND = 0x01;
- private static final byte CMD_SOUND_POSITION = 0x02;
-
private byte sequenceNumber = 0;
+ // Request queue, sent every ACK, as we can't send them all at once
+ // Initially, it should contain all the init requests
+ private final Queue requestQueue = new LinkedList<>();
+ private int pendingAcks = 0;
+
+ private AbstractSonyProtocolImpl protocolImpl = null;
+
public SonyHeadphonesProtocol(GBDevice device) {
super(device);
}
@Override
public GBDeviceEvent[] decodeResponse(byte[] res) {
- byte[] message = unescape(res);
- String hexdump = GB.hexdump(message, 0, message.length);
-
- LOG.debug("Received {}", hexdump);
-
- byte messageChecksum = message[message.length - 1];
- byte expectedChecksum = calcChecksum(message, true);
-
- if (messageChecksum != expectedChecksum) {
- LOG.error("Invalid checksum for {}", hexdump);
+ final Message message = Message.fromBytes(res);
+ if (message == null) {
return null;
}
- int payloadLength = ((message[2] << 24) & 0xFF000000) | ((message[3] << 16) & 0xFF0000) | ((message[4] << 8) & 0xFF00) | (message[5] & 0xFF);
- if (payloadLength != message.length - 7) {
- LOG.error("Unexpected payload length {}, expected {}", message.length - 7, payloadLength);
+ LOG.info("Received {}", message);
+
+ final MessageType messageType = message.getType();
+
+ if (messageType == MessageType.ACK) {
+ if (sequenceNumber == message.getSequenceNumber()) {
+ LOG.warn("Unexpected ACK sequence number {}", message.getSequenceNumber());
+ return null;
+ }
+
+ sequenceNumber = message.getSequenceNumber();
+
+ return new GBDeviceEvent[]{handleAck()};
+ }
+
+ if (message.getPayload().length == 0) {
+ LOG.warn("Empty message: {}", message);
return null;
}
- if (message[0] == MSG_TYPE_ACK) {
- LOG.info("Received ACK: {}", hexdump);
- sequenceNumber = message[1];
- return new GBDeviceEvent[]{new GBDeviceEventSendBytes(encodeAck())};
+ final List
Anzahl der TastendrückeStreichen nach links/rechts im Diagrammbetrieb aktivieren
- Wenn aktiviert, können Zifferblätter Wetter, Akkuinfos, usw. anzeigen
+ Wenn aktiviert, kann die Uhr Wetter, Akkuinfos, usw. anzeigenGanztägige Messung der Herzfrequenzeinmal pro Minutealle 5 Minuten
@@ -520,10 +520,10 @@
Speicherort für Export auswählenAllgemeinStatus
- Aktivität
+ TrainingsverlaufWetterAlarm
- Timer
+ CountdownKompassEinstellungenAlipay
@@ -764,8 +764,8 @@
Status und WeckerWecker einstellen nach:
- %d Std
- %d Std
+ %d Stunde
+ %d StundenMakibes HR3-EinstellungenMakibes HR3
@@ -866,7 +866,7 @@
Automatischer AbrufRaw Activity Dateien speichernTraining
- Herzfrequenz
+ PulsWatch X PlusWatch XKalibrierung
@@ -886,7 +886,7 @@
Uhr-EnergiesparmodusEreigniserinnerungPAI
- Erzwinge die automatische Zeitsynchronisation beim erneuten Verbinden. Analoge Zeiger können die falsche Zeit anzeigen!
+ Erzwinge automatische Zeitsynchronisation beim erneuten Verbinden. Analoge Uhrzeiger können dabei die falsche Uhrzeit anzeigen!Kopiere Aktion vom Uhr-KnopfSchüttelgeste Anruf ignorieren/zurückzuweisenAus - ignorieren, An - zurückweisen
@@ -926,15 +926,15 @@
Über GadgetbridgeÜberWird für den LineageOS Wetterdienst genutzt, andere Android-Versionen müssen eine Anwendung wie Weather notification nutzen. Mehr Informationen gibt es im Gadgetbride-Wiki.
- Weltzeit
+ WeltzeituhrACHTUNG: Fehler beim Prüfen der Information zur Version! Du solltest nicht fortfahren! Versionsname \"%s\" gefundenAlle Berechtigungen sind notwendig und es kann zu Problemen führen, wenn sie nicht genehmigt werdenStress
- Periode
+ Zyklus-TrackingStart des Hintergrunddienstes fehlgeschlagen wegen einem Fehler. Fehlermeldung:Hintergrunddienst konnte nicht gestartet werden, wegen…Start des Hintergrunddienstes fehlgeschlagen
- Atmung
+ AtemübungenMi Band 5Du bist dabei, die Firmware %s auf dein Mi Band 5 zu installieren.
\n
@@ -996,12 +996,12 @@
Beim EinschlafenYogaSchwimmen (Freiwasser)
- Schläge
+ ZügekcalSeilspringenCrosstrainer
- Indoor Cycling
- str/s
+ Spinning
+ Züge/sSchwimmstilsekmin/km
@@ -1031,7 +1031,7 @@
Höhebpmsek/km
- str
+ ZügeFlachDurchschnittliche SchlägeDurchschnittliche Schlag Distanz
@@ -1079,8 +1079,8 @@
Um diesen Screenshot zu teilen, installiere eine App, die Bilddateien verarbeiten kann.Minimale Aktivitätsdauer (Minuten)Pausenlänge zum Trennen von Aktivitäten (Minuten)
- Minimale Schritte pro Minute zur Erkennung von Aktivität
- Minimale Schritte pro Minute zur Lauferkennung
+ Minimale Schritte pro Minute zur Erkennung einer Aktivität (Gehen)
+ Minimale Schritte pro Minute zur Erkennung einer LaufaktivitätSprache der BenutzeroberflächeDas Band wird vibrieren, wenn dein Telefon die Verbindung zum Band unterbrichtAnti-Verlust
@@ -1125,9 +1125,9 @@
StoppuhrNicht störenAlexa
- Foto machen
- Telefon stumm schalten
- Telefon finden
+ Kamera-Fernauslösung
+ Telefon stummschalten
+ Telefon suchenAmazfit GTR 2Amazfit GTS 2Bewegungsintensität
@@ -1322,8 +1322,8 @@
Zweite ZeitzoneKalorienAkku
- Handbewegung ohne Handgelenk deaktivieren
- Bildschirmaktualisierungen ohne Handgelenk deaktivieren
+ Bewegungserkennung deaktivieren wenn Uhr nicht getragen
+ Bildschirmaktualisierungen deaktivieren wenn Uhr nicht getragenAktivieren, wenn das Gerät nach einem Firmware-Upgrade keine Verbindung mehr herstelltNeues Auth-ProtokollTaschenlampe
@@ -1482,4 +1482,13 @@
App muss zum Konfigurieren ausgewählt seinDruckentlastung mit UmgebungsgeräuschenVerhindert Druckgefühl in den Ohren, wenn Active Noise Cancelling nicht verwendet wird
+ Im Ruhemodes Anzeige beim Anheben aktivieren
+ Aktualisierungszeit in Minuten:
+ Aktivitätsinfo in der Geräteübersicht
+ Auswahl der Aktivitätsinfos in der Geräteübersicht
+ Aktivitätsinfos in der Geräteübersicht anzeigen
+ Zeige Schritte, Distanz oder Schlaf in der Geräteübersicht
+ Strecke basiert auf Schrittzahl und Schrittlänge (siehe Einstellungen - Über Dich)
+ Angeregt
+ Batteriefach
\ No newline at end of file
diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml
index 9d00acca0..7a2f0f9ce 100644
--- a/app/src/main/res/values-en-rGB/strings.xml
+++ b/app/src/main/res/values-en-rGB/strings.xml
@@ -335,10 +335,10 @@
AlipaySettingsCompass
- Timer
+ CountdownAlarmWeather
- Activity
+ Workout HistoryStatusReset fetch dateShare
@@ -950,7 +950,7 @@
Data transferLow batteryLefun
- Period
+ Cycle TrackingStressDNDStopwatch
@@ -1329,7 +1329,7 @@
Amazfit XZepp EFind Phone
- Take a photo
+ Camera RemoteAlexaMiddle Button shortUpper Button long
@@ -1479,4 +1479,15 @@
Every monthThe device has no free slots for reminders (total slots: %1$s)Number of calendar events that will be synchronized
+ Activate display upon lift during Do Not Disturb
+ Max Heartrate
+ steps/min
+ Minimum
+ Average Cadence
+ Average
+ Max Cadence
+ Min Cadence
+ Min Heartrate
+ Max Stride
+ Min Stride
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 2cf7464eb..d55914263 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -513,7 +513,7 @@
NotificacionesTiempoAlarma
- Temporizador
+ Cuenta atrásBrújulaAjustesMúsica
@@ -605,7 +605,7 @@
Roidmi 3Casio GB-6900Estado
- Actividad
+ Historial del entrenamientoAlipayEstablezca la hora que su dispositivo le está mostrando en este momento.Tenga en cuenta que Gadgetbridge registra archivos que pueden contener mucha información personal, incluidos, entre otros, datos de salud, identificadores únicos (como la dirección MAC de un dispositivo), preferencias de música, etc. Considere editar el archivo y eliminar esta información antes de enviar el archivo a un informe público.
@@ -1118,7 +1118,7 @@
CronómetroNo molestarAlexa
- Tomar una foto
+ Control remoto de la cámaraSilenciar teléfonoEncontrar teléfonoReloj mundial
@@ -1128,7 +1128,7 @@
SpO2Ritmo cardíacoPAI
- Periodo
+ Seguimiento del cicloRespiraciónLefunLemfo SG2
@@ -1486,4 +1486,15 @@
Número de eventos del calendario que se sincronizaránActivar la confirmación del emparejamiento en el dispositivoLas confirmaciones de emparejamiento en el dispositivo pueden resultar molestas. Desactivarlas puede hacer que pierda funcionalidad.
+ Activar la pantalla al levantarse durante la función \"No molestar\"
+ Media
+ Mínimo
+ Ritmo cardíaco máximo
+ Ritmo cardíaco mínimo
+ Zancada mínima
+ Cadencia media
+ Cadencia mínima
+ pasos/min
+ Zancada máxima
+ Cadencia máxima
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index cdd130468..86adbbd62 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -516,10 +516,10 @@ Temps de sommeil préféré en heuresPartagerRéinitialiser la date de récupérationÉtat
- Activité
+ Historique d\'activitéMétéoAlarme
- Minuteur
+ DécompteBoussoleRéglagesAlipay
@@ -1121,7 +1121,7 @@ Temps de sommeil préféré en heuresÉtapeNPDAlexa
- Prendre une photo
+ Appareil photo à distanceTéléphone muetTrouver mon téléphoneIntensité du mouvement
@@ -1486,4 +1486,14 @@ Temps de sommeil préféré en heuresNombre d\'évènements du calendrier qui seront synchronisésDétails du rappelActiver l\'écran lors d\'un retournement en mode Ne Pas Déranger
+ Rythme cardiaque max
+ Distance de pas max
+ Distance de pas min
+ Cadence min
+ pas/min
+ Moyenne
+ Cadence moyenne
+ Minimum
+ Rythme cardiaque min
+ Cadence max
\ No newline at end of file
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index b63a5fb90..299f7ffff 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -509,10 +509,10 @@
שיתוףאיפוס מועד הקבלהמצב
- פעילות
+ היסטוריית אימוניםמזג אווירשעון מעורר
- קוצב זמן
+ ספירה לאחורמצפןהגדרותAlipay
@@ -931,7 +931,7 @@
\n
\nהמשך מעבר לנקודה זו הוא על אחריותך!לחץ
- משך
+ מעקב מחזוריותנשימהMi Band 5הפעלת אפשרות זו תתעלם ממכשירים שכבר אוגדו/צומדו טרם הסריקה
@@ -1117,7 +1117,7 @@
שעון עצרלא להפריעAlexa
- צילום תמונה
+ שליטה במצלמההשתקת הטלפוןאיתור הטלפוןחוזק תנועה
@@ -1481,4 +1481,15 @@
כל שנהאין חלונות פנוייםמספר אירועי לוח השנה שיסונכרנו
+ הפעלת התצוגה עקב הנפה במצב לא להפריע
+ ממוצע
+ קצב מזערי
+ מזערי
+ דופק מרבי
+ דופק מזערי
+ קצב ממוצע
+ קצב מרבי
+ צעדים לדקה
+ צעד מרבי
+ צעד מזערי
\ No newline at end of file
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 3bfce0826..bf0d8d275 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -530,10 +530,10 @@
Alipay (snelkoppeling)Weer (snelkoppeling)Status
- Activiteit
+ TrainingsgeschiedenisWeerAlarm
- Timer
+ AftellenKompasInstellingenAlipay
@@ -925,7 +925,7 @@
LET OP: Fout bij het controleren van versie-informatie! Je moet niet doorgaan! Zag versienaam \"%s\"Al deze toestemmingen zijn vereist en er kan instabiliteit ontstaan als ze niet worden verleendSpanning
- Cycli
+ Cyclus volgenAdemhalingMi Band 5U staat op het punt om de %s-firmware op je Mi Band 5 te installeren.
@@ -1031,7 +1031,7 @@
StopwatchNiet storenAlexa
- Neem een foto
+ Camera-afstandsbedieningTelefoon dempenVind telefoonSpO2
@@ -1481,4 +1481,15 @@
Weet je zeker dat je de herinnering wilt verwijderen\?Geen vrije plekkenHerinneringen instellen
+ Activeer het display bij het optillen tijdens Niet Storen
+ Max hartslag
+ Max paslengte
+ Gemiddelde cadans
+ Min hartslag
+ Minimum
+ Gemiddeld
+ Min paslengte
+ Min cadans
+ stappen/min
+ Max cadans
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 2c6fca512..419b7a1cd 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -282,7 +282,7 @@
Ukryj powiadomienia z GadgetbridgeIkona na pasku stanu i powiadomienia będą wyświetlane na zablokowanym ekranieIkona na pasku stanu i powiadomienia będą ukrywane na zablokowanym ekranie
- Niechciane powiadomienia są wyłączone w tym trybie
+ Blokuj wszystkie powiadomienia, gdy tryb \"Nie przeszkadzać\" jest włączony w telefonieTransliteracjaWłącz tę opcję, jeśli twoje urządzenie nie obsługuje czcionki twojego językaPrywatność
@@ -576,10 +576,10 @@
Teclast H30XWatchStatus
- Aktywność
+ Historia treningówPogodaBudzik
- Minutnik
+ OdliczanieKompasUstawieniaAlipay
@@ -941,7 +941,7 @@
Lokalizacja musi być włączonaWszystkie te uprawnienia są wymagane, a ich brak może spowodować niestabilnośćDodatkowe wsparcie dla urządzeń
- Okres
+ Śledzenie cykluOddychaniePineTime (Firmware JF)Szczegóły aktywności sportowej
@@ -1123,7 +1123,7 @@
StoperNie przeszkadzaćAlexa
- Zrób zdjęcie
+ Zdalna kameraWycisz telefonZnajdź telefonDystans
@@ -1401,4 +1401,15 @@
3 godzinySony WH-1000XM35 minut
+ Data
+ Czas
+ Wiadomość
+ Mowa
+ Podbicie basu
+ Klub
+ Wokal
+ Korektor dźwięku
+ Strefa czasowa:
+ Wyłączony
+ Korektor dźwięku
\ No newline at end of file
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index e4a7dc928..eada6eda6 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -372,7 +372,7 @@
Canlı etkinlikErkekSüre
- Etkinlik
+ Egzersiz GeçmişiAlarmAlipayPusula
@@ -384,7 +384,7 @@
Alipay (Kısayol)Hava Durumu (Kısayol)Durum
- Zamanlama
+ Geri SayımHava DurumuMAC adresi verilmedi, eşleştirilemiyor.Otomatik (uyku algılama)
@@ -948,7 +948,7 @@
Bir istisna nedeniyle arka plan hizmetini başlatma başarısız oldu. Hata:Arka plan hizmeti başlatılamadıStres
- Döngü
+ Döngü İzlemeNefes AlmaMi Band 5Mi Band 5 aygıtınıza %s ürün yazılımını kurmak üzeresiniz.
@@ -1139,9 +1139,9 @@
%1$s aransın mı\?Amazfit GTR 2Kronometre
- Rahatsız etmeyin
+ Rahatsız EtmeAlexa
- Fotoğraf çek
+ Kamera KumandasıTelefonun Sesini KapatTelefonu BulHareket yoğunluğu
@@ -1508,4 +1508,14 @@
%1$s, her yılBir defaHatırlatıcıyı silmek istediğinizden emin misiniz\?
+ Rahatsız Etme sırasında kaldırıldığında ekranı etkinleştir
+ En Yüksek Kalp Ritmi
+ Ortalama
+ Asgari
+ En Düşük Kalp Ritmi
+ En Yüksek Tempo
+ En Uzun Adım
+ En Kısa Adım
+ Ortalama Tempo
+ En Düşük Tempo
\ No newline at end of file
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 2b11eefa5..97e68a713 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -435,10 +435,10 @@
Вибрати теку експортуСтанСповіщення
- Активність
+ Історія тренуваньПогодаБудильник
- Таймер
+ ВідлікКомпасНалаштуванняМузика
@@ -990,7 +990,7 @@
Звичайний крокШвидки темпНайповільніший темп
- Максимум
+ МаксимальнаКалоріїАктивноКроки
@@ -1028,7 +1028,7 @@
Останнє сповіщенняСвітовий часСтрес
- Період
+ Відстеження циклуДиханняPineTime (Прошивка JF)TLW64
@@ -1115,7 +1115,7 @@
СекундомерТихий режимAlexa
- Зробити фото
+ Віддалене керування камероюВимкнути звук телефонуЗнайти телефонSpO2
@@ -1488,4 +1488,15 @@
Видалити нагадуванняНемає вільних комірокНа пристрої немає вільних комірок для нагадувань (загальна кількість комірок: %1$s)
+ Вмикати дисплей під час підйому у режимі «Не турбувати»
+ Середня
+ Мінімальна
+ Максимальний пульс
+ кроків/хв
+ Середній темп
+ Максимальний темп
+ Мінімальний пульс
+ Максимальний крок
+ Мінімальний крок
+ Мінімальний темп
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 77e033568..18402638b 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -586,10 +586,10 @@
天气(快捷方式)状态通知
- 活动
+ 锻炼历史天气闹钟
- 计时器
+ 倒计时指南针设置支付宝
@@ -928,7 +928,7 @@
启动后台服务失败注意:检查版本信息时发生错误!您不应该继续下去,已知版本名“%s”压力
- 周期
+ 周期跟踪呼吸小米手环5您即将在您的 小米手环5 上安装 %s 固件。
@@ -1122,7 +1122,7 @@
秒表勿扰Alexa
- 拍照
+ 相机遥控静音手机查找手机运动强度
@@ -1488,4 +1488,14 @@
没有可用空位该设备已经没有可用于提醒的可用的空位(总计空位:%1$s)在请勿打扰期间在抬起时激活显示
+ 平均
+ 最小
+ 最大步幅
+ 平均节奏
+ 最大节奏
+ 最小节奏
+ 最大心率
+ 最小心率
+ 最小步幅
+ 步数/分钟
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c34f97f57..54574ac5c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -936,12 +936,12 @@
StatusNotifications
- Activity
+ Workout HistoryWeatherBreathing
- Period
+ Cycle TrackingAlarm
- Timer
+ CountdownCompassSettingsAlipay
@@ -959,7 +959,7 @@
World ClockFind PhoneMute Phone
- Take a photo
+ Camera RemoteAlexaDNDStopwatch
@@ -1317,7 +1317,7 @@
Power savingDisable display updates while off wristDisable hands movement while off wrist
-Sleep times
+ Sleep timesDefine sleep hoursSpecifies times when sleep is registeredEnable vibrations
@@ -1401,7 +1401,7 @@
ManualCustom 1Custom 2
- Manual Preset
+ BandsCustom Preset 1Custom Preset 2400
@@ -1410,7 +1410,7 @@
6.3k16kClear Bass
- DSEE HX
+ Audio UpsamplingTouch sensor controlNotifications & Voice GuideAutomatic Power Off
@@ -1427,5 +1427,4 @@
Show circle on timeout:Enable on-device pairing confirmationOn-device pairing confirmations can get annoying. Disabling them might lose you functionality.
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/devicesettings_automatic_power_off.xml b/app/src/main/res/xml/devicesettings_automatic_power_off.xml
new file mode 100644
index 000000000..6b11d5424
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_automatic_power_off.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_header_other.xml b/app/src/main/res/xml/devicesettings_header_other.xml
new file mode 100644
index 000000000..684ea1362
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_header_other.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_header_system.xml b/app/src/main/res/xml/devicesettings_header_system.xml
new file mode 100644
index 000000000..d5408f624
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_header_system.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_ambient_sound_control.xml b/app/src/main/res/xml/devicesettings_sony_headphones_ambient_sound_control.xml
index e1fa7b422..0945b5df7 100644
--- a/app/src/main/res/xml/devicesettings_sony_headphones_ambient_sound_control.xml
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_ambient_sound_control.xml
@@ -13,6 +13,7 @@
android:summary="%s"
android:title="@string/sony_ambient_sound" />
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_equalizer.xml b/app/src/main/res/xml/devicesettings_sony_headphones_equalizer.xml
index 1cffd036c..abc973b2f 100644
--- a/app/src/main/res/xml/devicesettings_sony_headphones_equalizer.xml
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_equalizer.xml
@@ -1,7 +1,10 @@
-
-
+
+
+
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_notifications_voice_guide.xml b/app/src/main/res/xml/devicesettings_sony_headphones_notifications_voice_guide.xml
new file mode 100644
index 000000000..1eb8d7ab9
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_notifications_voice_guide.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_other.xml b/app/src/main/res/xml/devicesettings_sony_headphones_other.xml
deleted file mode 100644
index 7102a0562..000000000
--- a/app/src/main/res/xml/devicesettings_sony_headphones_other.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_sound_position.xml b/app/src/main/res/xml/devicesettings_sony_headphones_sound_position.xml
new file mode 100644
index 000000000..5e3bb41dc
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_sound_position.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_surround_mode.xml b/app/src/main/res/xml/devicesettings_sony_headphones_surround_mode.xml
new file mode 100644
index 000000000..0b8244cf5
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_surround_mode.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_sony_headphones_touch_sensor_single.xml b/app/src/main/res/xml/devicesettings_sony_headphones_touch_sensor_single.xml
new file mode 100644
index 000000000..5f141262e
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_sony_headphones_touch_sensor_single.xml
@@ -0,0 +1,8 @@
+
+
+
+