AppSettings.java

  1package eu.siacs.conversations;
  2
  3import android.content.Context;
  4import android.content.SharedPreferences;
  5import android.net.Uri;
  6import android.os.Environment;
  7import androidx.annotation.BoolRes;
  8import androidx.annotation.NonNull;
  9import androidx.preference.PreferenceManager;
 10import com.google.common.base.Joiner;
 11import com.google.common.base.Splitter;
 12import com.google.common.base.Strings;
 13import eu.siacs.conversations.persistance.FileBackend;
 14import eu.siacs.conversations.services.QuickConversationsService;
 15import eu.siacs.conversations.utils.Compatibility;
 16import java.security.SecureRandom;
 17
 18public class AppSettings {
 19
 20    public static final String KEEP_FOREGROUND_SERVICE = "enable_foreground_service";
 21    public static final String AWAY_WHEN_SCREEN_IS_OFF = "away_when_screen_off";
 22    public static final String TREAT_VIBRATE_AS_SILENT = "treat_vibrate_as_silent";
 23    public static final String DND_ON_SILENT_MODE = "dnd_on_silent_mode";
 24    public static final String MANUALLY_CHANGE_PRESENCE = "manually_change_presence";
 25    public static final String BLIND_TRUST_BEFORE_VERIFICATION = "btbv";
 26    public static final String AUTOMATIC_MESSAGE_DELETION = "automatic_message_deletion";
 27    public static final String BROADCAST_LAST_ACTIVITY = "last_activity";
 28    public static final String THEME = "theme";
 29    public static final String DYNAMIC_COLORS = "dynamic_colors";
 30    public static final String SHOW_DYNAMIC_TAGS = "show_dynamic_tags";
 31    public static final String OMEMO = "omemo";
 32    public static final String ALLOW_SCREENSHOTS = "allow_screenshots";
 33    public static final String RINGTONE = "call_ringtone";
 34    public static final String BTBV = "btbv";
 35
 36    public static final String CONFIRM_MESSAGES = "confirm_messages";
 37    public static final String ALLOW_MESSAGE_CORRECTION = "allow_message_correction";
 38
 39    public static final String TRUST_SYSTEM_CA_STORE = "trust_system_ca_store";
 40    public static final String REQUIRE_CHANNEL_BINDING = "channel_binding_required";
 41    public static final String NOTIFICATION_RINGTONE = "notification_ringtone";
 42    public static final String NOTIFICATION_HEADS_UP = "notification_headsup";
 43    public static final String NOTIFICATION_VIBRATE = "vibrate_on_notification";
 44    public static final String NOTIFICATION_LED = "led";
 45    public static final String SHOW_CONNECTION_OPTIONS = "show_connection_options";
 46    public static final String USE_TOR = "use_tor";
 47    public static final String CHANNEL_DISCOVERY_METHOD = "channel_discovery_method";
 48    public static final String SEND_CRASH_REPORTS = "send_crash_reports";
 49    public static final String COLORFUL_CHAT_BUBBLES = "use_green_background";
 50    public static final String LARGE_FONT = "large_font";
 51    public static final String SHOW_AVATARS = "show_avatars";
 52    public static final String CALL_INTEGRATION = "call_integration";
 53    public static final String ALIGN_START = "align_start";
 54    public static final String BACKUP_LOCATION = "backup_location";
 55
 56    private static final String ACCEPT_INVITES_FROM_STRANGERS = "accept_invites_from_strangers";
 57    private static final String INSTALLATION_ID = "im.conversations.android.install_id";
 58
 59    private static final String EXTERNAL_STORAGE_AUTHORITY =
 60            "com.android.externalstorage.documents";
 61
 62    private final Context context;
 63
 64    public AppSettings(final Context context) {
 65        this.context = context;
 66    }
 67
 68    public Uri getRingtone() {
 69        final SharedPreferences sharedPreferences =
 70                PreferenceManager.getDefaultSharedPreferences(context);
 71        final String incomingCallRingtone =
 72                sharedPreferences.getString(
 73                        RINGTONE, context.getString(R.string.incoming_call_ringtone));
 74        return Strings.isNullOrEmpty(incomingCallRingtone) ? null : Uri.parse(incomingCallRingtone);
 75    }
 76
 77    public void setRingtone(final Uri uri) {
 78        final SharedPreferences sharedPreferences =
 79                PreferenceManager.getDefaultSharedPreferences(context);
 80        sharedPreferences.edit().putString(RINGTONE, uri == null ? null : uri.toString()).apply();
 81    }
 82
 83    public Uri getNotificationTone() {
 84        final SharedPreferences sharedPreferences =
 85                PreferenceManager.getDefaultSharedPreferences(context);
 86        final String incomingCallRingtone =
 87                sharedPreferences.getString(
 88                        NOTIFICATION_RINGTONE, context.getString(R.string.notification_ringtone));
 89        return Strings.isNullOrEmpty(incomingCallRingtone) ? null : Uri.parse(incomingCallRingtone);
 90    }
 91
 92    public void setNotificationTone(final Uri uri) {
 93        final SharedPreferences sharedPreferences =
 94                PreferenceManager.getDefaultSharedPreferences(context);
 95        sharedPreferences
 96                .edit()
 97                .putString(NOTIFICATION_RINGTONE, uri == null ? null : uri.toString())
 98                .apply();
 99    }
100
101    public boolean isBTBVEnabled() {
102        return getBooleanPreference(BTBV, R.bool.btbv);
103    }
104
105    public boolean isTrustSystemCAStore() {
106        return getBooleanPreference(TRUST_SYSTEM_CA_STORE, R.bool.trust_system_ca_store);
107    }
108
109    public boolean isAllowScreenshots() {
110        return getBooleanPreference(ALLOW_SCREENSHOTS, R.bool.allow_screenshots);
111    }
112
113    public boolean isColorfulChatBubbles() {
114        return getBooleanPreference(COLORFUL_CHAT_BUBBLES, R.bool.use_green_background);
115    }
116
117    public boolean isLargeFont() {
118        return getBooleanPreference(LARGE_FONT, R.bool.large_font);
119    }
120
121    public boolean isShowAvatars() {
122        return getBooleanPreference(SHOW_AVATARS, R.bool.show_avatars);
123    }
124
125    public boolean isCallIntegration() {
126        return getBooleanPreference(CALL_INTEGRATION, R.bool.call_integration);
127    }
128
129    public boolean isAlignStart() {
130        return getBooleanPreference(ALIGN_START, R.bool.align_start);
131    }
132
133    public boolean isConfirmMessages() {
134        return getBooleanPreference(CONFIRM_MESSAGES, R.bool.confirm_messages);
135    }
136
137    public boolean isAllowMessageCorrection() {
138        return getBooleanPreference(ALLOW_MESSAGE_CORRECTION, R.bool.allow_message_correction);
139    }
140
141    public boolean isBroadcastLastActivity() {
142        return getBooleanPreference(BROADCAST_LAST_ACTIVITY, R.bool.last_activity);
143    }
144
145    public boolean isUseTor() {
146        return QuickConversationsService.isConversations()
147                && getBooleanPreference(USE_TOR, R.bool.use_tor);
148    }
149
150    public boolean isExtendedConnectionOptions() {
151        return QuickConversationsService.isConversations()
152                && getBooleanPreference(
153                        AppSettings.SHOW_CONNECTION_OPTIONS, R.bool.show_connection_options);
154    }
155
156    public boolean isAcceptInvitesFromStrangers() {
157        return getBooleanPreference(
158                ACCEPT_INVITES_FROM_STRANGERS, R.bool.accept_invites_from_strangers);
159    }
160
161    public boolean isKeepForegroundService() {
162        return Compatibility.twentySix()
163                || getBooleanPreference(KEEP_FOREGROUND_SERVICE, R.bool.enable_foreground_service);
164    }
165
166    private boolean getBooleanPreference(@NonNull final String name, @BoolRes int res) {
167        final SharedPreferences sharedPreferences =
168                PreferenceManager.getDefaultSharedPreferences(context);
169        return sharedPreferences.getBoolean(name, context.getResources().getBoolean(res));
170    }
171
172    public String getOmemo() {
173        final SharedPreferences sharedPreferences =
174                PreferenceManager.getDefaultSharedPreferences(context);
175        return sharedPreferences.getString(
176                OMEMO, context.getString(R.string.omemo_setting_default));
177    }
178
179    public Uri getBackupLocation() {
180        final SharedPreferences sharedPreferences =
181                PreferenceManager.getDefaultSharedPreferences(context);
182        final String location = sharedPreferences.getString(BACKUP_LOCATION, null);
183        if (Strings.isNullOrEmpty(location)) {
184            final var directory = FileBackend.getBackupDirectory(context);
185            return Uri.fromFile(directory);
186        }
187        return Uri.parse(location);
188    }
189
190    public String getBackupLocationAsPath() {
191        return asPath(getBackupLocation());
192    }
193
194    public static String asPath(final Uri uri) {
195        final var scheme = uri.getScheme();
196        final var path = uri.getPath();
197        if (path == null) {
198            return uri.toString();
199        }
200        if ("file".equalsIgnoreCase(scheme)) {
201            return path;
202        } else if ("content".equalsIgnoreCase(scheme)) {
203            if (EXTERNAL_STORAGE_AUTHORITY.equalsIgnoreCase(uri.getAuthority())) {
204                final var parts = Splitter.on(':').limit(2).splitToList(path);
205                if (parts.size() == 2 && "/tree/primary".equals(parts.get(0))) {
206                    return Joiner.on('/')
207                            .join(Environment.getExternalStorageDirectory(), parts.get(1));
208                }
209            }
210        }
211        return uri.toString();
212    }
213
214    public void setBackupLocation(final Uri uri) {
215        final SharedPreferences sharedPreferences =
216                PreferenceManager.getDefaultSharedPreferences(context);
217        sharedPreferences
218                .edit()
219                .putString(BACKUP_LOCATION, uri == null ? "" : uri.toString())
220                .apply();
221    }
222
223    public boolean isSendCrashReports() {
224        return getBooleanPreference(SEND_CRASH_REPORTS, R.bool.send_crash_reports);
225    }
226
227    public void setSendCrashReports(boolean value) {
228        final SharedPreferences sharedPreferences =
229                PreferenceManager.getDefaultSharedPreferences(context);
230        sharedPreferences.edit().putBoolean(SEND_CRASH_REPORTS, value).apply();
231    }
232
233    public boolean isRequireChannelBinding() {
234        return getBooleanPreference(REQUIRE_CHANNEL_BINDING, R.bool.require_channel_binding);
235    }
236
237    public synchronized long getInstallationId() {
238        final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
239        final long existing = sharedPreferences.getLong(INSTALLATION_ID, 0);
240        if (existing != 0) {
241            return existing;
242        }
243        final var secureRandom = new SecureRandom();
244        final var installationId = secureRandom.nextLong();
245        sharedPreferences.edit().putLong(INSTALLATION_ID, installationId).apply();
246        return installationId;
247    }
248
249    public synchronized void resetInstallationId() {
250        final var secureRandom = new SecureRandom();
251        final var installationId = secureRandom.nextLong();
252        PreferenceManager.getDefaultSharedPreferences(context)
253                .edit()
254                .putLong(INSTALLATION_ID, installationId)
255                .apply();
256    }
257}