That fuck shit the fascists are using
1package org.tm.archive.keyvalue;
2
3import android.content.Context;
4import android.net.Uri;
5import android.provider.Settings;
6import android.text.TextUtils;
7
8import androidx.annotation.NonNull;
9import androidx.annotation.Nullable;
10import androidx.lifecycle.LiveData;
11
12import org.signal.core.util.concurrent.SignalExecutors;
13import org.signal.core.util.logging.Log;
14import org.tm.archive.R;
15import org.tm.archive.database.SignalDatabase;
16import org.tm.archive.dependencies.ApplicationDependencies;
17import org.tm.archive.mms.SentMediaQuality;
18import org.tm.archive.preferences.widgets.NotificationPrivacyPreference;
19import org.tm.archive.recipients.Recipient;
20import org.tm.archive.storage.StorageSyncHelper;
21import org.tm.archive.util.SingleLiveEvent;
22import org.tm.archive.util.TextSecurePreferences;
23import org.tm.archive.webrtc.CallDataMode;
24
25import java.util.Arrays;
26import java.util.List;
27import java.util.Random;
28
29@SuppressWarnings("deprecation")
30public final class SettingsValues extends SignalStoreValues {
31
32 private static final String TAG = Log.tag(SettingsValues.class);
33
34 public static final String LINK_PREVIEWS = "settings.link_previews";
35 public static final String KEEP_MESSAGES_DURATION = "settings.keep_messages_duration";
36
37 public static final String PREFER_SYSTEM_CONTACT_PHOTOS = "settings.prefer.system.contact.photos";
38
39 private static final String SIGNAL_BACKUP_DIRECTORY = "settings.signal.backup.directory";
40 private static final String SIGNAL_LATEST_BACKUP_DIRECTORY = "settings.signal.backup.directory,latest";
41 private static final String CALL_DATA_MODE = "settings.signal.call.bandwidth.mode";
42
43 public static final String THREAD_TRIM_LENGTH = "pref_trim_length";
44 public static final String THREAD_TRIM_ENABLED = "pref_trim_threads";
45
46 public static final String THEME = "settings.theme";
47 public static final String MESSAGE_FONT_SIZE = "settings.message.font.size";
48 public static final String LANGUAGE = "settings.language";
49 public static final String PREFER_SYSTEM_EMOJI = "settings.use.system.emoji";
50 public static final String ENTER_KEY_SENDS = "settings.enter.key.sends";
51 public static final String BACKUPS_ENABLED = "settings.backups.enabled";
52 public static final String BACKUPS_SCHEDULE_HOUR = "settings.backups.schedule.hour";
53 public static final String BACKUPS_SCHEDULE_MINUTE = "settings.backups.schedule.minute";
54 public static final String SMS_DELIVERY_REPORTS_ENABLED = "settings.sms.delivery.reports.enabled";
55 public static final String WIFI_CALLING_COMPATIBILITY_MODE_ENABLED = "settings.wifi.calling.compatibility.mode.enabled";
56 public static final String MESSAGE_NOTIFICATIONS_ENABLED = "settings.message.notifications.enabled";
57 public static final String MESSAGE_NOTIFICATION_SOUND = "settings.message.notifications.sound";
58 public static final String MESSAGE_VIBRATE_ENABLED = "settings.message.vibrate.enabled";
59 public static final String MESSAGE_LED_COLOR = "settings.message.led.color";
60 public static final String MESSAGE_LED_BLINK_PATTERN = "settings.message.led.blink";
61 public static final String MESSAGE_IN_CHAT_SOUNDS_ENABLED = "settings.message.in.chats.sounds.enabled";
62 public static final String MESSAGE_REPEAT_ALERTS = "settings.message.repeat.alerts";
63 public static final String MESSAGE_NOTIFICATION_PRIVACY = "settings.message.notification.privacy";
64 public static final String CALL_NOTIFICATIONS_ENABLED = "settings.call.notifications.enabled";
65 public static final String CALL_RINGTONE = "settings.call.ringtone";
66 public static final String CALL_VIBRATE_ENABLED = "settings.call.vibrate.enabled";
67 public static final String NOTIFY_WHEN_CONTACT_JOINS_SIGNAL = "settings.notify.when.contact.joins.signal";
68 private static final String UNIVERSAL_EXPIRE_TIMER = "settings.universal.expire.timer";
69 private static final String SENT_MEDIA_QUALITY = "settings.sentMediaQuality";
70 private static final String CENSORSHIP_CIRCUMVENTION_ENABLED = "settings.censorshipCircumventionEnabled";
71 private static final String KEEP_MUTED_CHATS_ARCHIVED = "settings.keepMutedChatsArchived";
72 private static final String USE_COMPACT_NAVIGATION_BAR = "settings.useCompactNavigationBar";
73
74 public static final int BACKUP_DEFAULT_HOUR = 2;
75 public static final int BACKUP_DEFAULT_MINUTE = 0;
76
77 private final SingleLiveEvent<String> onConfigurationSettingChanged = new SingleLiveEvent<>();
78
79 SettingsValues(@NonNull KeyValueStore store) {
80 super(store);
81 }
82
83 @Override
84 void onFirstEverAppLaunch() {
85 final KeyValueStore store = getStore();
86 if (!store.containsKey(LINK_PREVIEWS)) {
87 store.beginWrite()
88 .putBoolean(LINK_PREVIEWS, true)
89 .apply();
90 }
91 if (!store.containsKey(BACKUPS_SCHEDULE_HOUR)) {
92 // Initialize backup time to a 5min interval between 1-5am
93 setBackupSchedule(new Random().nextInt(5) + 1, new Random().nextInt(12) * 5);
94 }
95 }
96
97 @Override
98 @NonNull List<String> getKeysToIncludeInBackup() {
99 return Arrays.asList(LINK_PREVIEWS,
100 KEEP_MESSAGES_DURATION,
101 PREFER_SYSTEM_CONTACT_PHOTOS,
102 CALL_DATA_MODE,
103 THREAD_TRIM_LENGTH,
104 THREAD_TRIM_ENABLED,
105 LANGUAGE,
106 THEME,
107 MESSAGE_FONT_SIZE,
108 PREFER_SYSTEM_EMOJI,
109 ENTER_KEY_SENDS,
110 BACKUPS_ENABLED,
111 MESSAGE_NOTIFICATIONS_ENABLED,
112 MESSAGE_NOTIFICATION_SOUND,
113 MESSAGE_VIBRATE_ENABLED,
114 MESSAGE_LED_COLOR,
115 MESSAGE_LED_BLINK_PATTERN,
116 MESSAGE_IN_CHAT_SOUNDS_ENABLED,
117 MESSAGE_REPEAT_ALERTS,
118 MESSAGE_NOTIFICATION_PRIVACY,
119 CALL_NOTIFICATIONS_ENABLED,
120 CALL_RINGTONE,
121 CALL_VIBRATE_ENABLED,
122 NOTIFY_WHEN_CONTACT_JOINS_SIGNAL,
123 UNIVERSAL_EXPIRE_TIMER,
124 SENT_MEDIA_QUALITY,
125 KEEP_MUTED_CHATS_ARCHIVED,
126 USE_COMPACT_NAVIGATION_BAR);
127 }
128
129 public @NonNull LiveData<String> getOnConfigurationSettingChanged() {
130 return onConfigurationSettingChanged;
131 }
132
133 public boolean isLinkPreviewsEnabled() {
134 return getBoolean(LINK_PREVIEWS, false);
135 }
136
137 public void setLinkPreviewsEnabled(boolean enabled) {
138 putBoolean(LINK_PREVIEWS, enabled);
139 }
140
141 public @NonNull KeepMessagesDuration getKeepMessagesDuration() {
142 return KeepMessagesDuration.fromId(getInteger(KEEP_MESSAGES_DURATION, 0));
143 }
144
145 public void setKeepMessagesForDuration(@NonNull KeepMessagesDuration duration) {
146 putInteger(KEEP_MESSAGES_DURATION, duration.getId());
147 }
148
149 public boolean isTrimByLengthEnabled() {
150 return getBoolean(THREAD_TRIM_ENABLED, false);
151 }
152
153 public void setThreadTrimByLengthEnabled(boolean enabled) {
154 putBoolean(THREAD_TRIM_ENABLED, enabled);
155 }
156
157 public int getThreadTrimLength() {
158 return getInteger(THREAD_TRIM_LENGTH, 500);
159 }
160
161 public void setThreadTrimLength(int length) {
162 putInteger(THREAD_TRIM_LENGTH, length);
163 }
164
165 public void setSignalBackupDirectory(@NonNull Uri uri) {
166 putString(SIGNAL_BACKUP_DIRECTORY, uri.toString());
167 putString(SIGNAL_LATEST_BACKUP_DIRECTORY, uri.toString());
168 }
169
170 public void setPreferSystemContactPhotos(boolean preferSystemContactPhotos) {
171 putBoolean(PREFER_SYSTEM_CONTACT_PHOTOS, preferSystemContactPhotos);
172 }
173
174 public boolean isPreferSystemContactPhotos() {
175 return getBoolean(PREFER_SYSTEM_CONTACT_PHOTOS, false);
176 }
177
178 public @Nullable Uri getSignalBackupDirectory() {
179 return getUri(SIGNAL_BACKUP_DIRECTORY);
180 }
181
182 public @Nullable Uri getLatestSignalBackupDirectory() {
183 return getUri(SIGNAL_LATEST_BACKUP_DIRECTORY);
184 }
185
186 public void clearSignalBackupDirectory() {
187 putString(SIGNAL_BACKUP_DIRECTORY, null);
188 }
189
190 public void setCallDataMode(@NonNull CallDataMode callDataMode) {
191 putInteger(CALL_DATA_MODE, callDataMode.getCode());
192 }
193
194 public @NonNull CallDataMode getCallDataMode() {
195 return CallDataMode.fromCode(getInteger(CALL_DATA_MODE, CallDataMode.HIGH_ALWAYS.getCode()));
196 }
197
198 public @NonNull Theme getTheme() {
199 return Theme.deserialize(getString(THEME, TextSecurePreferences.getTheme(ApplicationDependencies.getApplication())));
200 }
201
202 public void setTheme(@NonNull Theme theme) {
203 putString(THEME, theme.serialize());
204 onConfigurationSettingChanged.postValue(THEME);
205 }
206
207 public int getMessageFontSize() {
208 return getInteger(MESSAGE_FONT_SIZE, TextSecurePreferences.getMessageBodyTextSize(ApplicationDependencies.getApplication()));
209 }
210
211 public int getMessageQuoteFontSize(@NonNull Context context) {
212 int currentMessageSize = getMessageFontSize();
213 int[] possibleMessageSizes = context.getResources().getIntArray(R.array.pref_message_font_size_values);
214 int[] possibleQuoteSizes = context.getResources().getIntArray(R.array.pref_message_font_quote_size_values);
215 int sizeIndex = Arrays.binarySearch(possibleMessageSizes, currentMessageSize);
216
217 if (sizeIndex < 0) {
218 int closestSizeIndex = 0;
219 int closestSizeDiff = Integer.MAX_VALUE;
220
221 for (int i = 0; i < possibleMessageSizes.length; i++) {
222 int diff = Math.abs(possibleMessageSizes[i] - currentMessageSize);
223 if (diff < closestSizeDiff) {
224 closestSizeIndex = i;
225 closestSizeDiff = diff;
226 }
227 }
228
229 int newSize = possibleMessageSizes[closestSizeIndex];
230 Log.w(TAG, "Using non-standard font size of " + currentMessageSize + ". Closest match was " + newSize + ". Updating.");
231
232 setMessageFontSize(newSize);
233 sizeIndex = Arrays.binarySearch(possibleMessageSizes, newSize);
234 }
235
236 return possibleQuoteSizes[sizeIndex];
237 }
238
239 public void setMessageFontSize(int messageFontSize) {
240 putInteger(MESSAGE_FONT_SIZE, messageFontSize);
241 }
242
243 public @NonNull String getLanguage() {
244 return TextSecurePreferences.getLanguage(ApplicationDependencies.getApplication());
245 }
246
247 public void setLanguage(@NonNull String language) {
248 TextSecurePreferences.setLanguage(ApplicationDependencies.getApplication(), language);
249 onConfigurationSettingChanged.postValue(LANGUAGE);
250 }
251
252 public boolean isPreferSystemEmoji() {
253 return getBoolean(PREFER_SYSTEM_EMOJI, TextSecurePreferences.isSystemEmojiPreferred(ApplicationDependencies.getApplication()));
254 }
255
256 public void setPreferSystemEmoji(boolean useSystemEmoji) {
257 putBoolean(PREFER_SYSTEM_EMOJI, useSystemEmoji);
258 }
259
260 public boolean isEnterKeySends() {
261 return getBoolean(ENTER_KEY_SENDS, TextSecurePreferences.isEnterSendsEnabled(ApplicationDependencies.getApplication()));
262 }
263
264 public void setEnterKeySends(boolean enterKeySends) {
265 putBoolean(ENTER_KEY_SENDS, enterKeySends);
266 }
267
268 public boolean isBackupEnabled() {
269 return getBoolean(BACKUPS_ENABLED, TextSecurePreferences.isBackupEnabled(ApplicationDependencies.getApplication()));
270 }
271
272 public void setBackupEnabled(boolean backupEnabled) {
273 putBoolean(BACKUPS_ENABLED, backupEnabled);
274 }
275
276 public int getBackupHour() {
277 return getInteger(BACKUPS_SCHEDULE_HOUR, BACKUP_DEFAULT_HOUR);
278 }
279
280 public int getBackupMinute() {
281 return getInteger(BACKUPS_SCHEDULE_MINUTE, BACKUP_DEFAULT_MINUTE);
282 }
283
284 public void setBackupSchedule(int hour, int minute) {
285 putInteger(BACKUPS_SCHEDULE_HOUR, hour);
286 putInteger(BACKUPS_SCHEDULE_MINUTE, minute);
287 }
288
289 public boolean isSmsDeliveryReportsEnabled() {
290 return getBoolean(SMS_DELIVERY_REPORTS_ENABLED, TextSecurePreferences.isSmsDeliveryReportsEnabled(ApplicationDependencies.getApplication()));
291 }
292
293 public void setSmsDeliveryReportsEnabled(boolean smsDeliveryReportsEnabled) {
294 putBoolean(SMS_DELIVERY_REPORTS_ENABLED, smsDeliveryReportsEnabled);
295 }
296
297 public boolean isWifiCallingCompatibilityModeEnabled() {
298 return getBoolean(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, TextSecurePreferences.isWifiSmsEnabled(ApplicationDependencies.getApplication()));
299 }
300
301 public void setWifiCallingCompatibilityModeEnabled(boolean wifiCallingCompatibilityModeEnabled) {
302 putBoolean(WIFI_CALLING_COMPATIBILITY_MODE_ENABLED, wifiCallingCompatibilityModeEnabled);
303 }
304
305 public void setMessageNotificationsEnabled(boolean messageNotificationsEnabled) {
306 putBoolean(MESSAGE_NOTIFICATIONS_ENABLED, messageNotificationsEnabled);
307 }
308
309 public boolean isMessageNotificationsEnabled() {
310 return getBoolean(MESSAGE_NOTIFICATIONS_ENABLED, TextSecurePreferences.isNotificationsEnabled(ApplicationDependencies.getApplication()));
311 }
312
313 public void setMessageNotificationSound(@NonNull Uri sound) {
314 putString(MESSAGE_NOTIFICATION_SOUND, sound.toString());
315 }
316
317 public @NonNull Uri getMessageNotificationSound() {
318 String result = getString(MESSAGE_NOTIFICATION_SOUND, TextSecurePreferences.getNotificationRingtone(ApplicationDependencies.getApplication()).toString());
319
320 if (result.startsWith("file:")) {
321 result = Settings.System.DEFAULT_NOTIFICATION_URI.toString();
322 }
323
324 return Uri.parse(result);
325 }
326
327 public boolean isMessageVibrateEnabled() {
328 return getBoolean(MESSAGE_VIBRATE_ENABLED, TextSecurePreferences.isNotificationVibrateEnabled(ApplicationDependencies.getApplication()));
329 }
330
331 public void setMessageVibrateEnabled(boolean messageVibrateEnabled) {
332 putBoolean(MESSAGE_VIBRATE_ENABLED, messageVibrateEnabled);
333 }
334
335 public @NonNull String getMessageLedColor() {
336 return getString(MESSAGE_LED_COLOR, TextSecurePreferences.getNotificationLedColor(ApplicationDependencies.getApplication()));
337 }
338
339 public void setMessageLedColor(@NonNull String ledColor) {
340 putString(MESSAGE_LED_COLOR, ledColor);
341 }
342
343 public @NonNull String getMessageLedBlinkPattern() {
344 return getString(MESSAGE_LED_BLINK_PATTERN, TextSecurePreferences.getNotificationLedPattern(ApplicationDependencies.getApplication()));
345 }
346
347 public void setMessageLedBlinkPattern(@NonNull String blinkPattern) {
348 putString(MESSAGE_LED_BLINK_PATTERN, blinkPattern);
349 }
350
351 public boolean isMessageNotificationsInChatSoundsEnabled() {
352 return getBoolean(MESSAGE_IN_CHAT_SOUNDS_ENABLED, TextSecurePreferences.isInThreadNotifications(ApplicationDependencies.getApplication()));
353 }
354
355 public void setMessageNotificationsInChatSoundsEnabled(boolean inChatSoundsEnabled) {
356 putBoolean(MESSAGE_IN_CHAT_SOUNDS_ENABLED, inChatSoundsEnabled);
357 }
358
359 public int getMessageNotificationsRepeatAlerts() {
360 return getInteger(MESSAGE_REPEAT_ALERTS, TextSecurePreferences.getRepeatAlertsCount(ApplicationDependencies.getApplication()));
361 }
362
363 public void setMessageNotificationsRepeatAlerts(int count) {
364 putInteger(MESSAGE_REPEAT_ALERTS, count);
365 }
366
367 public @NonNull NotificationPrivacyPreference getMessageNotificationsPrivacy() {
368 return new NotificationPrivacyPreference(getString(MESSAGE_NOTIFICATION_PRIVACY, TextSecurePreferences.getNotificationPrivacy(ApplicationDependencies.getApplication()).toString()));
369 }
370
371 public void setMessageNotificationsPrivacy(@NonNull NotificationPrivacyPreference messageNotificationsPrivacy) {
372 putString(MESSAGE_NOTIFICATION_PRIVACY, messageNotificationsPrivacy.toString());
373 }
374
375 public boolean isCallNotificationsEnabled() {
376 return getBoolean(CALL_NOTIFICATIONS_ENABLED, TextSecurePreferences.isCallNotificationsEnabled(ApplicationDependencies.getApplication()));
377 }
378
379 public void setCallNotificationsEnabled(boolean callNotificationsEnabled) {
380 putBoolean(CALL_NOTIFICATIONS_ENABLED, callNotificationsEnabled);
381 }
382
383 public @NonNull Uri getCallRingtone() {
384 String result = getString(CALL_RINGTONE, TextSecurePreferences.getCallNotificationRingtone(ApplicationDependencies.getApplication()).toString());
385
386 if (result != null && result.startsWith("file:")) {
387 result = Settings.System.DEFAULT_RINGTONE_URI.toString();
388 }
389
390 return Uri.parse(result);
391 }
392
393 public void setCallRingtone(@NonNull Uri ringtone) {
394 putString(CALL_RINGTONE, ringtone.toString());
395 }
396
397 public boolean isCallVibrateEnabled() {
398 return getBoolean(CALL_VIBRATE_ENABLED, TextSecurePreferences.isCallNotificationVibrateEnabled(ApplicationDependencies.getApplication()));
399 }
400
401 public void setCallVibrateEnabled(boolean callVibrateEnabled) {
402 putBoolean(CALL_VIBRATE_ENABLED, callVibrateEnabled);
403 }
404
405 public boolean isNotifyWhenContactJoinsSignal() {
406 return getBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, TextSecurePreferences.isNewContactsNotificationEnabled(ApplicationDependencies.getApplication()));
407 }
408
409 public void setNotifyWhenContactJoinsSignal(boolean notifyWhenContactJoinsSignal) {
410 putBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, notifyWhenContactJoinsSignal);
411 }
412
413 public void setUniversalExpireTimer(int seconds) {
414 putInteger(UNIVERSAL_EXPIRE_TIMER, seconds);
415 }
416
417 public int getUniversalExpireTimer() {
418 return getInteger(UNIVERSAL_EXPIRE_TIMER, 0);
419 }
420
421 public void setSentMediaQuality(@NonNull SentMediaQuality sentMediaQuality) {
422 putInteger(SENT_MEDIA_QUALITY, sentMediaQuality.getCode());
423 }
424
425 public @NonNull SentMediaQuality getSentMediaQuality() {
426 return SentMediaQuality.fromCode(getInteger(SENT_MEDIA_QUALITY, SentMediaQuality.STANDARD.getCode()));
427 }
428
429 public @NonNull CensorshipCircumventionEnabled getCensorshipCircumventionEnabled() {
430 return CensorshipCircumventionEnabled.deserialize(getInteger(CENSORSHIP_CIRCUMVENTION_ENABLED, CensorshipCircumventionEnabled.DEFAULT.serialize()));
431 }
432
433 public void setCensorshipCircumventionEnabled(boolean enabled) {
434 Log.i(TAG, "Changing censorship circumvention state to: " + enabled, new Throwable());
435 putInteger(CENSORSHIP_CIRCUMVENTION_ENABLED, enabled ? CensorshipCircumventionEnabled.ENABLED.serialize() : CensorshipCircumventionEnabled.DISABLED.serialize());
436 }
437
438 public void setKeepMutedChatsArchived(boolean enabled) {
439 putBoolean(KEEP_MUTED_CHATS_ARCHIVED, enabled);
440 }
441
442 public boolean shouldKeepMutedChatsArchived() {
443 return getBoolean(KEEP_MUTED_CHATS_ARCHIVED, false);
444 }
445
446 public void setUseCompactNavigationBar(boolean enabled) {
447 putBoolean(USE_COMPACT_NAVIGATION_BAR, enabled);
448 }
449
450 public boolean getUseCompactNavigationBar() {
451 return getBoolean(USE_COMPACT_NAVIGATION_BAR, false);
452 }
453
454 private @Nullable Uri getUri(@NonNull String key) {
455 String uri = getString(key, "");
456
457 if (TextUtils.isEmpty(uri)) {
458 return null;
459 } else {
460 return Uri.parse(uri);
461 }
462 }
463
464 public enum CensorshipCircumventionEnabled {
465 DEFAULT(0), ENABLED(1), DISABLED(2);
466
467 private final int value;
468
469 CensorshipCircumventionEnabled(int value) {
470 this.value = value;
471 }
472
473 public static CensorshipCircumventionEnabled deserialize(int value) {
474 switch (value) {
475 case 0:
476 return DEFAULT;
477 case 1:
478 return ENABLED;
479 case 2:
480 return DISABLED;
481 default:
482 throw new IllegalArgumentException("Bad value: " + value);
483 }
484 }
485
486 public int serialize() {
487 return value;
488 }
489 }
490
491 public enum Theme {
492 SYSTEM("system"), LIGHT("light"), DARK("dark");
493
494 private final String value;
495
496 Theme(String value) {
497 this.value = value;
498 }
499
500 public @NonNull String serialize() {
501 return value;
502 }
503
504 public static @NonNull Theme deserialize(@NonNull String value) {
505 switch (value) {
506 case "system":
507 return SYSTEM;
508 case "light":
509 return LIGHT;
510 case "dark":
511 return DARK;
512 default:
513 throw new IllegalArgumentException("Unrecognized value " + value);
514 }
515 }
516 }
517}