diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java index 9aea73cf07..6634da5c55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java @@ -39,9 +39,9 @@ import org.thoughtcrime.securesms.preferences.AppearancePreferenceFragment; import org.thoughtcrime.securesms.preferences.BackupsPreferenceFragment; import org.thoughtcrime.securesms.preferences.ChatsPreferenceFragment; import org.thoughtcrime.securesms.preferences.CorrectedPreferenceFragment; +import org.thoughtcrime.securesms.preferences.DataAndStoragePreferenceFragment; import org.thoughtcrime.securesms.preferences.NotificationsPreferenceFragment; import org.thoughtcrime.securesms.preferences.SmsMmsPreferenceFragment; -import org.thoughtcrime.securesms.preferences.StoragePreferenceFragment; import org.thoughtcrime.securesms.preferences.widgets.ProfilePreference; import org.thoughtcrime.securesms.preferences.widgets.UsernamePreference; import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity; @@ -309,7 +309,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActivity fragment = new ChatsPreferenceFragment(); break; case PREFERENCE_CATEGORY_STORAGE: - fragment = new StoragePreferenceFragment(); + fragment = new DataAndStoragePreferenceFragment(); break; case PREFERENCE_CATEGORY_DEVICES: Intent intent = new Intent(getActivity(), DeviceActivity.class); diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java index 08481dfd36..36ab5eeeee 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SettingsValues.java @@ -6,6 +6,8 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.thoughtcrime.securesms.webrtc.CallBandwidthMode; + public final class SettingsValues extends SignalStoreValues { public static final String LINK_PREVIEWS = "settings.link_previews"; @@ -14,6 +16,8 @@ public final class SettingsValues extends SignalStoreValues { private static final String SIGNAL_BACKUP_DIRECTORY = "settings.signal.backup.directory"; private static final String SIGNAL_LATEST_BACKUP_DIRECTORY = "settings.signal.backup.directory,latest"; + private static final String CALL_BANDWIDTH_MODE = "settings.signal.call.bandwidth.mode"; + public static final String THREAD_TRIM_LENGTH = "pref_trim_length"; public static final String THREAD_TRIM_ENABLED = "pref_trim_threads"; @@ -77,6 +81,14 @@ public final class SettingsValues extends SignalStoreValues { putString(SIGNAL_BACKUP_DIRECTORY, null); } + public void setCallBandwidthMode(@NonNull CallBandwidthMode callBandwidthMode) { + putInteger(CALL_BANDWIDTH_MODE, callBandwidthMode.getCode()); + } + + public @NonNull CallBandwidthMode getCallBandwidthMode() { + return CallBandwidthMode.fromCode(getInteger(CALL_BANDWIDTH_MODE, CallBandwidthMode.HIGH_ALWAYS.getCode())); + } + private @Nullable Uri getUri(@NonNull String key) { String uri = getString(key, ""); diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/ChatsPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/ChatsPreferenceFragment.java index ae4d5820ea..c03654f2fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/ChatsPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/ChatsPreferenceFragment.java @@ -13,26 +13,22 @@ import org.greenrobot.eventbus.EventBus; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.ApplicationPreferencesActivity; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.permissions.Permissions; +import org.thoughtcrime.securesms.service.WebRtcCallService; import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.webrtc.CallBandwidthMode; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment { - private static final String TAG = ChatsPreferenceFragment.class.getSimpleName(); - @Override public void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF) - .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF) - .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF) - .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); findPreference(TextSecurePreferences.MESSAGE_BODY_TEXT_SIZE_PREF) .setOnPreferenceChangeListener(new ListSummaryListener()); @@ -52,8 +48,7 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment { @Override public void onResume() { super.onResume(); - ((ApplicationPreferencesActivity)getActivity()).getSupportActionBar().setTitle(R.string.preferences__chats); - setMediaDownloadSummaries(); + ((ApplicationPreferencesActivity)getActivity()).getSupportActionBar().setTitle(R.string.preferences_chats__chats); } @Override @@ -71,37 +66,6 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment { ((ApplicationPreferencesActivity) requireActivity()).pushFragment(new BackupsPreferenceFragment()); } - private void setMediaDownloadSummaries() { - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF) - .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getMobileMediaDownloadAllowed(getActivity()))); - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF) - .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getWifiMediaDownloadAllowed(getActivity()))); - findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF) - .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getRoamingMediaDownloadAllowed(getActivity()))); - } - - private CharSequence getSummaryForMediaPreference(Set allowedNetworks) { - String[] keys = getResources().getStringArray(R.array.pref_media_download_entries); - String[] values = getResources().getStringArray(R.array.pref_media_download_values); - List outValues = new ArrayList<>(allowedNetworks.size()); - - for (int i=0; i < keys.length; i++) { - if (allowedNetworks.contains(keys[i])) outValues.add(values[i]); - } - - return outValues.isEmpty() ? getResources().getString(R.string.preferences__none) - : TextUtils.join(", ", outValues); - } - - private class MediaDownloadChangeListener implements Preference.OnPreferenceChangeListener { - @SuppressWarnings("unchecked") - @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - Log.i(TAG, "onPreferenceChange"); - preference.setSummary(getSummaryForMediaPreference((Set)newValue)); - return true; - } - } - public static CharSequence getSummary(Context context) { return null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/DataAndStoragePreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/DataAndStoragePreferenceFragment.java new file mode 100644 index 0000000000..39c1259a75 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/DataAndStoragePreferenceFragment.java @@ -0,0 +1,130 @@ +package org.thoughtcrime.securesms.preferences; + +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.preference.ListPreference; +import androidx.preference.Preference; + +import org.signal.core.util.logging.Log; +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.keyvalue.SignalStore; +import org.thoughtcrime.securesms.service.WebRtcCallService; +import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.webrtc.CallBandwidthMode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class DataAndStoragePreferenceFragment extends ListSummaryPreferenceFragment { + + private static final String TAG = Log.tag(DataAndStoragePreferenceFragment.class); + private static final String MANAGE_STORAGE_KEY = "pref_data_manage"; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF) + .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF) + .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF) + .setOnPreferenceChangeListener(new MediaDownloadChangeListener()); + + findPreference(TextSecurePreferences.CALL_BANDWIDTH_PREF) + .setOnPreferenceChangeListener(new CallBandwidthChangeListener()); + initializeListSummary((ListPreference) findPreference(TextSecurePreferences.CALL_BANDWIDTH_PREF)); + + Preference manageStorage = findPreference(MANAGE_STORAGE_KEY); + manageStorage.setOnPreferenceClickListener(unused -> { + requireApplicationPreferencesActivity().pushFragment(new StoragePreferenceFragment()); + return false; + }); + + ApplicationPreferencesViewModel viewModel = ApplicationPreferencesViewModel.getApplicationPreferencesViewModel(requireActivity()); + + viewModel.getStorageBreakdown() + .observe(requireActivity(), + breakdown -> manageStorage.setSummary(Util.getPrettyFileSize(breakdown.getTotalSize()))); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.preferences_data_and_storage); + } + + @Override + public void onResume() { + super.onResume(); + requireApplicationPreferencesActivity().getSupportActionBar().setTitle(R.string.preferences__data_and_storage); + setMediaDownloadSummaries(); + ApplicationPreferencesViewModel.getApplicationPreferencesViewModel(requireActivity()).refreshStorageBreakdown(requireContext()); + } + + private @NonNull ApplicationPreferencesActivity requireApplicationPreferencesActivity() { + return (ApplicationPreferencesActivity) requireActivity(); + } + + private void setMediaDownloadSummaries() { + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_MOBILE_PREF) + .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getMobileMediaDownloadAllowed(getActivity()))); + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_WIFI_PREF) + .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getWifiMediaDownloadAllowed(getActivity()))); + findPreference(TextSecurePreferences.MEDIA_DOWNLOAD_ROAMING_PREF) + .setSummary(getSummaryForMediaPreference(TextSecurePreferences.getRoamingMediaDownloadAllowed(getActivity()))); + } + + private CharSequence getSummaryForMediaPreference(Set allowedNetworks) { + String[] keys = getResources().getStringArray(R.array.pref_media_download_entries); + String[] values = getResources().getStringArray(R.array.pref_media_download_values); + List outValues = new ArrayList<>(allowedNetworks.size()); + + for (int i=0; i < keys.length; i++) { + if (allowedNetworks.contains(keys[i])) outValues.add(values[i]); + } + + return outValues.isEmpty() ? getResources().getString(R.string.preferences__none) + : TextUtils.join(", ", outValues); + } + + private class MediaDownloadChangeListener implements Preference.OnPreferenceChangeListener { + @SuppressWarnings("unchecked") + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { + Log.i(TAG, "onPreferenceChange"); + preference.setSummary(getSummaryForMediaPreference((Set)newValue)); + return true; + } + } + + private class CallBandwidthChangeListener extends ListSummaryListener { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + ListPreference listPref = (ListPreference) preference; + int entryIndex = Arrays.asList(listPref.getEntryValues()).indexOf(value); + + switch (entryIndex) { + case 0: + SignalStore.settings().setCallBandwidthMode(CallBandwidthMode.HIGH_ALWAYS); + break; + case 1: + SignalStore.settings().setCallBandwidthMode(CallBandwidthMode.HIGH_ON_WIFI); + break; + case 2: + SignalStore.settings().setCallBandwidthMode(CallBandwidthMode.LOW_ALWAYS); + break; + default: + throw new AssertionError(); + } + + WebRtcCallService.notifyBandwidthModeUpdated(requireContext()); + + return super.onPreferenceChange(preference, value); + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/widgets/StorageGraphView.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/widgets/StorageGraphView.java index 21941c77f6..43bfd23a59 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/widgets/StorageGraphView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/widgets/StorageGraphView.java @@ -107,7 +107,7 @@ public final class StorageGraphView extends View { this.totalSize = total; } - long getTotalSize() { + public long getTotalSize() { return totalSize; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java index f82d6e61f9..7c07373f1c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -152,6 +152,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer, public static final String ACTION_FLIP_CAMERA = "FLIP_CAMERA"; public static final String ACTION_BLUETOOTH_CHANGE = "BLUETOOTH_CHANGE"; public static final String ACTION_NETWORK_CHANGE = "NETWORK_CHANGE"; + public static final String ACTION_BANDWIDTH_MODE_UPDATE = "BANDWIDTH_MODE_UPDATE"; public static final String ACTION_WIRED_HEADSET_CHANGE = "WIRED_HEADSET_CHANGE"; public static final String ACTION_SCREEN_OFF = "SCREEN_OFF"; public static final String ACTION_IS_IN_CALL_QUERY = "IS_IN_CALL"; @@ -536,6 +537,9 @@ public class WebRtcCallService extends Service implements CallManager.Observer, serviceIntent.setAction(ACTION_NETWORK_CHANGE); serviceIntent.putExtra(EXTRA_AVAILABLE, activeNetworkInfo != null && activeNetworkInfo.isConnected()); context.startService(serviceIntent); + + serviceIntent.setAction(ACTION_BANDWIDTH_MODE_UPDATE); + context.startService(serviceIntent); } } @@ -572,6 +576,13 @@ public class WebRtcCallService extends Service implements CallManager.Observer, context.startService(intent); } + public static void notifyBandwidthModeUpdated(@NonNull Context context) { + Intent intent = new Intent(context, WebRtcCallService.class); + intent.setAction(ACTION_BANDWIDTH_MODE_UPDATE); + + context.startService(intent); + } + private class HangUpRtcOnPstnCallAnsweredListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, @NonNull String phoneNumber) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java index 42abae02e9..eced2f15c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallSetupActionProcessorDelegate.java @@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.ringrtc.CallState; import org.thoughtcrime.securesms.ringrtc.Camera; import org.thoughtcrime.securesms.ringrtc.RemotePeer; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; +import org.thoughtcrime.securesms.util.NetworkUtil; import org.thoughtcrime.securesms.webrtc.locks.LockManager; import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED; @@ -62,6 +63,7 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor { callManager.setCommunicationMode(); callManager.setAudioEnable(currentState.getLocalDeviceState().isMicrophoneEnabled()); callManager.setVideoEnable(currentState.getLocalDeviceState().getCameraState().isEnabled()); + callManager.setLowBandwidthMode(NetworkUtil.useLowBandwidthCalling(context)); } catch (CallException e) { return callFailure(currentState, "Enabling audio/video failed: ", e); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java index cc9c0e89de..055d932ec9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupJoiningActionProcessor.java @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.events.WebRtcViewModel; import org.thoughtcrime.securesms.ringrtc.Camera; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder; +import org.thoughtcrime.securesms.util.NetworkUtil; import org.thoughtcrime.securesms.webrtc.locks.LockManager; import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED; @@ -74,6 +75,7 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor { try { groupCall.setOutgoingVideoMuted(!currentState.getLocalDeviceState().getCameraState().isEnabled()); groupCall.setOutgoingAudioMuted(!currentState.getLocalDeviceState().isMicrophoneEnabled()); + groupCall.setBandwidthMode(NetworkUtil.useLowBandwidthCalling(context) ? GroupCall.BandwidthMode.LOW : GroupCall.BandwidthMode.NORMAL); } catch (CallException e) { Log.e(tag, e); throw new RuntimeException(e); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java index 3ded6bbf92..3d450b15c2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java @@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.ringrtc.RemotePeer; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder; +import org.thoughtcrime.securesms.util.NetworkUtil; import org.thoughtcrime.securesms.util.ServiceUtil; import org.whispersystems.signalservice.api.messages.calls.OfferMessage; @@ -51,6 +52,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor { try { groupCall.setOutgoingAudioMuted(true); groupCall.setOutgoingVideoMuted(true); + groupCall.setBandwidthMode(NetworkUtil.useLowBandwidthCalling(context) ? GroupCall.BandwidthMode.LOW : GroupCall.BandwidthMode.NORMAL); Log.i(TAG, "Connecting to group call: " + currentState.getCallInfoState().getCallRecipient().getId()); groupCall.connect(); @@ -149,7 +151,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor { groupCall.setOutgoingVideoSource(currentState.getVideoState().requireLocalSink(), currentState.getVideoState().requireCamera()); groupCall.setOutgoingVideoMuted(!currentState.getLocalDeviceState().getCameraState().isEnabled()); groupCall.setOutgoingAudioMuted(!currentState.getLocalDeviceState().isMicrophoneEnabled()); - groupCall.setBandwidthMode(GroupCall.BandwidthMode.NORMAL); + groupCall.setBandwidthMode(NetworkUtil.useLowBandwidthCalling(context) ? GroupCall.BandwidthMode.LOW : GroupCall.BandwidthMode.NORMAL); groupCall.join(); } catch (CallException e) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java index 6a0dd02489..130297e101 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/WebRtcActionProcessor.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.os.ResultReceiver; +import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -26,6 +27,7 @@ import org.thoughtcrime.securesms.service.webrtc.WebRtcData.OfferMetadata; import org.thoughtcrime.securesms.service.webrtc.WebRtcData.ReceivedOfferMetadata; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder; +import org.thoughtcrime.securesms.util.NetworkUtil; import org.thoughtcrime.securesms.util.TelephonyUtil; import org.thoughtcrime.securesms.webrtc.locks.LockManager; import org.webrtc.PeerConnection; @@ -42,6 +44,7 @@ import java.util.List; import java.util.Objects; import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_ACCEPT_CALL; +import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_BANDWIDTH_MODE_UPDATE; import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_BLUETOOTH_CHANGE; import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_CALL_CONCLUDED; import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_CALL_CONNECTED; @@ -215,6 +218,7 @@ public abstract class WebRtcActionProcessor { case ACTION_BLUETOOTH_CHANGE: return handleBluetoothChange(currentState, getAvailable(intent)); case ACTION_CAMERA_SWITCH_COMPLETED: return handleCameraSwitchCompleted(currentState, getCameraState(intent)); case ACTION_NETWORK_CHANGE: return handleNetworkChanged(currentState, getAvailable(intent)); + case ACTION_BANDWIDTH_MODE_UPDATE: return handleBandwidthModeUpdate(currentState); // End Call Actions case ACTION_ENDED_REMOTE_HANGUP: @@ -605,6 +609,16 @@ public abstract class WebRtcActionProcessor { return currentState; } + protected @NonNull WebRtcServiceState handleBandwidthModeUpdate(@NonNull WebRtcServiceState currentState) { + try { + webRtcInteractor.getCallManager().setLowBandwidthMode(NetworkUtil.useLowBandwidthCalling(context)); + } catch (CallException e) { + Log.i(tag, "handleBandwidthModeUpdate: could not update bandwidth mode."); + } + + return currentState; + } + //endregion Local device //region End call diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java index ec0d570fc4..b00b356568 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AttachmentUtil.java @@ -82,29 +82,10 @@ public class AttachmentUtil { } private static @NonNull Set getAllowedAutoDownloadTypes(@NonNull Context context) { - if (isConnectedWifi(context)) return TextSecurePreferences.getWifiMediaDownloadAllowed(context); - else if (isConnectedRoaming(context)) return TextSecurePreferences.getRoamingMediaDownloadAllowed(context); - else if (isConnectedMobile(context)) return TextSecurePreferences.getMobileMediaDownloadAllowed(context); - else return Collections.emptySet(); - } - - private static NetworkInfo getNetworkInfo(@NonNull Context context) { - return ServiceUtil.getConnectivityManager(context).getActiveNetworkInfo(); - } - - private static boolean isConnectedWifi(@NonNull Context context) { - final NetworkInfo info = getNetworkInfo(context); - return info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI; - } - - private static boolean isConnectedMobile(@NonNull Context context) { - final NetworkInfo info = getNetworkInfo(context); - return info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE; - } - - private static boolean isConnectedRoaming(@NonNull Context context) { - final NetworkInfo info = getNetworkInfo(context); - return info != null && info.isConnected() && info.isRoaming() && info.getType() == ConnectivityManager.TYPE_MOBILE; + if (NetworkUtil.isConnectedWifi(context)) return TextSecurePreferences.getWifiMediaDownloadAllowed(context); + else if (NetworkUtil.isConnectedRoaming(context)) return TextSecurePreferences.getRoamingMediaDownloadAllowed(context); + else if (NetworkUtil.isConnectedMobile(context)) return TextSecurePreferences.getMobileMediaDownloadAllowed(context); + else return Collections.emptySet(); } @WorkerThread diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java new file mode 100644 index 0000000000..86c655a060 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java @@ -0,0 +1,44 @@ +package org.thoughtcrime.securesms.util; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.keyvalue.SignalStore; + +public final class NetworkUtil { + + private NetworkUtil() {} + + public static boolean isConnectedWifi(@NonNull Context context) { + final NetworkInfo info = getNetworkInfo(context); + return info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI; + } + + public static boolean isConnectedMobile(@NonNull Context context) { + final NetworkInfo info = getNetworkInfo(context); + return info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE; + } + + public static boolean isConnectedRoaming(@NonNull Context context) { + final NetworkInfo info = getNetworkInfo(context); + return info != null && info.isConnected() && info.isRoaming() && info.getType() == ConnectivityManager.TYPE_MOBILE; + } + + public static boolean useLowBandwidthCalling(@NonNull Context context) { + switch (SignalStore.settings().getCallBandwidthMode()) { + case HIGH_ON_WIFI: + return !NetworkUtil.isConnectedWifi(context); + case HIGH_ALWAYS: + return false; + default: + return true; + } + } + + private static NetworkInfo getNetworkInfo(@NonNull Context context) { + return ServiceUtil.getConnectivityManager(context).getActiveNetworkInfo(); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 1d50618a10..6d8325d026 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -113,6 +113,8 @@ public class TextSecurePreferences { public static final String MEDIA_DOWNLOAD_WIFI_PREF = "pref_media_download_wifi"; public static final String MEDIA_DOWNLOAD_ROAMING_PREF = "pref_media_download_roaming"; + public static final String CALL_BANDWIDTH_PREF = "pref_data_call_bandwidth"; + public static final String SYSTEM_EMOJI_PREF = "pref_system_emoji"; private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device"; public static final String DIRECT_CAPTURE_CAMERA_ID = "pref_direct_capture_camera_id"; diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBandwidthMode.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBandwidthMode.java new file mode 100644 index 0000000000..915263264c --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBandwidthMode.java @@ -0,0 +1,40 @@ +package org.thoughtcrime.securesms.webrtc; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import org.signal.core.util.logging.Log; +import org.signal.ringrtc.CallException; +import org.thoughtcrime.securesms.keyvalue.SignalStore; +import org.thoughtcrime.securesms.util.NetworkUtil; + +/** + * Represents the user's desired bandwidth mode for calls. + */ +public enum CallBandwidthMode { + LOW_ALWAYS(0), + HIGH_ON_WIFI(1), + HIGH_ALWAYS(2); + + private final int code; + + CallBandwidthMode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static CallBandwidthMode fromCode(int code) { + switch (code) { + case 1: + return HIGH_ON_WIFI; + case 2: + return HIGH_ALWAYS; + default: + return LOW_ALWAYS; + } + } +} diff --git a/app/src/main/res/layout/preference_data_and_storage_call_bandwidth_notice.xml b/app/src/main/res/layout/preference_data_and_storage_call_bandwidth_notice.xml new file mode 100644 index 0000000000..e995919918 --- /dev/null +++ b/app/src/main/res/layout/preference_data_and_storage_call_bandwidth_notice.xml @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index a56c1b8153..c302b9bdbc 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -275,6 +275,12 @@ documents + + @string/preferences_data_and_storage__never + @string/preferences_data_and_storage__cellular_only + @string/preferences_data_and_storage__wifi_and_cellular + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46512c27bd..d78228afa6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2375,7 +2375,7 @@ MMSC Password SMS delivery reports Request a delivery report for each SMS message you send - Chats and media + Data and Storage Storage Conversation length limit Keep messages @@ -2440,6 +2440,13 @@ App access Communication Chats + Manage storage + Calls + Use less data for calls + Never + WiFi and Cellular + Cellular only + Using less data may improve calls on bad networks Messages Events In-chat sounds diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 3a8279376a..9f291b0329 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -27,11 +27,11 @@ android:icon="@drawable/ic_appearance_24"/> - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file