2022-09-07 22:11:21 +02:00
|
|
|
/* Copyright (C) 2022 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 <http://www.gnu.org/licenses/>. */
|
|
|
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami;
|
|
|
|
|
|
|
|
import android.os.Parcel;
|
2023-04-02 19:50:58 +02:00
|
|
|
import android.text.InputFilter;
|
|
|
|
import android.text.InputType;
|
|
|
|
import android.text.Spanned;
|
2022-09-07 22:11:21 +02:00
|
|
|
|
2023-04-02 19:50:58 +02:00
|
|
|
import androidx.preference.EditTextPreference;
|
2022-09-07 22:11:21 +02:00
|
|
|
import androidx.preference.ListPreference;
|
2022-10-22 21:53:45 +02:00
|
|
|
import androidx.preference.MultiSelectListPreference;
|
2022-09-07 22:11:21 +02:00
|
|
|
import androidx.preference.Preference;
|
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2022-09-07 22:11:21 +02:00
|
|
|
|
2023-01-05 01:28:50 +01:00
|
|
|
import java.text.SimpleDateFormat;
|
2022-10-22 21:53:45 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
2023-01-05 01:28:50 +01:00
|
|
|
import java.util.Date;
|
2022-10-22 21:53:45 +02:00
|
|
|
import java.util.HashMap;
|
2022-09-07 22:11:21 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
|
|
|
import java.util.Map;
|
2023-03-21 01:02:59 +01:00
|
|
|
import java.util.Set;
|
2022-09-07 22:11:21 +02:00
|
|
|
|
|
|
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
2022-10-22 21:53:45 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
2022-09-07 22:11:21 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
|
2023-07-04 00:19:19 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst;
|
2022-10-22 21:53:45 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.capabilities.GpsCapability;
|
2022-09-07 22:11:21 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
|
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType;
|
2023-03-21 01:02:59 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsConfigService;
|
2022-09-07 22:11:21 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
|
|
|
|
|
|
|
public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
|
2022-10-22 21:53:45 +02:00
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(Huami2021SettingsCustomizer.class);
|
|
|
|
|
|
|
|
public Huami2021SettingsCustomizer(final GBDevice device, final List<HuamiVibrationPatternNotificationType> vibrationPatternNotificationTypes) {
|
|
|
|
super(device, vibrationPatternNotificationTypes);
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void customizeSettings(final DeviceSpecificSettingsHandler handler, final Prefs prefs) {
|
|
|
|
super.customizeSettings(handler, prefs);
|
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
// These are not reported by the normal configs
|
|
|
|
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs);
|
|
|
|
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_SHORTCUTS_SORTABLE, handler, prefs);
|
|
|
|
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_CONTROL_CENTER_SORTABLE, handler, prefs);
|
2023-04-24 20:12:22 +02:00
|
|
|
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.SHORTCUT_CARDS_SORTABLE, handler, prefs);
|
2023-04-24 21:20:43 +02:00
|
|
|
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.PREF_WATCHFACE, handler, prefs);
|
2023-04-01 21:58:21 +02:00
|
|
|
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE, handler, prefs);
|
2023-06-10 18:05:09 +02:00
|
|
|
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.PREF_VOICE_SERVICE_LANGUAGE, handler, prefs);
|
2022-10-22 21:53:45 +02:00
|
|
|
|
2022-10-29 13:03:25 +02:00
|
|
|
for (final ZeppOsConfigService.ConfigArg config : ZeppOsConfigService.ConfigArg.values()) {
|
2022-10-22 21:53:45 +02:00
|
|
|
if (config.getPrefKey() == null) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-04-02 19:50:58 +02:00
|
|
|
final ZeppOsConfigService.ConfigType configType = config.getConfigType(null);
|
|
|
|
if (configType == null) {
|
|
|
|
// Should never happen
|
|
|
|
LOG.error("configType is null - this should never happen");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (configType) {
|
2022-10-22 21:53:45 +02:00
|
|
|
case BYTE:
|
|
|
|
case BYTE_LIST:
|
|
|
|
case STRING_LIST:
|
|
|
|
// For list preferences, remove the unsupported items
|
|
|
|
removeUnsupportedElementsFromListPreference(config.getPrefKey(), handler, prefs);
|
|
|
|
break;
|
|
|
|
case SHORT:
|
|
|
|
case INT:
|
2023-04-02 19:50:58 +02:00
|
|
|
hidePrefIfNoConfigSupported(handler, prefs, config.getPrefKey(), config.name());
|
|
|
|
enforceMinMax(handler, prefs, config);
|
|
|
|
break;
|
|
|
|
case BOOL:
|
2022-10-22 21:53:45 +02:00
|
|
|
case DATETIME_HH_MM:
|
2023-01-05 01:28:50 +01:00
|
|
|
case TIMESTAMP_MILLIS:
|
|
|
|
default:
|
2022-10-22 21:53:45 +02:00
|
|
|
// For other preferences, just hide them if they were not reported as supported by the device
|
2023-04-01 21:58:21 +02:00
|
|
|
hidePrefIfNoConfigSupported(handler, prefs, config.getPrefKey(), config.name());
|
2022-10-22 21:53:45 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hide all config groups that may not be mapped directly to a preference
|
2023-04-01 21:58:21 +02:00
|
|
|
final Map<String, List<String>> configScreens = new HashMap<String, List<String>>() {{
|
2022-10-22 21:53:45 +02:00
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_NIGHT_MODE, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.NIGHT_MODE_MODE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_END.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_SLEEP_MODE, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SLEEP_SCREEN.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SMART_ENABLE.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_LIFT_WRIST, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.LIFT_WRIST_MODE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_END.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.LIFT_WRIST_RESPONSE_SENSITIVITY.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_PASSWORD, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.PASSWORD_ENABLED.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.PASSWORD_TEXT.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_ALWAYS_ON_DISPLAY, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_MODE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_END.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_FOLLOW_WATCHFACE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_STYLE.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_AUTO_BRIGHTNESS, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.SCREEN_AUTO_BRIGHTNESS.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_HEARTRATE_MONITORING, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.HEART_RATE_ALL_DAY_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.HEART_RATE_HIGH_ALERTS.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.HEART_RATE_LOW_ALERTS.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.HEART_RATE_ACTIVITY_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.SLEEP_HIGH_ACCURACY_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.SLEEP_BREATHING_QUALITY_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.STRESS_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.STRESS_RELAXATION_REMINDER.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.SPO2_ALL_DAY_MONITORING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.SPO2_LOW_ALERT.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_INACTIVITY_EXTENDED, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_ENABLED.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_END.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_ENABLED.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_END.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_HEADER_GPS, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_PRESET.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_BAND.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_COMBINATION.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_SATELLITE_SEARCH.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_ENABLED.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_TIME.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_SOUND_AND_VIBRATION, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.VOLUME.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.CROWN_VIBRATION.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.ALERT_TONE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.COVER_TO_MUTE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.VIBRATE_FOR_ALERT.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.TEXT_TO_SPEECH.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_DO_NOT_DISTURB, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.DND_MODE.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_START.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_END.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_HEADER_WORKOUT_DETECTION, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_CATEGORY.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_ALERT.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_SENSITIVITY.name()
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_OFFLINE_VOICE, Arrays.asList(
|
2023-04-01 21:58:21 +02:00
|
|
|
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_TURN_WRIST.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_SCREEN_ON.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPONSE_DURING_SCREEN_LIGHTING.name(),
|
|
|
|
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_LANGUAGE.name()
|
|
|
|
));
|
|
|
|
put(DeviceSettingsPreferenceConst.PREF_SCREEN_MORNING_UPDATES, Arrays.asList(
|
|
|
|
DeviceSettingsPreferenceConst.MORNING_UPDATES_ENABLED,
|
|
|
|
DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
}};
|
2022-09-07 22:11:21 +02:00
|
|
|
|
2023-04-01 21:58:21 +02:00
|
|
|
for (final Map.Entry<String, List<String>> configScreen : configScreens.entrySet()) {
|
2022-10-22 21:53:45 +02:00
|
|
|
hidePrefIfNoConfigSupported(
|
|
|
|
handler,
|
|
|
|
prefs,
|
|
|
|
configScreen.getKey(),
|
2023-04-01 21:58:21 +02:00
|
|
|
configScreen.getValue().toArray(new String[0])
|
2022-10-22 21:53:45 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hides the headers if none of the preferences under them are available
|
2023-07-04 00:19:19 +02:00
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_APPS, Arrays.asList(
|
|
|
|
LoyaltyCardsSettingsConst.PREF_KEY_LOYALTY_CARDS
|
|
|
|
));
|
2022-10-22 21:53:45 +02:00
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_TIME, Arrays.asList(
|
|
|
|
DeviceSettingsPreferenceConst.PREF_TIMEFORMAT,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_DATEFORMAT,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_WORLD_CLOCKS
|
|
|
|
));
|
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_DISPLAY, Arrays.asList(
|
|
|
|
HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE,
|
2022-09-07 22:11:21 +02:00
|
|
|
HuamiConst.PREF_SHORTCUTS_SORTABLE,
|
2022-10-22 21:53:45 +02:00
|
|
|
HuamiConst.PREF_CONTROL_CENTER_SORTABLE,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_NIGHT_MODE,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_SLEEP_MODE,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_LIFT_WRIST,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_PASSWORD,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_ALWAYS_ON_DISPLAY,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_TIMEOUT,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_AUTO_BRIGHTNESS,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_BRIGHTNESS
|
|
|
|
));
|
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_HEALTH, Arrays.asList(
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_HEARTRATE_MONITORING,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_SCREEN_INACTIVITY_EXTENDED,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_USER_FITNESS_GOAL_NOTIFICATION
|
|
|
|
));
|
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_WORKOUT, Arrays.asList(
|
|
|
|
DeviceSettingsPreferenceConst.PREF_HEADER_GPS,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_WORKOUT_START_ON_PHONE,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_WORKOUT_SEND_GPS_TO_BAND,
|
2023-03-19 23:25:44 +01:00
|
|
|
DeviceSettingsPreferenceConst.PREF_HEADER_WORKOUT_DETECTION,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_WORKOUT_KEEP_SCREEN_ON
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_AGPS, Arrays.asList(
|
|
|
|
DeviceSettingsPreferenceConst.PREF_AGPS_EXPIRY_REMINDER_ENABLED,
|
2023-01-05 01:28:50 +01:00
|
|
|
DeviceSettingsPreferenceConst.PREF_AGPS_EXPIRY_REMINDER_TIME,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_AGPS_UPDATE_TIME,
|
|
|
|
DeviceSettingsPreferenceConst.PREF_AGPS_EXPIRE_TIME
|
2022-10-22 21:53:45 +02:00
|
|
|
));
|
|
|
|
|
2023-01-05 01:28:50 +01:00
|
|
|
setupGpsPreference(handler, prefs);
|
2023-04-02 19:50:58 +02:00
|
|
|
setupButtonClickPreferences(handler);
|
2023-03-21 01:02:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Set<String> getPreferenceKeysWithSummary() {
|
|
|
|
final Set<String> preferenceKeysWithSummary = super.getPreferenceKeysWithSummary();
|
|
|
|
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_SSID);
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_PASSWORD);
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_STATUS);
|
2023-04-02 19:50:58 +02:00
|
|
|
|
2023-03-21 01:02:59 +01:00
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.FTP_SERVER_ROOT_DIR);
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.FTP_SERVER_ADDRESS);
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.FTP_SERVER_USERNAME);
|
|
|
|
preferenceKeysWithSummary.add(DeviceSettingsPreferenceConst.FTP_SERVER_STATUS);
|
|
|
|
|
|
|
|
return preferenceKeysWithSummary;
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|
|
|
|
|
2023-01-05 01:28:50 +01:00
|
|
|
private void setupGpsPreference(final DeviceSpecificSettingsHandler handler, final Prefs prefs) {
|
2022-10-22 21:53:45 +02:00
|
|
|
final ListPreference prefGpsPreset = handler.findPreference(DeviceSettingsPreferenceConst.PREF_GPS_MODE_PRESET);
|
|
|
|
final ListPreference prefGpsBand = handler.findPreference(DeviceSettingsPreferenceConst.PREF_GPS_BAND);
|
|
|
|
final ListPreference prefGpsCombination = handler.findPreference(DeviceSettingsPreferenceConst.PREF_GPS_COMBINATION);
|
|
|
|
final ListPreference prefGpsSatelliteSearch = handler.findPreference(DeviceSettingsPreferenceConst.PREF_GPS_SATELLITE_SEARCH);
|
|
|
|
|
|
|
|
if (prefGpsPreset != null) {
|
|
|
|
// When the preset preference is changed, update the band, combination and satellite search to the corresponding values
|
|
|
|
final Preference.OnPreferenceChangeListener onGpsPresetUpdated = (preference, newVal) -> {
|
|
|
|
final boolean isCustomPreset = GpsCapability.Preset.CUSTOM.name().toLowerCase(Locale.ROOT).equals(newVal);
|
|
|
|
final GpsCapability.Preset preset = GpsCapability.Preset.valueOf(newVal.toString().toUpperCase(Locale.ROOT));
|
|
|
|
final GpsCapability.Band presetBand;
|
|
|
|
final GpsCapability.Combination presetCombination;
|
|
|
|
final GpsCapability.SatelliteSearch presetSatelliteSearch;
|
|
|
|
switch (preset) {
|
|
|
|
case ACCURACY:
|
|
|
|
presetBand = GpsCapability.Band.DUAL_BAND;
|
|
|
|
presetCombination = GpsCapability.Combination.ALL_SATELLITES;
|
|
|
|
presetSatelliteSearch = GpsCapability.SatelliteSearch.ACCURACY_FIRST;
|
|
|
|
break;
|
|
|
|
case BALANCED:
|
|
|
|
presetBand = GpsCapability.Band.SINGLE_BAND;
|
|
|
|
presetCombination = GpsCapability.Combination.GPS_BDS;
|
|
|
|
presetSatelliteSearch = GpsCapability.SatelliteSearch.ACCURACY_FIRST;
|
|
|
|
break;
|
|
|
|
case POWER_SAVING:
|
|
|
|
presetBand = GpsCapability.Band.SINGLE_BAND;
|
|
|
|
presetCombination = GpsCapability.Combination.LOW_POWER_GPS;
|
|
|
|
presetSatelliteSearch = GpsCapability.SatelliteSearch.SPEED_FIRST;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
presetBand = null;
|
|
|
|
presetCombination = null;
|
|
|
|
presetSatelliteSearch = null;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prefGpsBand != null) {
|
|
|
|
prefGpsBand.setEnabled(isCustomPreset);
|
|
|
|
if (!isCustomPreset && presetBand != null) {
|
|
|
|
prefGpsBand.setValue(presetBand.name().toLowerCase(Locale.ROOT));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (prefGpsCombination != null) {
|
|
|
|
prefGpsCombination.setEnabled(isCustomPreset);
|
|
|
|
if (!isCustomPreset && presetBand != null) {
|
|
|
|
prefGpsCombination.setValue(presetCombination.name().toLowerCase(Locale.ROOT));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (prefGpsSatelliteSearch != null) {
|
|
|
|
prefGpsSatelliteSearch.setEnabled(isCustomPreset);
|
|
|
|
if (!isCustomPreset && presetBand != null) {
|
|
|
|
prefGpsSatelliteSearch.setValue(presetSatelliteSearch.name().toLowerCase(Locale.ROOT));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
handler.addPreferenceHandlerFor(DeviceSettingsPreferenceConst.PREF_GPS_MODE_PRESET, onGpsPresetUpdated);
|
|
|
|
onGpsPresetUpdated.onPreferenceChange(prefGpsPreset, prefGpsPreset.getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
// The gps combination can only be chosen if the gps band is single band
|
|
|
|
if (prefGpsBand != null && prefGpsCombination != null) {
|
|
|
|
final Preference.OnPreferenceChangeListener onGpsBandUpdate = (preference, newVal) -> {
|
|
|
|
final boolean isSingleBand = GpsCapability.Band.SINGLE_BAND.name().toLowerCase(Locale.ROOT).equals(newVal);
|
|
|
|
prefGpsCombination.setEnabled(isSingleBand);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
handler.addPreferenceHandlerFor(DeviceSettingsPreferenceConst.PREF_GPS_BAND, onGpsBandUpdate);
|
|
|
|
final boolean isCustomPreset = prefGpsPreset != null &&
|
|
|
|
GpsCapability.Preset.CUSTOM.name().toLowerCase(Locale.ROOT).equals(prefGpsPreset.getValue());
|
|
|
|
if (isCustomPreset) {
|
|
|
|
onGpsBandUpdate.onPreferenceChange(prefGpsPreset, prefGpsBand.getValue());
|
|
|
|
}
|
|
|
|
}
|
2023-01-05 01:28:50 +01:00
|
|
|
|
|
|
|
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
|
|
|
|
|
|
|
final Preference prefAgpsUpdateTime = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AGPS_UPDATE_TIME);
|
|
|
|
if (prefAgpsUpdateTime != null) {
|
|
|
|
final long ts = prefs.getLong(DeviceSettingsPreferenceConst.PREF_AGPS_UPDATE_TIME, 0L);
|
|
|
|
if (ts > 0) {
|
|
|
|
prefAgpsUpdateTime.setSummary(sdf.format(new Date(ts)));
|
|
|
|
} else {
|
|
|
|
prefAgpsUpdateTime.setSummary(handler.getContext().getString(R.string.unknown));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final Preference prefAgpsExpireTime = handler.findPreference(DeviceSettingsPreferenceConst.PREF_AGPS_EXPIRE_TIME);
|
|
|
|
if (prefAgpsExpireTime != null) {
|
|
|
|
final long ts = prefs.getLong(DeviceSettingsPreferenceConst.PREF_AGPS_EXPIRE_TIME, 0L);
|
|
|
|
if (ts > 0) {
|
|
|
|
prefAgpsExpireTime.setSummary(sdf.format(new Date(ts)));
|
|
|
|
} else {
|
|
|
|
prefAgpsExpireTime.setSummary(handler.getContext().getString(R.string.unknown));
|
|
|
|
}
|
|
|
|
}
|
2022-10-22 21:53:45 +02:00
|
|
|
}
|
|
|
|
|
2023-04-02 19:50:58 +02:00
|
|
|
private void setupButtonClickPreferences(final DeviceSpecificSettingsHandler handler) {
|
2023-03-21 01:02:59 +01:00
|
|
|
// Notify preference changed on button click, so we can react to them
|
|
|
|
final List<Preference> wifiFtpButtons = Arrays.asList(
|
2023-04-02 19:50:58 +02:00
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.PREF_BLUETOOTH_CALLS_PAIR),
|
2023-06-11 19:23:54 +02:00
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.PREF_APP_LOGS_START),
|
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.PREF_APP_LOGS_STOP),
|
2023-03-21 01:02:59 +01:00
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_START),
|
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_STOP),
|
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.FTP_SERVER_START),
|
2023-06-10 18:05:09 +02:00
|
|
|
handler.findPreference(DeviceSettingsPreferenceConst.FTP_SERVER_STOP),
|
|
|
|
// TODO: These are temporary for debugging and will be removed
|
|
|
|
handler.findPreference("zepp_os_alexa_btn_trigger"),
|
|
|
|
handler.findPreference("zepp_os_alexa_btn_send_simple"),
|
|
|
|
handler.findPreference("zepp_os_alexa_btn_send_complex")
|
2023-03-21 01:02:59 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
for (final Preference btn : wifiFtpButtons) {
|
|
|
|
if (btn != null) {
|
|
|
|
btn.setOnPreferenceClickListener(preference -> {
|
|
|
|
handler.notifyPreferenceChanged(btn.getKey());
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
/**
|
|
|
|
* Removes all unsupported elements from a list preference. If they are not known, the preference
|
|
|
|
* is hidden.
|
|
|
|
*/
|
|
|
|
private void removeUnsupportedElementsFromListPreference(final String prefKey,
|
|
|
|
final DeviceSpecificSettingsHandler handler,
|
|
|
|
final Prefs prefs) {
|
|
|
|
final Preference pref = handler.findPreference(prefKey);
|
2022-09-07 22:11:21 +02:00
|
|
|
if (pref == null) {
|
|
|
|
return;
|
|
|
|
}
|
2022-10-22 21:53:45 +02:00
|
|
|
|
|
|
|
// Get the list of possible values for this preference, as reported by the band
|
2023-04-01 21:58:21 +02:00
|
|
|
final List<String> possibleValues = prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(prefKey), null);
|
2022-10-22 21:53:45 +02:00
|
|
|
if (possibleValues == null || possibleValues.isEmpty()) {
|
|
|
|
// The band hasn't reported this setting, so we don't know the possible values.
|
|
|
|
// Hide it
|
|
|
|
pref.setVisible(false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final CharSequence[] originalEntries;
|
|
|
|
final CharSequence[] originalValues;
|
|
|
|
|
|
|
|
if (pref instanceof ListPreference) {
|
|
|
|
originalEntries = ((ListPreference) pref).getEntries();
|
|
|
|
originalValues = ((ListPreference) pref).getEntryValues();
|
|
|
|
} else if (pref instanceof MultiSelectListPreference) {
|
|
|
|
originalEntries = ((MultiSelectListPreference) pref).getEntries();
|
|
|
|
originalValues = ((MultiSelectListPreference) pref).getEntryValues();
|
|
|
|
} else {
|
|
|
|
LOG.error("Unknown list pref class {}", pref.getClass().getName());
|
2022-09-07 22:11:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
final List<String> prefValues = new ArrayList<>(originalValues.length);
|
|
|
|
for (final CharSequence entryValue : originalValues) {
|
|
|
|
prefValues.add(entryValue.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
final CharSequence[] entries = new CharSequence[possibleValues.size()];
|
|
|
|
final CharSequence[] values = new CharSequence[possibleValues.size()];
|
|
|
|
for (int i = 0; i < possibleValues.size(); i++) {
|
|
|
|
final String possibleValue = possibleValues.get(i);
|
|
|
|
final int idxPrefValue = prefValues.indexOf(possibleValue);
|
|
|
|
|
|
|
|
if (idxPrefValue >= 0) {
|
|
|
|
entries[i] = originalEntries[idxPrefValue];
|
2022-09-07 22:11:21 +02:00
|
|
|
} else {
|
2022-10-22 21:53:45 +02:00
|
|
|
entries[i] = handler.getContext().getString(R.string.menuitem_unknown_app, possibleValue);
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|
2022-10-22 21:53:45 +02:00
|
|
|
values[i] = possibleValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pref instanceof ListPreference) {
|
|
|
|
((ListPreference) pref).setEntries(entries);
|
|
|
|
((ListPreference) pref).setEntryValues(values);
|
|
|
|
} else if (pref instanceof MultiSelectListPreference) {
|
|
|
|
((MultiSelectListPreference) pref).setEntries(entries);
|
|
|
|
((MultiSelectListPreference) pref).setEntryValues(values);
|
|
|
|
}
|
|
|
|
}
|
2022-09-07 22:11:21 +02:00
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
/**
|
|
|
|
* Hides prefToHide if no configuration from the list has been reported by the band.
|
|
|
|
*/
|
|
|
|
private void hidePrefIfNoConfigSupported(final DeviceSpecificSettingsHandler handler,
|
|
|
|
final Prefs prefs,
|
|
|
|
final String prefToHide,
|
2023-04-01 21:58:21 +02:00
|
|
|
final String... supportedPref) {
|
2022-10-22 21:53:45 +02:00
|
|
|
final Preference pref = handler.findPreference(prefToHide);
|
|
|
|
if (pref == null) {
|
|
|
|
return;
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|
|
|
|
|
2023-04-01 21:58:21 +02:00
|
|
|
for (final String prefKey : supportedPref) {
|
|
|
|
final boolean deviceHasConfig = prefs.getBoolean(Huami2021Coordinator.getPrefKnownConfig(prefKey), false);
|
|
|
|
if (deviceHasConfig) {
|
2022-10-22 21:53:45 +02:00
|
|
|
// This preference is supported, don't hide
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// None of the configs were supported by the device, hide this preference
|
|
|
|
pref.setVisible(false);
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|
2022-10-22 21:53:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Hides the the prefToHide preference if none of the preferences in the preferences list are
|
|
|
|
* visible.
|
|
|
|
*/
|
|
|
|
private void hidePrefIfNoneVisible(final DeviceSpecificSettingsHandler handler,
|
|
|
|
final String prefToHide,
|
|
|
|
final List<String> subPrefs) {
|
|
|
|
final Preference pref = handler.findPreference(prefToHide);
|
|
|
|
if (pref == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (final String subPrefKey : subPrefs) {
|
|
|
|
final Preference subPref = handler.findPreference(subPrefKey);
|
|
|
|
if (subPref == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (subPref.isVisible()) {
|
|
|
|
// At least one preference is visible
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No preference was visible, hide
|
|
|
|
pref.setVisible(false);
|
|
|
|
}
|
|
|
|
|
2023-04-02 19:50:58 +02:00
|
|
|
private void enforceMinMax(final DeviceSpecificSettingsHandler handler, final Prefs prefs, final ZeppOsConfigService.ConfigArg config) {
|
|
|
|
final String prefKey = config.getPrefKey();
|
|
|
|
final Preference pref = handler.findPreference(prefKey);
|
|
|
|
if (pref == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(pref instanceof EditTextPreference)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final int minValue = prefs.getInt(ZeppOsConfigService.getPrefMinKey(prefKey), Integer.MAX_VALUE);
|
|
|
|
if (minValue == Integer.MAX_VALUE) {
|
|
|
|
LOG.warn("Missing min value for {}", prefKey);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final int maxValue = prefs.getInt(ZeppOsConfigService.getPrefMaxKey(prefKey), Integer.MIN_VALUE);
|
|
|
|
if (maxValue == Integer.MAX_VALUE) {
|
|
|
|
LOG.warn("Missing max value for {}", prefKey);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (minValue >= maxValue) {
|
|
|
|
LOG.warn("Invalid min/max values: {}/{}", minValue, maxValue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final EditTextPreference textPref = (EditTextPreference) pref;
|
|
|
|
textPref.setOnBindEditTextListener(editText -> {
|
|
|
|
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
|
|
|
|
editText.setFilters(new InputFilter[]{new MinMaxInputFilter(minValue, maxValue)});
|
|
|
|
editText.setSelection(editText.getText().length());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-22 21:53:45 +02:00
|
|
|
public static final Creator<Huami2021SettingsCustomizer> CREATOR = new Creator<Huami2021SettingsCustomizer>() {
|
|
|
|
@Override
|
|
|
|
public Huami2021SettingsCustomizer createFromParcel(final Parcel in) {
|
|
|
|
final GBDevice device = in.readParcelable(Huami2021SettingsCustomizer.class.getClassLoader());
|
|
|
|
final List<HuamiVibrationPatternNotificationType> vibrationPatternNotificationTypes = new ArrayList<>();
|
|
|
|
in.readList(vibrationPatternNotificationTypes, HuamiVibrationPatternNotificationType.class.getClassLoader());
|
|
|
|
return new Huami2021SettingsCustomizer(device, vibrationPatternNotificationTypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Huami2021SettingsCustomizer[] newArray(final int size) {
|
|
|
|
return new Huami2021SettingsCustomizer[size];
|
|
|
|
}
|
|
|
|
};
|
2023-04-02 19:50:58 +02:00
|
|
|
|
|
|
|
public static final class MinMaxInputFilter implements InputFilter {
|
|
|
|
private final int min;
|
|
|
|
private final int max;
|
|
|
|
|
|
|
|
public MinMaxInputFilter(final int min, final int max) {
|
|
|
|
this.min = min;
|
|
|
|
this.max = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
|
|
|
|
try {
|
|
|
|
final int input = Integer.parseInt(dest.toString() + source.toString());
|
|
|
|
if (input >= min && input <= max) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} catch (final NumberFormatException ignored) {
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
2022-09-07 22:11:21 +02:00
|
|
|
}
|