mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Convert InternalValues to kotlin.
This commit is contained in:
@@ -115,7 +115,7 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
|
||||
}
|
||||
|
||||
fun setUseConversationItemV2Media(enabled: Boolean) {
|
||||
SignalStore.internal.setUseConversationItemV2Media(enabled)
|
||||
SignalStore.internal.useConversationItemV2Media = enabled
|
||||
refresh()
|
||||
}
|
||||
|
||||
@@ -145,25 +145,25 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
|
||||
}
|
||||
|
||||
private fun getState() = InternalSettingsState(
|
||||
seeMoreUserDetails = SignalStore.internal.recipientDetails(),
|
||||
shakeToReport = SignalStore.internal.shakeToReport(),
|
||||
gv2forceInvites = SignalStore.internal.gv2ForceInvites(),
|
||||
gv2ignoreP2PChanges = SignalStore.internal.gv2IgnoreP2PChanges(),
|
||||
allowCensorshipSetting = SignalStore.internal.allowChangingCensorshipSetting(),
|
||||
seeMoreUserDetails = SignalStore.internal.recipientDetails,
|
||||
shakeToReport = SignalStore.internal.shakeToReport,
|
||||
gv2forceInvites = SignalStore.internal.gv2ForceInvites,
|
||||
gv2ignoreP2PChanges = SignalStore.internal.gv2IgnoreP2PChanges,
|
||||
allowCensorshipSetting = SignalStore.internal.allowChangingCensorshipSetting,
|
||||
forceWebsocketMode = SignalStore.internal.isWebsocketModeForced,
|
||||
callingServer = SignalStore.internal.groupCallingServer(),
|
||||
callingAudioProcessingMethod = SignalStore.internal.callingAudioProcessingMethod(),
|
||||
callingDataMode = SignalStore.internal.callingDataMode(),
|
||||
callingDisableTelecom = SignalStore.internal.callingDisableTelecom(),
|
||||
callingEnableOboeAdm = SignalStore.internal.callingEnableOboeAdm(),
|
||||
useBuiltInEmojiSet = SignalStore.internal.forceBuiltInEmoji(),
|
||||
callingServer = SignalStore.internal.groupCallingServer,
|
||||
callingAudioProcessingMethod = SignalStore.internal.callingAudioProcessingMethod,
|
||||
callingDataMode = SignalStore.internal.callingDataMode,
|
||||
callingDisableTelecom = SignalStore.internal.callingDisableTelecom,
|
||||
callingEnableOboeAdm = SignalStore.internal.callingEnableOboeAdm,
|
||||
useBuiltInEmojiSet = SignalStore.internal.forceBuiltInEmoji,
|
||||
emojiVersion = null,
|
||||
removeSenderKeyMinimium = SignalStore.internal.removeSenderKeyMinimum(),
|
||||
delayResends = SignalStore.internal.delayResends(),
|
||||
disableStorageService = SignalStore.internal.storageServiceDisabled(),
|
||||
removeSenderKeyMinimium = SignalStore.internal.removeSenderKeyMinimum,
|
||||
delayResends = SignalStore.internal.delayResends,
|
||||
disableStorageService = SignalStore.internal.storageServiceDisabled,
|
||||
canClearOnboardingState = SignalStore.story.hasDownloadedOnboardingStory && Stories.isFeatureEnabled(),
|
||||
pnpInitialized = SignalStore.misc.hasPniInitializedDevices,
|
||||
useConversationItemV2ForMedia = SignalStore.internal.useConversationItemV2Media(),
|
||||
useConversationItemV2ForMedia = SignalStore.internal.useConversationItemV2Media,
|
||||
hasPendingOneTimeDonation = SignalStore.inAppPayments.getPendingOneTimeDonation() != null,
|
||||
hevcEncoding = SignalStore.internal.hevcEncoding,
|
||||
newCallingUi = SignalStore.internal.newCallingUi
|
||||
|
||||
@@ -96,7 +96,7 @@ class AdvancedPrivacySettingsViewModel(
|
||||
val websocketConnected: Boolean = AppDependencies.signalWebSocket.webSocketState.firstOrError().blockingGet() == WebSocketConnectionState.CONNECTED
|
||||
|
||||
return when {
|
||||
SignalStore.internal.allowChangingCensorshipSetting() -> {
|
||||
SignalStore.internal.allowChangingCensorshipSetting -> {
|
||||
CensorshipCircumventionState.AVAILABLE
|
||||
}
|
||||
isCountryCodeCensoredByDefault && enabledState == SettingsValues.CensorshipCircumventionEnabled.DISABLED -> {
|
||||
|
||||
@@ -84,7 +84,7 @@ class ConversationSettingsRepository(
|
||||
}
|
||||
}
|
||||
|
||||
fun isInternalRecipientDetailsEnabled(): Boolean = SignalStore.internal.recipientDetails()
|
||||
fun isInternalRecipientDetailsEnabled(): Boolean = SignalStore.internal.recipientDetails
|
||||
|
||||
fun hasGroups(consumer: (Boolean) -> Unit) {
|
||||
SignalExecutors.BOUNDED.execute { consumer(SignalDatabase.groups.getActiveGroupCount() > 0) }
|
||||
|
||||
@@ -107,7 +107,7 @@ class ConversationAdapterV2(
|
||||
ConversationUpdateViewHolder(view)
|
||||
}
|
||||
|
||||
if (SignalStore.internal.useConversationItemV2Media()) {
|
||||
if (SignalStore.internal.useConversationItemV2Media) {
|
||||
registerFactory(OutgoingMedia::class.java) { parent ->
|
||||
val view = CachedInflater.from(parent.context).inflate<View>(R.layout.v2_conversation_item_media_outgoing, parent, false)
|
||||
V2ConversationItemMediaViewHolder(V2ConversationItemMediaOutgoingBinding.bind(view).bridge(), this)
|
||||
|
||||
@@ -104,7 +104,7 @@ class EmojiSource(
|
||||
}
|
||||
|
||||
private fun loadRemoteBasedEmojis(): EmojiSource? {
|
||||
if (SignalStore.internal.forceBuiltInEmoji()) {
|
||||
if (SignalStore.internal.forceBuiltInEmoji) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ final class GroupManagerV2 {
|
||||
|
||||
Set<GroupCandidate> groupCandidates = groupCandidateHelper.recipientIdsToCandidates(new HashSet<>(newMembers));
|
||||
|
||||
if (SignalStore.internal().gv2ForceInvites()) {
|
||||
if (SignalStore.internal().getGv2ForceInvites()) {
|
||||
groupCandidates = GroupCandidate.withoutExpiringProfileKeyCredentials(groupCandidates);
|
||||
}
|
||||
|
||||
@@ -792,7 +792,7 @@ final class GroupManagerV2 {
|
||||
GroupCandidate self = groupCandidateHelper.recipientIdToCandidate(Recipient.self().getId());
|
||||
Set<GroupCandidate> candidates = new HashSet<>(groupCandidateHelper.recipientIdsToCandidates(members));
|
||||
|
||||
if (SignalStore.internal().gv2ForceInvites()) {
|
||||
if (SignalStore.internal().getGv2ForceInvites()) {
|
||||
Log.w(TAG, "Forcing GV2 invites due to internal setting");
|
||||
candidates = GroupCandidate.withoutExpiringProfileKeyCredentials(candidates);
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ class GroupsV2StateProcessor private constructor(
|
||||
currentLocalState: DecryptedGroup?,
|
||||
groupRecord: Optional<GroupRecord>
|
||||
): Boolean {
|
||||
if (SignalStore.internal.gv2IgnoreP2PChanges()) {
|
||||
if (SignalStore.internal.gv2IgnoreP2PChanges) {
|
||||
Log.w(TAG, "$logPrefix Ignoring P2P group change by setting")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class ResendMessageJob extends BaseJob {
|
||||
|
||||
@Override
|
||||
protected void onRun() throws Exception {
|
||||
if (SignalStore.internal().delayResends()) {
|
||||
if (SignalStore.internal().getDelayResends()) {
|
||||
Log.w(TAG, "Delaying resend by 10 sec because of an internal preference.");
|
||||
ThreadUtil.sleep(10000);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ class StorageSyncJob private constructor(parameters: Parameters) : BaseJob(param
|
||||
return
|
||||
}
|
||||
|
||||
if (SignalStore.internal.storageServiceDisabled()) {
|
||||
if (SignalStore.internal.storageServiceDisabled) {
|
||||
Log.w(TAG, "Storage service has been manually disabled. Skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.ringrtc.CallManager;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.util.Environment;
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class InternalValues extends SignalStoreValues {
|
||||
|
||||
public static final String GV2_FORCE_INVITES = "internal.gv2.force_invites";
|
||||
public static final String GV2_IGNORE_P2P_CHANGES = "internal.gv2.ignore_p2p_changes";
|
||||
public static final String RECIPIENT_DETAILS = "internal.recipient_details";
|
||||
public static final String ALLOW_CENSORSHIP_SETTING = "internal.force_censorship";
|
||||
public static final String FORCE_BUILT_IN_EMOJI = "internal.force_built_in_emoji";
|
||||
public static final String REMOVE_SENDER_KEY_MINIMUM = "internal.remove_sender_key_minimum";
|
||||
public static final String DELAY_RESENDS = "internal.delay_resends";
|
||||
public static final String CALLING_SERVER = "internal.calling_server";
|
||||
public static final String CALLING_AUDIO_PROCESSING_METHOD = "internal.calling_audio_processing_method";
|
||||
public static final String CALLING_DATA_MODE = "internal.calling_bandwidth_mode";
|
||||
public static final String CALLING_DISABLE_TELECOM = "internal.calling_disable_telecom";
|
||||
public static final String CALLING_ENABLE_OBOE_ADM = "internal.calling_enable_oboe_adm";
|
||||
public static final String SHAKE_TO_REPORT = "internal.shake_to_report";
|
||||
public static final String DISABLE_STORAGE_SERVICE = "internal.disable_storage_service";
|
||||
public static final String FORCE_WEBSOCKET_MODE = "internal.force_websocket_mode";
|
||||
public static final String LAST_SCROLL_POSITION = "internal.last_scroll_position";
|
||||
public static final String CONVERSATION_ITEM_V2_MEDIA = "internal.conversation_item_v2_media";
|
||||
public static final String FORCE_ENTER_RESTORE_V2_FLOW = "internal.force_enter_restore_v2_flow";
|
||||
public static final String WEB_SOCKET_SHADOWING_STATS = "internal.web_socket_shadowing_stats";
|
||||
public static final String ENCODE_HEVC = "internal.hevc_encoding";
|
||||
public static final String NEW_CALL_UI = "internal.new.call.ui";
|
||||
|
||||
InternalValues(KeyValueStore store) {
|
||||
super(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onFirstEverAppLaunch() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull List<String> getKeysToIncludeInBackup() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Members will not be added directly to a GV2 even if they could be.
|
||||
*/
|
||||
public synchronized boolean gv2ForceInvites() {
|
||||
return RemoteConfig.internalUser() && getBoolean(GV2_FORCE_INVITES, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signed group changes are sent P2P, if the client ignores them, it will then ask the server
|
||||
* directly which allows testing of certain testing scenarios.
|
||||
*/
|
||||
public synchronized boolean gv2IgnoreP2PChanges() {
|
||||
return RemoteConfig.internalUser() && getBoolean(GV2_IGNORE_P2P_CHANGES, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show detailed recipient info in the {@link org.thoughtcrime.securesms.components.settings.conversation.InternalConversationSettingsFragment}.
|
||||
*/
|
||||
public synchronized boolean recipientDetails() {
|
||||
return RemoteConfig.internalUser() && getBoolean(RECIPIENT_DETAILS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow changing the censorship circumvention setting regardless of network status.
|
||||
*/
|
||||
public synchronized boolean allowChangingCensorshipSetting() {
|
||||
return RemoteConfig.internalUser() && getBoolean(ALLOW_CENSORSHIP_SETTING, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the app to use the emoji that ship with the app, as opposed to the ones that were downloaded.
|
||||
*/
|
||||
public synchronized boolean forceBuiltInEmoji() {
|
||||
return RemoteConfig.internalUser() && getBoolean(FORCE_BUILT_IN_EMOJI, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the requirement that there must be two sender-key-capable recipients to use sender key
|
||||
*/
|
||||
public synchronized boolean removeSenderKeyMinimum() {
|
||||
return RemoteConfig.internalUser() && getBoolean(REMOVE_SENDER_KEY_MINIMUM, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay resending messages in response to retry receipts by 10 seconds.
|
||||
*/
|
||||
public synchronized boolean delayResends() {
|
||||
return RemoteConfig.internalUser() && getBoolean(DELAY_RESENDS, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not "shake to report" is enabled.
|
||||
*/
|
||||
public synchronized boolean shakeToReport() {
|
||||
return RemoteConfig.internalUser() && getBoolean(SHAKE_TO_REPORT, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not storage service is manually disabled.
|
||||
*/
|
||||
public synchronized boolean storageServiceDisabled() {
|
||||
return RemoteConfig.internalUser() && getBoolean(DISABLE_STORAGE_SERVICE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The selected group calling server to use.
|
||||
* <p>
|
||||
* The user must be an internal user and the setting must be one of the current set of internal servers otherwise
|
||||
* the default SFU will be returned. This ensures that if the {@link BuildConfig#SIGNAL_SFU_INTERNAL_URLS} list changes,
|
||||
* internal users cannot be left on old servers.
|
||||
*/
|
||||
public synchronized @NonNull String groupCallingServer() {
|
||||
String internalServer = RemoteConfig.internalUser() ? getString(CALLING_SERVER, Environment.Calling.defaultSfuUrl()) : null;
|
||||
if (internalServer != null && !Arrays.asList(BuildConfig.SIGNAL_SFU_INTERNAL_URLS).contains(internalServer)) {
|
||||
internalServer = null;
|
||||
}
|
||||
return internalServer != null ? internalServer : BuildConfig.SIGNAL_SFU_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting to override the default handling of hardware/software AEC.
|
||||
*/
|
||||
public synchronized CallManager.AudioProcessingMethod callingAudioProcessingMethod() {
|
||||
if (RemoteConfig.internalUser()) {
|
||||
return CallManager.AudioProcessingMethod.values()[getInteger(CALLING_AUDIO_PROCESSING_METHOD, CallManager.AudioProcessingMethod.Default.ordinal())];
|
||||
} else {
|
||||
return CallManager.AudioProcessingMethod.Default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting to override the default calling bandwidth mode.
|
||||
*/
|
||||
public synchronized CallManager.DataMode callingDataMode() {
|
||||
if (RemoteConfig.internalUser()) {
|
||||
int index = getInteger(CALLING_DATA_MODE, CallManager.DataMode.NORMAL.ordinal());
|
||||
CallManager.DataMode[] modes = CallManager.DataMode.values();
|
||||
|
||||
return index < modes.length ? modes[index] : CallManager.DataMode.NORMAL;
|
||||
} else {
|
||||
return CallManager.DataMode.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not Telecom integration is manually disabled.
|
||||
*/
|
||||
public synchronized boolean callingDisableTelecom() {
|
||||
if (RemoteConfig.internalUser()) {
|
||||
return getBoolean(CALLING_DISABLE_TELECOM, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the Oboe ADM is used.
|
||||
*/
|
||||
public synchronized boolean callingEnableOboeAdm() {
|
||||
if (RemoteConfig.internalUser()) {
|
||||
return getBoolean(CALLING_ENABLE_OBOE_ADM, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the system is forced to be in 'websocket mode', where FCM is ignored and we use a foreground service to keep the app alive.
|
||||
*/
|
||||
public boolean isWebsocketModeForced() {
|
||||
if (RemoteConfig.internalUser()) {
|
||||
return getBoolean(FORCE_WEBSOCKET_MODE, false);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setHevcEncoding(boolean enabled) {
|
||||
putBoolean(ENCODE_HEVC, enabled);
|
||||
}
|
||||
|
||||
public boolean getHevcEncoding() {
|
||||
return getBoolean(ENCODE_HEVC, false);
|
||||
}
|
||||
|
||||
public void setNewCallingUi(boolean enabled) {
|
||||
putBoolean(NEW_CALL_UI, enabled);
|
||||
}
|
||||
|
||||
public boolean getNewCallingUi() {
|
||||
return getBoolean(NEW_CALL_UI, false);
|
||||
}
|
||||
|
||||
public void setLastScrollPosition(int position) {
|
||||
putInteger(LAST_SCROLL_POSITION, position);
|
||||
}
|
||||
|
||||
public int getLastScrollPosition() {
|
||||
return getInteger(LAST_SCROLL_POSITION, 0);
|
||||
}
|
||||
|
||||
public void setUseConversationItemV2Media(boolean useConversationFragmentV2Media) {
|
||||
putBoolean(CONVERSATION_ITEM_V2_MEDIA, useConversationFragmentV2Media);
|
||||
}
|
||||
|
||||
public boolean useConversationItemV2Media() {
|
||||
return RemoteConfig.internalUser() && getBoolean(CONVERSATION_ITEM_V2_MEDIA, false);
|
||||
}
|
||||
|
||||
public synchronized void setWebSocketShadowingStats(byte[] bytes) {
|
||||
putBlob(WEB_SOCKET_SHADOWING_STATS, bytes);
|
||||
}
|
||||
|
||||
public synchronized byte[] getWebSocketShadowingStats(byte[] defaultValue) {
|
||||
return getBlob(WEB_SOCKET_SHADOWING_STATS, defaultValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package org.thoughtcrime.securesms.keyvalue
|
||||
|
||||
import org.signal.ringrtc.CallManager.AudioProcessingMethod
|
||||
import org.signal.ringrtc.CallManager.DataMode
|
||||
import org.thoughtcrime.securesms.BuildConfig
|
||||
import org.thoughtcrime.securesms.util.Environment.Calling.defaultSfuUrl
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
|
||||
class InternalValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
companion object {
|
||||
const val GV2_FORCE_INVITES: String = "internal.gv2.force_invites"
|
||||
const val GV2_IGNORE_P2P_CHANGES: String = "internal.gv2.ignore_p2p_changes"
|
||||
const val RECIPIENT_DETAILS: String = "internal.recipient_details"
|
||||
const val ALLOW_CENSORSHIP_SETTING: String = "internal.force_censorship"
|
||||
const val FORCE_BUILT_IN_EMOJI: String = "internal.force_built_in_emoji"
|
||||
const val REMOVE_SENDER_KEY_MINIMUM: String = "internal.remove_sender_key_minimum"
|
||||
const val DELAY_RESENDS: String = "internal.delay_resends"
|
||||
const val CALLING_SERVER: String = "internal.calling_server"
|
||||
const val CALLING_AUDIO_PROCESSING_METHOD: String = "internal.calling_audio_processing_method"
|
||||
const val CALLING_DATA_MODE: String = "internal.calling_bandwidth_mode"
|
||||
const val CALLING_DISABLE_TELECOM: String = "internal.calling_disable_telecom"
|
||||
const val CALLING_ENABLE_OBOE_ADM: String = "internal.calling_enable_oboe_adm"
|
||||
const val SHAKE_TO_REPORT: String = "internal.shake_to_report"
|
||||
const val DISABLE_STORAGE_SERVICE: String = "internal.disable_storage_service"
|
||||
const val FORCE_WEBSOCKET_MODE: String = "internal.force_websocket_mode"
|
||||
const val LAST_SCROLL_POSITION: String = "internal.last_scroll_position"
|
||||
const val CONVERSATION_ITEM_V2_MEDIA: String = "internal.conversation_item_v2_media"
|
||||
const val WEB_SOCKET_SHADOWING_STATS: String = "internal.web_socket_shadowing_stats"
|
||||
const val ENCODE_HEVC: String = "internal.hevc_encoding"
|
||||
const val NEW_CALL_UI: String = "internal.new.call.ui"
|
||||
}
|
||||
|
||||
public override fun onFirstEverAppLaunch() = Unit
|
||||
|
||||
public override fun getKeysToIncludeInBackup(): List<String> = emptyList()
|
||||
|
||||
/**
|
||||
* Members will not be added directly to a GV2 even if they could be.
|
||||
*/
|
||||
var gv2ForceInvites by booleanValue(GV2_FORCE_INVITES, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Signed group changes are sent P2P, if the client ignores them, it will then ask the server
|
||||
* directly which allows testing of certain testing scenarios.
|
||||
*/
|
||||
var gv2IgnoreP2PChanges by booleanValue(GV2_IGNORE_P2P_CHANGES, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Show detailed recipient info in the [org.thoughtcrime.securesms.components.settings.conversation.InternalConversationSettingsFragment].
|
||||
*/
|
||||
var recipientDetails by booleanValue(RECIPIENT_DETAILS, true).falseForExternalUsers()
|
||||
|
||||
/**
|
||||
* Allow changing the censorship circumvention setting regardless of network status.
|
||||
*/
|
||||
var allowChangingCensorshipSetting by booleanValue(ALLOW_CENSORSHIP_SETTING, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Force the app to use the emoji that ship with the app, as opposed to the ones that were downloaded.
|
||||
*/
|
||||
var forceBuiltInEmoji by booleanValue(FORCE_BUILT_IN_EMOJI, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Remove the requirement that there must be two sender-key-capable recipients to use sender key
|
||||
*/
|
||||
var removeSenderKeyMinimum by booleanValue(REMOVE_SENDER_KEY_MINIMUM, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Delay resending messages in response to retry receipts by 10 seconds.
|
||||
*/
|
||||
var delayResends by booleanValue(DELAY_RESENDS, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* Whether or not "shake to report" is enabled.
|
||||
*/
|
||||
var shakeToReport: Boolean by booleanValue(SHAKE_TO_REPORT, true).falseForExternalUsers()
|
||||
|
||||
/**
|
||||
* Whether or not storage service is manually disabled.
|
||||
*/
|
||||
var storageServiceDisabled by booleanValue(DISABLE_STORAGE_SERVICE, false).defaultForExternalUsers()
|
||||
|
||||
/**
|
||||
* The selected group calling server to use.
|
||||
*
|
||||
*
|
||||
* The user must be an internal user and the setting must be one of the current set of internal servers otherwise
|
||||
* the default SFU will be returned. This ensures that if the [BuildConfig.SIGNAL_SFU_INTERNAL_URLS] list changes,
|
||||
* internal users cannot be left on old servers.
|
||||
*/
|
||||
var groupCallingServer: String
|
||||
get() {
|
||||
var internalServer = if (RemoteConfig.internalUser) getString(CALLING_SERVER, defaultSfuUrl()) else null
|
||||
if (internalServer != null && !listOf(*BuildConfig.SIGNAL_SFU_INTERNAL_URLS).contains(internalServer)) {
|
||||
internalServer = null
|
||||
}
|
||||
return internalServer ?: BuildConfig.SIGNAL_SFU_URL
|
||||
}
|
||||
set(value) = putString(CALLING_SERVER, value)
|
||||
|
||||
/**
|
||||
* Setting to override the default handling of hardware/software AEC.
|
||||
*/
|
||||
val callingAudioProcessingMethod: AudioProcessingMethod
|
||||
get() {
|
||||
return if (RemoteConfig.internalUser) {
|
||||
val entryIndex = getInteger(CALLING_AUDIO_PROCESSING_METHOD, AudioProcessingMethod.Default.ordinal)
|
||||
AudioProcessingMethod.entries[entryIndex]
|
||||
} else {
|
||||
AudioProcessingMethod.Default
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting to override the default calling bandwidth mode.
|
||||
*/
|
||||
val callingDataMode: DataMode
|
||||
get() {
|
||||
return if (RemoteConfig.internalUser) {
|
||||
val index = getInteger(CALLING_DATA_MODE, DataMode.NORMAL.ordinal)
|
||||
val modes: Array<DataMode> = DataMode.entries.toTypedArray()
|
||||
|
||||
if (index < modes.size) modes[index] else DataMode.NORMAL
|
||||
} else {
|
||||
DataMode.NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not Telecom integration is manually disabled.
|
||||
*/
|
||||
var callingDisableTelecom by booleanValue(CALLING_DISABLE_TELECOM, true).falseForExternalUsers()
|
||||
|
||||
/**
|
||||
* Whether or not the Oboe ADM is used.
|
||||
*/
|
||||
var callingEnableOboeAdm by booleanValue(CALLING_ENABLE_OBOE_ADM, true).falseForExternalUsers()
|
||||
|
||||
/**
|
||||
* Whether or not the system is forced to be in 'websocket mode', where FCM is ignored and we use a foreground service to keep the app alive.
|
||||
*/
|
||||
var isWebsocketModeForced: Boolean by booleanValue(FORCE_WEBSOCKET_MODE, false).defaultForExternalUsers()
|
||||
|
||||
var hevcEncoding by booleanValue(ENCODE_HEVC, false).defaultForExternalUsers()
|
||||
|
||||
var newCallingUi: Boolean by booleanValue(NEW_CALL_UI, false).defaultForExternalUsers()
|
||||
|
||||
var lastScrollPosition: Int by integerValue(LAST_SCROLL_POSITION, 0).defaultForExternalUsers()
|
||||
|
||||
var useConversationItemV2Media by booleanValue(CONVERSATION_ITEM_V2_MEDIA, false).defaultForExternalUsers()
|
||||
|
||||
var webSocketShadowingStats by nullableBlobValue(WEB_SOCKET_SHADOWING_STATS, null).defaultForExternalUsers()
|
||||
|
||||
private fun <T> SignalStoreValueDelegate<T>.defaultForExternalUsers(): SignalStoreValueDelegate<T> {
|
||||
return this.withPrecondition { RemoteConfig.internalUser }
|
||||
}
|
||||
|
||||
private fun SignalStoreValueDelegate<Boolean>.falseForExternalUsers(): SignalStoreValueDelegate<Boolean> {
|
||||
return this.map { actualValue -> RemoteConfig.internalUser && actualValue }
|
||||
}
|
||||
}
|
||||
@@ -42,11 +42,25 @@ internal fun <M> SignalStoreValues.protoValue(key: String, adapter: ProtoAdapter
|
||||
return KeyValueProtoValue(key, adapter, this.store)
|
||||
}
|
||||
|
||||
internal fun <T> SignalStoreValueDelegate<T>.withPrecondition(precondition: () -> Boolean): SignalStoreValueDelegate<T> {
|
||||
return PreconditionDelegate(
|
||||
delegate = this,
|
||||
precondition = precondition
|
||||
)
|
||||
}
|
||||
|
||||
internal fun <T> SignalStoreValueDelegate<T>.map(transform: (T) -> T): SignalStoreValueDelegate<T> {
|
||||
return MappingDelegate(
|
||||
delegate = this,
|
||||
transform = transform
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin delegate that serves as a base for all other value types. This allows us to only expose this sealed
|
||||
* class to callers and protect the individual implementations as private behind the various extension functions.
|
||||
*/
|
||||
sealed class SignalStoreValueDelegate<T>(private val store: KeyValueStore) {
|
||||
sealed class SignalStoreValueDelegate<T>(val store: KeyValueStore, open val default: T) {
|
||||
|
||||
private var flow: Lazy<MutableStateFlow<T>> = lazy { MutableStateFlow(getValue(store)) }
|
||||
|
||||
@@ -69,7 +83,7 @@ sealed class SignalStoreValueDelegate<T>(private val store: KeyValueStore) {
|
||||
internal abstract fun setValue(values: KeyValueStore, value: T)
|
||||
}
|
||||
|
||||
private class LongValue(private val key: String, private val default: Long, store: KeyValueStore) : SignalStoreValueDelegate<Long>(store) {
|
||||
private class LongValue(private val key: String, default: Long, store: KeyValueStore) : SignalStoreValueDelegate<Long>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): Long {
|
||||
return values.getLong(key, default)
|
||||
}
|
||||
@@ -79,7 +93,7 @@ private class LongValue(private val key: String, private val default: Long, stor
|
||||
}
|
||||
}
|
||||
|
||||
private class BooleanValue(private val key: String, private val default: Boolean, store: KeyValueStore) : SignalStoreValueDelegate<Boolean>(store) {
|
||||
private class BooleanValue(private val key: String, default: Boolean, store: KeyValueStore) : SignalStoreValueDelegate<Boolean>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): Boolean {
|
||||
return values.getBoolean(key, default)
|
||||
}
|
||||
@@ -89,7 +103,7 @@ private class BooleanValue(private val key: String, private val default: Boolean
|
||||
}
|
||||
}
|
||||
|
||||
private class StringValue<T : String?>(private val key: String, private val default: T, store: KeyValueStore) : SignalStoreValueDelegate<T>(store) {
|
||||
private class StringValue<T : String?>(private val key: String, default: T, store: KeyValueStore) : SignalStoreValueDelegate<T>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return values.getString(key, default) as T
|
||||
@@ -100,7 +114,7 @@ private class StringValue<T : String?>(private val key: String, private val defa
|
||||
}
|
||||
}
|
||||
|
||||
private class IntValue(private val key: String, private val default: Int, store: KeyValueStore) : SignalStoreValueDelegate<Int>(store) {
|
||||
private class IntValue(private val key: String, default: Int, store: KeyValueStore) : SignalStoreValueDelegate<Int>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): Int {
|
||||
return values.getInteger(key, default)
|
||||
}
|
||||
@@ -110,7 +124,7 @@ private class IntValue(private val key: String, private val default: Int, store:
|
||||
}
|
||||
}
|
||||
|
||||
private class FloatValue(private val key: String, private val default: Float, store: KeyValueStore) : SignalStoreValueDelegate<Float>(store) {
|
||||
private class FloatValue(private val key: String, default: Float, store: KeyValueStore) : SignalStoreValueDelegate<Float>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): Float {
|
||||
return values.getFloat(key, default)
|
||||
}
|
||||
@@ -120,7 +134,7 @@ private class FloatValue(private val key: String, private val default: Float, st
|
||||
}
|
||||
}
|
||||
|
||||
private class BlobValue(private val key: String, private val default: ByteArray, store: KeyValueStore) : SignalStoreValueDelegate<ByteArray>(store) {
|
||||
private class BlobValue(private val key: String, default: ByteArray, store: KeyValueStore) : SignalStoreValueDelegate<ByteArray>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): ByteArray {
|
||||
return values.getBlob(key, default)
|
||||
}
|
||||
@@ -130,7 +144,7 @@ private class BlobValue(private val key: String, private val default: ByteArray,
|
||||
}
|
||||
}
|
||||
|
||||
private class NullableBlobValue(private val key: String, private val default: ByteArray?, store: KeyValueStore) : SignalStoreValueDelegate<ByteArray?>(store) {
|
||||
private class NullableBlobValue(private val key: String, default: ByteArray?, store: KeyValueStore) : SignalStoreValueDelegate<ByteArray?>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): ByteArray? {
|
||||
return values.getBlob(key, default)
|
||||
}
|
||||
@@ -144,7 +158,7 @@ private class KeyValueProtoValue<M>(
|
||||
private val key: String,
|
||||
private val adapter: ProtoAdapter<M>,
|
||||
store: KeyValueStore
|
||||
) : SignalStoreValueDelegate<M?>(store) {
|
||||
) : SignalStoreValueDelegate<M?>(store, null) {
|
||||
override fun getValue(values: KeyValueStore): M? {
|
||||
return if (values.containsKey(key)) {
|
||||
adapter.decode(values.getBlob(key, null))
|
||||
@@ -162,7 +176,7 @@ private class KeyValueProtoValue<M>(
|
||||
}
|
||||
}
|
||||
|
||||
private class KeyValueEnumValue<T>(private val key: String, private val default: T, private val serializer: LongSerializer<T>, store: KeyValueStore) : SignalStoreValueDelegate<T>(store) {
|
||||
private class KeyValueEnumValue<T>(private val key: String, default: T, private val serializer: LongSerializer<T>, store: KeyValueStore) : SignalStoreValueDelegate<T>(store, default) {
|
||||
override fun getValue(values: KeyValueStore): T {
|
||||
return if (values.containsKey(key)) {
|
||||
serializer.deserialize(values.getLong(key, 0))
|
||||
@@ -175,3 +189,37 @@ private class KeyValueEnumValue<T>(private val key: String, private val default:
|
||||
values.beginWrite().putLong(key, serializer.serialize(value)).apply()
|
||||
}
|
||||
}
|
||||
|
||||
private class PreconditionDelegate<T>(
|
||||
private val delegate: SignalStoreValueDelegate<T>,
|
||||
private val precondition: () -> Boolean
|
||||
) : SignalStoreValueDelegate<T>(delegate.store, delegate.default) {
|
||||
|
||||
override fun getValue(values: KeyValueStore): T {
|
||||
return if (precondition()) {
|
||||
delegate.getValue(values)
|
||||
} else {
|
||||
delegate.default
|
||||
}
|
||||
}
|
||||
|
||||
override fun setValue(values: KeyValueStore, value: T) {
|
||||
if (precondition()) {
|
||||
delegate.setValue(values, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MappingDelegate<T>(
|
||||
private val delegate: SignalStoreValueDelegate<T>,
|
||||
private val transform: (T) -> T
|
||||
) : SignalStoreValueDelegate<T>(delegate.store, delegate.default) {
|
||||
|
||||
override fun getValue(values: KeyValueStore): T {
|
||||
return transform(delegate.getValue(values))
|
||||
}
|
||||
|
||||
override fun setValue(values: KeyValueStore, value: T) {
|
||||
delegate.setValue(values, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ public final class GroupSendUtil {
|
||||
senderKeyTargets.clear();
|
||||
senderKeyTargets.addAll(registeredTargets);
|
||||
legacyTargets.clear();
|
||||
} else if (SignalStore.internal().removeSenderKeyMinimum()) {
|
||||
} else if (SignalStore.internal().getRemoveSenderKeyMinimum()) {
|
||||
Log.i(TAG, "Sender key minimum removed. Using for " + senderKeyTargets.size() + " recipients.");
|
||||
} else if (senderKeyTargets.size() < 2) {
|
||||
Log.i(TAG, "Too few sender-key-capable users (" + senderKeyTargets.size() + "). Doing all legacy sends.");
|
||||
|
||||
@@ -29,11 +29,11 @@ class DefaultWebSocketShadowingBridge(private val context: Application) : WebSoc
|
||||
private val store: InternalValues = SignalStore.internal
|
||||
|
||||
override fun writeStatsSnapshot(bytes: ByteArray) {
|
||||
store.setWebSocketShadowingStats(bytes)
|
||||
store.webSocketShadowingStats = bytes
|
||||
}
|
||||
|
||||
override fun readStatsSnapshot(): ByteArray? {
|
||||
return store.getWebSocketShadowingStats(null)
|
||||
return store.webSocketShadowingStats
|
||||
}
|
||||
|
||||
override fun triggerFailureNotification(message: String) {
|
||||
|
||||
@@ -193,7 +193,7 @@ object AndroidTelecomUtil {
|
||||
|
||||
private fun isTelecomAllowedForDevice(): Boolean {
|
||||
if (RemoteConfig.internalUser) {
|
||||
return !SignalStore.internal.callingDisableTelecom()
|
||||
return !SignalStore.internal.callingDisableTelecom
|
||||
}
|
||||
return RingRtcDynamicConfiguration.isTelecomAllowedForDevice()
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class CallLinkPreJoinActionProcessor(
|
||||
.getCallLinkAuthorizationForToday(genericServerPublicParams, callLinkSecretParams)
|
||||
|
||||
webRtcInteractor.callManager.createCallLinkCall(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
callLinkAuthCredentialPresentation.serialize(),
|
||||
callLinkRootKey,
|
||||
callLink.credentials.adminPassBytes,
|
||||
|
||||
@@ -49,7 +49,7 @@ public class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcesso
|
||||
|
||||
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
|
||||
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
|
||||
SignalStore.internal().groupCallingServer(),
|
||||
SignalStore.internal().getGroupCallingServer(),
|
||||
new byte[0],
|
||||
null,
|
||||
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
|
||||
|
||||
@@ -47,7 +47,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||
|
||||
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
|
||||
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
|
||||
SignalStore.internal().groupCallingServer(),
|
||||
SignalStore.internal().getGroupCallingServer(),
|
||||
new byte[0],
|
||||
AUDIO_LEVELS_INTERVAL,
|
||||
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
|
||||
|
||||
@@ -182,7 +182,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
protected @NonNull WebRtcServiceState handleAcceptCall(@NonNull WebRtcServiceState currentState, boolean answerWithVideo) {
|
||||
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
|
||||
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId,
|
||||
SignalStore.internal().groupCallingServer(),
|
||||
SignalStore.internal().getGroupCallingServer(),
|
||||
new byte[0],
|
||||
AUDIO_LEVELS_INTERVAL,
|
||||
RingRtcDynamicConfiguration.getAudioProcessingMethod(),
|
||||
|
||||
@@ -15,8 +15,8 @@ object RingRtcDynamicConfiguration {
|
||||
|
||||
@JvmStatic
|
||||
fun getAudioProcessingMethod(): AudioProcessingMethod {
|
||||
if (SignalStore.internal.callingAudioProcessingMethod() != AudioProcessingMethod.Default) {
|
||||
return SignalStore.internal.callingAudioProcessingMethod()
|
||||
if (SignalStore.internal.callingAudioProcessingMethod != AudioProcessingMethod.Default) {
|
||||
return SignalStore.internal.callingAudioProcessingMethod
|
||||
}
|
||||
|
||||
return if (shouldUseOboeAdm()) {
|
||||
@@ -57,7 +57,7 @@ object RingRtcDynamicConfiguration {
|
||||
@JvmStatic
|
||||
fun shouldUseOboeAdm(): Boolean {
|
||||
if (RemoteConfig.internalUser) {
|
||||
return SignalStore.internal.callingEnableOboeAdm()
|
||||
return SignalStore.internal.callingEnableOboeAdm
|
||||
}
|
||||
|
||||
// For now, only allow the Oboe ADM to be used for custom ROMS.
|
||||
|
||||
@@ -415,7 +415,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
CallLinkSecretParams.deriveFromRootKey(callLinkRootKey.getKeyBytes())
|
||||
);
|
||||
|
||||
callManager.peekCallLinkCall(SignalStore.internal().groupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, peekInfo -> {
|
||||
callManager.peekCallLinkCall(SignalStore.internal().getGroupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, peekInfo -> {
|
||||
PeekInfo info = peekInfo.getValue();
|
||||
if (info == null) {
|
||||
Log.w(TAG, "Failed to get peek info: " + peekInfo.getStatus());
|
||||
@@ -465,7 +465,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
List<GroupCall.GroupMemberInfo> members = Stream.of(GroupManager.getUuidCipherTexts(context, groupId))
|
||||
.map(entry -> new GroupCall.GroupMemberInfo(entry.getKey(), entry.getValue().serialize()))
|
||||
.toList();
|
||||
callManager.peekGroupCall(SignalStore.internal().groupCallingServer(), credential.token.getBytes(Charsets.UTF_8), members, peekInfo -> {
|
||||
callManager.peekGroupCall(SignalStore.internal().getGroupCallingServer(), credential.token.getBytes(Charsets.UTF_8), members, peekInfo -> {
|
||||
Long threadId = SignalDatabase.threads().getThreadIdFor(group.getId());
|
||||
|
||||
if (threadId != null) {
|
||||
@@ -508,7 +508,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
.map(entry -> new GroupCall.GroupMemberInfo(entry.getKey(), entry.getValue().serialize()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
callManager.peekGroupCall(SignalStore.internal().groupCallingServer(),
|
||||
callManager.peekGroupCall(SignalStore.internal().getGroupCallingServer(),
|
||||
credential.token.getBytes(Charsets.UTF_8),
|
||||
members,
|
||||
peekInfo -> receivedGroupCallPeekForRingingCheck(info, peekInfo));
|
||||
|
||||
@@ -111,7 +111,7 @@ class SignalCallLinkManager(
|
||||
|
||||
// Credential
|
||||
callManager.createCallLink(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
credentialPresentation.serialize(),
|
||||
rootKey,
|
||||
adminPassKey,
|
||||
@@ -139,7 +139,7 @@ class SignalCallLinkManager(
|
||||
): Single<ReadCallLinkResult> {
|
||||
return Single.create { emitter ->
|
||||
callManager.readCallLink(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes).serialize(),
|
||||
CallLinkRootKey(credentials.linkKeyBytes)
|
||||
) {
|
||||
@@ -165,7 +165,7 @@ class SignalCallLinkManager(
|
||||
val credentialPresentation = requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes)
|
||||
|
||||
callManager.updateCallLinkName(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
credentialPresentation.serialize(),
|
||||
CallLinkRootKey(credentials.linkKeyBytes),
|
||||
credentials.adminPassBytes,
|
||||
@@ -192,7 +192,7 @@ class SignalCallLinkManager(
|
||||
val credentialPresentation = requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes)
|
||||
|
||||
callManager.updateCallLinkRestrictions(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
credentialPresentation.serialize(),
|
||||
CallLinkRootKey(credentials.linkKeyBytes),
|
||||
credentials.adminPassBytes,
|
||||
@@ -218,7 +218,7 @@ class SignalCallLinkManager(
|
||||
val credentialPresentation = requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes)
|
||||
|
||||
callManager.deleteCallLink(
|
||||
SignalStore.internal.groupCallingServer(),
|
||||
SignalStore.internal.groupCallingServer,
|
||||
credentialPresentation.serialize(),
|
||||
CallLinkRootKey(credentials.linkKeyBytes),
|
||||
credentials.adminPassBytes
|
||||
|
||||
@@ -48,26 +48,26 @@ public final class ShakeToReport implements ShakeDetector.Listener {
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
if (!SignalStore.internal().shakeToReport()) return;
|
||||
if (!SignalStore.internal().getShakeToReport()) return;
|
||||
|
||||
detector.start(ServiceUtil.getSensorManager(application));
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
if (!SignalStore.internal().shakeToReport()) return;
|
||||
if (!SignalStore.internal().getShakeToReport()) return;
|
||||
|
||||
detector.stop();
|
||||
}
|
||||
|
||||
public void registerActivity(@NonNull AppCompatActivity activity) {
|
||||
if (!SignalStore.internal().shakeToReport()) return;
|
||||
if (!SignalStore.internal().getShakeToReport()) return;
|
||||
|
||||
this.weakActivity = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShakeDetected() {
|
||||
if (!SignalStore.internal().shakeToReport()) return;
|
||||
if (!SignalStore.internal().getShakeToReport()) return;
|
||||
|
||||
AppCompatActivity activity = weakActivity.get();
|
||||
if (activity == null) {
|
||||
|
||||
@@ -43,8 +43,8 @@ public final class NetworkUtil {
|
||||
}
|
||||
|
||||
public static @NonNull CallManager.DataMode getCallingDataMode(@NonNull Context context, @NonNull PeerConnection.AdapterType networkAdapter) {
|
||||
if (SignalStore.internal().callingDataMode() != CallManager.DataMode.NORMAL) {
|
||||
return SignalStore.internal().callingDataMode();
|
||||
if (SignalStore.internal().getCallingDataMode() != CallManager.DataMode.NORMAL) {
|
||||
return SignalStore.internal().getCallingDataMode();
|
||||
}
|
||||
|
||||
return useLowDataCalling(context, networkAdapter) ? CallManager.DataMode.LOW : CallManager.DataMode.NORMAL;
|
||||
|
||||
Reference in New Issue
Block a user