Convert MiscellaneousValues to kotlin.

This commit is contained in:
Greyson Parrelli
2024-03-18 11:18:22 -04:00
committed by Cody Henthorne
parent e6a11c1ccf
commit e24c951d83
18 changed files with 264 additions and 397 deletions

View File

@@ -273,7 +273,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
public void checkBuildExpiration() {
if (Util.getTimeUntilBuildExpiry() <= 0 && !SignalStore.misc().isClientDeprecated()) {
Log.w(TAG, "Build expired!");
SignalStore.misc().markClientDeprecated();
SignalStore.misc().setClientDeprecated(true);
}
}

View File

@@ -152,7 +152,7 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
.setMessage(R.string.OldDeviceTransferLockedDialog__your_signal_account_has_been_transferred_to_your_new_device)
.setPositiveButton(R.string.OldDeviceTransferLockedDialog__done, (d, w) -> OldDeviceExitActivity.exit(this))
.setNegativeButton(R.string.OldDeviceTransferLockedDialog__cancel_and_activate_this_device, (d, w) -> {
SignalStore.misc().clearOldDeviceTransferLocked();
SignalStore.misc().setOldDeviceTransferLocked(false);
DeviceTransferBlockingInterceptor.getInstance().unblockNetwork();
})
.setCancelable(false)

View File

@@ -291,7 +291,7 @@ class ChangeNumberRepository(
true
)
SignalStore.misc().setPniInitializedDevices(true)
SignalStore.misc().hasPniInitializedDevices = true
ApplicationDependencies.getGroupsV2Authorization().clear()
}

View File

@@ -75,7 +75,7 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
}
fun resetPnpInitializedState() {
SignalStore.misc().setPniInitializedDevices(false)
SignalStore.misc().hasPniInitializedDevices = false
refresh()
}
@@ -159,7 +159,7 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
delayResends = SignalStore.internalValues().delayResends(),
disableStorageService = SignalStore.internalValues().storageServiceDisabled(),
canClearOnboardingState = SignalStore.storyValues().hasDownloadedOnboardingStory && Stories.isFeatureEnabled(),
pnpInitialized = SignalStore.misc().hasPniInitializedDevices(),
pnpInitialized = SignalStore.misc().hasPniInitializedDevices,
useConversationItemV2ForMedia = SignalStore.internalValues().useConversationItemV2Media(),
hasPendingOneTimeDonation = SignalStore.donationsValues().getPendingOneTimeDonation() != null
)

View File

@@ -67,7 +67,7 @@ final class OldDeviceClientTask implements ClientTask {
@Override
public void success() {
SignalStore.misc().markOldDeviceTransferLocked();
SignalStore.misc().setOldDeviceTransferLocked(true);
EventBus.getDefault().post(new Status(0, 0, 0,true));
}

View File

@@ -48,7 +48,7 @@ class PnpInitializeDevicesJob private constructor(parameters: Parameters) : Base
@JvmStatic
fun enqueueIfNecessary() {
if (SignalStore.misc().hasPniInitializedDevices() || !SignalStore.account().isRegistered || SignalStore.account().aci == null) {
if (SignalStore.misc().hasPniInitializedDevices || !SignalStore.account().isRegistered || SignalStore.account().aci == null) {
return
}
@@ -77,19 +77,19 @@ class PnpInitializeDevicesJob private constructor(parameters: Parameters) : Base
if (!TextSecurePreferences.isMultiDevice(context)) {
Log.i(TAG, "Not multi device, aborting...")
SignalStore.misc().setPniInitializedDevices(true)
SignalStore.misc().hasPniInitializedDevices = true
return
}
if (SignalStore.account().isLinkedDevice) {
Log.i(TAG, "Not primary device, aborting...")
SignalStore.misc().setPniInitializedDevices(true)
SignalStore.misc().hasPniInitializedDevices = true
return
}
ChangeNumberRepository.CHANGE_NUMBER_LOCK.lock()
try {
if (SignalStore.misc().hasPniInitializedDevices()) {
if (SignalStore.misc().hasPniInitializedDevices) {
Log.w(TAG, "We found out that things have been initialized after we got the lock! No need to do anything else.")
return
}
@@ -110,7 +110,7 @@ class PnpInitializeDevicesJob private constructor(parameters: Parameters) : Base
throw t
}
SignalStore.misc().setPniInitializedDevices(true)
SignalStore.misc().hasPniInitializedDevices = true
} finally {
ChangeNumberRepository.CHANGE_NUMBER_LOCK.unlock()
}

View File

@@ -127,7 +127,7 @@ public class RetrieveProfileAvatarJob extends BaseJob {
AvatarHelper.setAvatar(context, recipient.getId(), avatarStream);
if (recipient.isSelf()) {
SignalStore.misc().markHasEverHadAnAvatar();
SignalStore.misc().setHasEverHadAnAvatar(true);
}
} catch (AssertionError e) {
throw new IOException("Failed to copy stream. Likely a Conscrypt issue.", e);

View File

@@ -1,373 +0,0 @@
package org.thoughtcrime.securesms.keyvalue;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.components.settings.app.usernamelinks.UsernameQrCodeColorScheme;
import org.thoughtcrime.securesms.database.model.databaseprotos.PendingChangeNumberMetadata;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.impl.ChangeNumberConstraintObserver;
import java.util.Collections;
import java.util.List;
public final class MiscellaneousValues extends SignalStoreValues {
private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time";
private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time";
private static final String LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time";
private static final String USERNAME_SHOW_REMINDER = "username.show.reminder";
private static final String CLIENT_DEPRECATED = "misc.client_deprecated";
private static final String OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked";
private static final String HAS_EVER_HAD_AN_AVATAR = "misc.has.ever.had.an.avatar";
private static final String CHANGE_NUMBER_LOCK = "misc.change_number.lock";
private static final String PENDING_CHANGE_NUMBER_METADATA = "misc.pending_change_number.metadata";
private static final String CENSORSHIP_LAST_CHECK_TIME = "misc.censorship.last_check_time";
private static final String CENSORSHIP_SERVICE_REACHABLE = "misc.censorship.service_reachable";
private static final String LAST_GV2_PROFILE_CHECK_TIME = "misc.last_gv2_profile_check_time";
private static final String CDS_TOKEN = "misc.cds_token";
private static final String CDS_BLOCKED_UNTIL = "misc.cds_blocked_until";
private static final String LAST_FOREGROUND_TIME = "misc.last_foreground_time";
private static final String PNI_INITIALIZED_DEVICES = "misc.pni_initialized_devices";
private static final String LINKED_DEVICES_REMINDER = "misc.linked_devices_reminder";
private static final String HAS_LINKED_DEVICES = "misc.linked_devices_present";
private static final String USERNAME_QR_CODE_COLOR = "mis.username_qr_color_scheme";
private static final String KEYBOARD_LANDSCAPE_HEIGHT = "misc.keyboard.landscape_height";
private static final String KEYBOARD_PORTRAIT_HEIGHT = "misc.keyboard.protrait_height";
private static final String LAST_CONSISTENCY_CHECK_TIME = "misc.last_consistency_check_time";
private static final String SERVER_TIME_OFFSET = "misc.server_time_offset";
private static final String LAST_SERVER_TIME_OFFSET_UPDATE = "misc.last_server_time_offset_update";
private static final String NEEDS_USERNAME_RESTORE = "misc.needs_username_restore";
private static final String LAST_FORCED_PREKEY_REFRESH = "misc.last_forced_prekey_refresh";
private static final String LAST_CDS_FOREGROUND_SYNC = "misc.last_cds_foreground_sync";
MiscellaneousValues(@NonNull KeyValueStore store) {
super(store);
}
@Override
void onFirstEverAppLaunch() {
putLong(MESSAGE_REQUEST_ENABLE_TIME, 0);
putBoolean(NEEDS_USERNAME_RESTORE, true);
}
@Override
@NonNull List<String> getKeysToIncludeInBackup() {
return Collections.emptyList();
}
/**
* Represents the last time a _full_ prekey refreshed finished. That means signed+one-time prekeys for both ACI and PNI.
*/
public long getLastFullPrekeyRefreshTime() {
return getLong(LAST_PREKEY_REFRESH_TIME, 0);
}
public void setLastFullPrekeyRefreshTime(long time) {
putLong(LAST_PREKEY_REFRESH_TIME, time);
}
public long getMessageRequestEnableTime() {
return getLong(MESSAGE_REQUEST_ENABLE_TIME, 0);
}
public long getLastProfileRefreshTime() {
return getLong(LAST_PROFILE_REFRESH_TIME, 0);
}
public void setLastProfileRefreshTime(long time) {
putLong(LAST_PROFILE_REFRESH_TIME, time);
}
public void hideUsernameReminder() {
putBoolean(USERNAME_SHOW_REMINDER, false);
}
public boolean shouldShowUsernameReminder() {
return getBoolean(USERNAME_SHOW_REMINDER, true);
}
public boolean isClientDeprecated() {
return getBoolean(CLIENT_DEPRECATED, false);
}
public void markClientDeprecated() {
putBoolean(CLIENT_DEPRECATED, true);
}
public void clearClientDeprecated() {
putBoolean(CLIENT_DEPRECATED, false);
}
public boolean isOldDeviceTransferLocked() {
return getBoolean(OLD_DEVICE_TRANSFER_LOCKED, false);
}
public void markOldDeviceTransferLocked() {
putBoolean(OLD_DEVICE_TRANSFER_LOCKED, true);
}
public void clearOldDeviceTransferLocked() {
putBoolean(OLD_DEVICE_TRANSFER_LOCKED, false);
}
public boolean hasEverHadAnAvatar() {
return getBoolean(HAS_EVER_HAD_AN_AVATAR, false);
}
public void markHasEverHadAnAvatar() {
putBoolean(HAS_EVER_HAD_AN_AVATAR, true);
}
public boolean isChangeNumberLocked() {
return getBoolean(CHANGE_NUMBER_LOCK, false);
}
public void lockChangeNumber() {
putBoolean(CHANGE_NUMBER_LOCK, true);
ChangeNumberConstraintObserver.INSTANCE.onChange();
}
public void unlockChangeNumber() {
putBoolean(CHANGE_NUMBER_LOCK, false);
ChangeNumberConstraintObserver.INSTANCE.onChange();
}
public @Nullable PendingChangeNumberMetadata getPendingChangeNumberMetadata() {
return getObject(PENDING_CHANGE_NUMBER_METADATA, null, PendingChangeNumberMetadataSerializer.INSTANCE);
}
/** Store pending new PNI data to be applied after successful change number */
public void setPendingChangeNumberMetadata(@NonNull PendingChangeNumberMetadata metadata) {
putObject(PENDING_CHANGE_NUMBER_METADATA, metadata, PendingChangeNumberMetadataSerializer.INSTANCE);
}
/** Clear pending new PNI data after confirmed successful or failed change number */
public void clearPendingChangeNumberMetadata() {
remove(PENDING_CHANGE_NUMBER_METADATA);
}
public long getLastCensorshipServiceReachabilityCheckTime() {
return getLong(CENSORSHIP_LAST_CHECK_TIME, 0);
}
public void setLastCensorshipServiceReachabilityCheckTime(long value) {
putLong(CENSORSHIP_LAST_CHECK_TIME, value);
}
public boolean isServiceReachableWithoutCircumvention() {
return getBoolean(CENSORSHIP_SERVICE_REACHABLE, false);
}
public void setServiceReachableWithoutCircumvention(boolean value) {
putBoolean(CENSORSHIP_SERVICE_REACHABLE, value);
}
public long getLastGv2ProfileCheckTime() {
return getLong(LAST_GV2_PROFILE_CHECK_TIME, 0);
}
public void setLastGv2ProfileCheckTime(long value) {
putLong(LAST_GV2_PROFILE_CHECK_TIME, value);
}
public @Nullable byte[] getCdsToken() {
return getBlob(CDS_TOKEN, null);
}
public void setCdsToken(@Nullable byte[] token) {
getStore().beginWrite()
.putBlob(CDS_TOKEN, token)
.commit();
}
/**
* Marks the time at which we think the next CDS request will succeed. This should be taken from the service response.
*/
public void setCdsBlockedUtil(long time) {
putLong(CDS_BLOCKED_UNTIL, time);
}
/**
* Indicates that a CDS request will never succeed at the current contact count.
*/
public void markCdsPermanentlyBlocked() {
putLong(CDS_BLOCKED_UNTIL, Long.MAX_VALUE);
}
/**
* Clears any rate limiting state related to CDS.
*/
public void clearCdsBlocked() {
setCdsBlockedUtil(0);
}
/**
* Whether or not we expect the next CDS request to succeed.
*/
public boolean isCdsBlocked() {
return getCdsBlockedUtil() > 0;
}
/**
* This represents the next time we think we'll be able to make a successful CDS request. If it is before this time, we expect the request will fail
* (assuming the user still has the same number of new E164s).
*/
public long getCdsBlockedUtil() {
return getLong(CDS_BLOCKED_UNTIL, 0);
}
public long getLastForegroundTime() {
return getLong(LAST_FOREGROUND_TIME, 0);
}
public void setLastForegroundTime(long time) {
putLong(LAST_FOREGROUND_TIME, time);
}
public boolean hasPniInitializedDevices() {
return getBoolean(PNI_INITIALIZED_DEVICES, false);
}
public void setPniInitializedDevices(boolean value) {
putBoolean(PNI_INITIALIZED_DEVICES, value);
}
public void setHasLinkedDevices(boolean value) {
putBoolean(HAS_LINKED_DEVICES, value);
}
public boolean getHasLinkedDevices() {
return getBoolean(HAS_LINKED_DEVICES, false);
}
public void setShouldShowLinkedDevicesReminder(boolean value) {
putBoolean(LINKED_DEVICES_REMINDER, value);
}
public boolean getShouldShowLinkedDevicesReminder() {
return getBoolean(LINKED_DEVICES_REMINDER, false);
}
/** The color the user saved for rendering their shareable username QR code. */
public @NonNull UsernameQrCodeColorScheme getUsernameQrCodeColorScheme() {
String serialized = getString(USERNAME_QR_CODE_COLOR, null);
return UsernameQrCodeColorScheme.deserialize(serialized);
}
public void setUsernameQrCodeColorScheme(@NonNull UsernameQrCodeColorScheme color) {
putString(USERNAME_QR_CODE_COLOR, color.serialize());
}
public int getKeyboardLandscapeHeight() {
int height = (int) getLong(KEYBOARD_LANDSCAPE_HEIGHT, 0);
if (height == 0) {
//noinspection deprecation
height = PreferenceManager.getDefaultSharedPreferences(ApplicationDependencies.getApplication())
.getInt("keyboard_height_landscape", 0);
if (height > 0) {
setKeyboardLandscapeHeight(height);
}
}
return height;
}
public void setKeyboardLandscapeHeight(int height) {
putLong(KEYBOARD_LANDSCAPE_HEIGHT, height);
}
public int getKeyboardPortraitHeight() {
int height = (int) getInteger(KEYBOARD_PORTRAIT_HEIGHT, 0);
if (height == 0) {
//noinspection deprecation
height = PreferenceManager.getDefaultSharedPreferences(ApplicationDependencies.getApplication())
.getInt("keyboard_height_portrait", 0);
if (height > 0) {
setKeyboardPortraitHeight(height);
}
}
return height;
}
public void setKeyboardPortraitHeight(int height) {
putInteger(KEYBOARD_PORTRAIT_HEIGHT, height);
}
public long getLastConsistencyCheckTime() {
return getLong(LAST_CONSISTENCY_CHECK_TIME, 0);
}
public void setLastConsistencyCheckTime(long time) {
putLong(LAST_CONSISTENCY_CHECK_TIME, time);
}
/**
* Sets the last-known server time.
*/
public void setLastKnownServerTime(long serverTime, long currentTime) {
getStore()
.beginWrite()
.putLong(SERVER_TIME_OFFSET, currentTime - serverTime)
.putLong(LAST_SERVER_TIME_OFFSET_UPDATE, System.currentTimeMillis())
.apply();
}
/**
* The last-known offset between our local clock and the server. To get an estimate of the server time, take your current time and subtract this offset. e.g.
*
* estimatedServerTime = System.currentTimeMillis() - SignalStore.misc().getLastKnownServerTimeOffset()
*/
public long getLastKnownServerTimeOffset() {
return getLong(SERVER_TIME_OFFSET, 0);
}
/**
* The last time (using our local clock) we updated the server time offset returned by {@link #getLastKnownServerTimeOffset()}}.
*/
public long getLastKnownServerTimeOffsetUpdateTime() {
return getLong(LAST_SERVER_TIME_OFFSET_UPDATE, 0);
}
/**
* Whether or not we should attempt to restore the user's username and link.
*/
public boolean needsUsernameRestore() {
return getBoolean(NEEDS_USERNAME_RESTORE, false);
}
public void setNeedsUsernameRestore(boolean value) {
putBoolean(NEEDS_USERNAME_RESTORE, value);
}
/**
* Set the last time we successfully completed a forced prekey refresh.
*/
public void setLastForcedPreKeyRefresh(long time) {
putLong(LAST_FORCED_PREKEY_REFRESH, time);
}
/**
* Get the last time we successfully completed a forced prekey refresh.
*/
public long getLastForcedPreKeyRefresh() {
return getLong(LAST_FORCED_PREKEY_REFRESH, 0);
}
/**
* How long it's been since the last foreground CDS sync, which we do in response to new threads being created.
*/
public long getLastCdsForegroundSyncTime() {
return getLong(LAST_CDS_FOREGROUND_SYNC, 0);
}
/**
* Set the last time we did a foreground CDS sync.
*/
public void setLastCdsForegroundSyncTime(long time) {
putLong(LAST_CDS_FOREGROUND_SYNC, time);
}
}

View File

@@ -0,0 +1,226 @@
package org.thoughtcrime.securesms.keyvalue
import org.thoughtcrime.securesms.components.settings.app.usernamelinks.UsernameQrCodeColorScheme
import org.thoughtcrime.securesms.database.model.databaseprotos.PendingChangeNumberMetadata
import org.thoughtcrime.securesms.jobmanager.impl.ChangeNumberConstraintObserver
internal class MiscellaneousValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) {
companion object {
private const val LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time"
private const val MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time"
private const val LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time"
private const val CLIENT_DEPRECATED = "misc.client_deprecated"
private const val OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked"
private const val HAS_EVER_HAD_AN_AVATAR = "misc.has.ever.had.an.avatar"
private const val CHANGE_NUMBER_LOCK = "misc.change_number.lock"
private const val PENDING_CHANGE_NUMBER_METADATA = "misc.pending_change_number.metadata"
private const val CENSORSHIP_LAST_CHECK_TIME = "misc.censorship.last_check_time"
private const val CENSORSHIP_SERVICE_REACHABLE = "misc.censorship.service_reachable"
private const val LAST_GV2_PROFILE_CHECK_TIME = "misc.last_gv2_profile_check_time"
private const val CDS_TOKEN = "misc.cds_token"
private const val CDS_BLOCKED_UNTIL = "misc.cds_blocked_until"
private const val LAST_FOREGROUND_TIME = "misc.last_foreground_time"
private const val PNI_INITIALIZED_DEVICES = "misc.pni_initialized_devices"
private const val LINKED_DEVICES_REMINDER = "misc.linked_devices_reminder"
private const val HAS_LINKED_DEVICES = "misc.linked_devices_present"
private const val USERNAME_QR_CODE_COLOR = "mis.username_qr_color_scheme"
private const val KEYBOARD_LANDSCAPE_HEIGHT = "misc.keyboard.landscape_height"
private const val KEYBOARD_PORTRAIT_HEIGHT = "misc.keyboard.protrait_height"
private const val LAST_CONSISTENCY_CHECK_TIME = "misc.last_consistency_check_time"
private const val SERVER_TIME_OFFSET = "misc.server_time_offset"
private const val LAST_SERVER_TIME_OFFSET_UPDATE = "misc.last_server_time_offset_update"
private const val NEEDS_USERNAME_RESTORE = "misc.needs_username_restore"
private const val LAST_FORCED_PREKEY_REFRESH = "misc.last_forced_prekey_refresh"
private const val LAST_CDS_FOREGROUND_SYNC = "misc.last_cds_foreground_sync"
}
public override fun onFirstEverAppLaunch() {
putLong(MESSAGE_REQUEST_ENABLE_TIME, 0)
putBoolean(NEEDS_USERNAME_RESTORE, true)
}
public override fun getKeysToIncludeInBackup(): List<String> {
return emptyList()
}
/**
* Represents the last time a _full_ prekey refreshed finished. That means signed+one-time prekeys for both ACI and PNI.
*/
var lastFullPrekeyRefreshTime by longValue(LAST_PREKEY_REFRESH_TIME, 0)
val messageRequestEnableTime by longValue(MESSAGE_REQUEST_ENABLE_TIME, 0)
/**
* Get the last time we successfully completed a forced prekey refresh.
*/
var lastForcedPreKeyRefresh by longValue(LAST_FORCED_PREKEY_REFRESH, 0)
/**
* The last time we completed a routine profile refresh.
*/
var lastProfileRefreshTime by longValue(LAST_PROFILE_REFRESH_TIME, 0)
/**
* Whether or not the client is currently in a 'deprecated' state, disallowing network access.
*/
var isClientDeprecated: Boolean by booleanValue(CLIENT_DEPRECATED, false)
/**
* Whether or not we've locked the device after they've transferred to a new one.
*/
var isOldDeviceTransferLocked by booleanValue(OLD_DEVICE_TRANSFER_LOCKED, false)
/**
* Whether or not the user has ever had an avatar.
*/
var hasEverHadAnAvatar by booleanValue(HAS_EVER_HAD_AN_AVATAR, false)
val isChangeNumberLocked: Boolean by booleanValue(CHANGE_NUMBER_LOCK, false)
fun lockChangeNumber() {
putBoolean(CHANGE_NUMBER_LOCK, true)
ChangeNumberConstraintObserver.onChange()
}
fun unlockChangeNumber() {
putBoolean(CHANGE_NUMBER_LOCK, false)
ChangeNumberConstraintObserver.onChange()
}
val pendingChangeNumberMetadata: PendingChangeNumberMetadata?
get() = getObject(PENDING_CHANGE_NUMBER_METADATA, null, PendingChangeNumberMetadataSerializer)
/** Store pending new PNI data to be applied after successful change number */
fun setPendingChangeNumberMetadata(metadata: PendingChangeNumberMetadata) {
putObject(PENDING_CHANGE_NUMBER_METADATA, metadata, PendingChangeNumberMetadataSerializer)
}
/** Clear pending new PNI data after confirmed successful or failed change number */
fun clearPendingChangeNumberMetadata() {
remove(PENDING_CHANGE_NUMBER_METADATA)
}
/**
* The last time we checked if the service was reachable without censorship circumvention.
*/
var lastCensorshipServiceReachabilityCheckTime by longValue(CENSORSHIP_LAST_CHECK_TIME, 0)
/**
* Whether or not the service is reachable without censorship circumvention.
*/
var isServiceReachableWithoutCircumvention by booleanValue(CENSORSHIP_SERVICE_REACHABLE, false)
/**
* The last time we did a routing check to see if our GV2 groups have the latest version of our profile key.
*/
var lastGv2ProfileCheckTime by longValue(LAST_GV2_PROFILE_CHECK_TIME, 0)
/**
* The CDS token that is used for rate-limiting.
*/
var cdsToken by nullableBlobValue(CDS_TOKEN, null)
/**
* Indicates that a CDS request will never succeed at the current contact count.
*/
fun markCdsPermanentlyBlocked() {
putLong(CDS_BLOCKED_UNTIL, Long.MAX_VALUE)
}
/**
* Clears any rate limiting state related to CDS.
*/
fun clearCdsBlocked() {
cdsBlockedUtil = 0
}
/** Whether or not we expect the next CDS request to succeed.*/
val isCdsBlocked: Boolean
get() = cdsBlockedUtil > 0
/**
* This represents the next time we think we'll be able to make a successful CDS request. If it is before this time, we expect the request will fail
* (assuming the user still has the same number of new E164s).
*/
var cdsBlockedUtil by longValue(CDS_BLOCKED_UNTIL, 0)
/**
* The last time the user foregrounded the app.
*/
var lastForegroundTime by longValue(LAST_FOREGROUND_TIME, 0)
/**
* Whether or not we've done the initial "PNP Hello World" dance.
*/
var hasPniInitializedDevices by booleanValue(PNI_INITIALIZED_DEVICES, false)
/**
* Whether or not the user has linked devices.
*/
var hasLinkedDevices by booleanValue(HAS_LINKED_DEVICES, false)
/**
* Whether or not we should show a reminder for the user to relink their devices after re-registering.
*/
var shouldShowLinkedDevicesReminder by booleanValue(LINKED_DEVICES_REMINDER, false)
/**
* The color the user saved for rendering their shareable username QR code.
*/
var usernameQrCodeColorScheme: UsernameQrCodeColorScheme
get() {
val serialized = getString(USERNAME_QR_CODE_COLOR, null)
return UsernameQrCodeColorScheme.deserialize(serialized)
}
set(color) {
putString(USERNAME_QR_CODE_COLOR, color.serialize())
}
/**
* Cached landscape keyboard height.
*/
var keyboardLandscapeHeight by integerValue(KEYBOARD_LANDSCAPE_HEIGHT, 0)
/**
* Cached portrait keyboard height.
*/
var keyboardPortraitHeight by integerValue(KEYBOARD_PORTRAIT_HEIGHT, 0)
/**
* The last time we ran an account consistency check via [org.thoughtcrime.securesms.jobs.AccountConsistencyWorkerJob]
*/
var lastConsistencyCheckTime by longValue(LAST_CONSISTENCY_CHECK_TIME, 0)
/**
* The last-known offset between our local clock and the server. To get an estimate of the server time, take your current time and subtract this offset. e.g.
*
* estimatedServerTime = System.currentTimeMillis() - SignalStore.misc().getLastKnownServerTimeOffset()
*/
val lastKnownServerTimeOffset by longValue(SERVER_TIME_OFFSET, 0)
/**
* The last time (using our local clock) we updated the server time offset returned by [.getLastKnownServerTimeOffset]}.
*/
val lastKnownServerTimeOffsetUpdateTime by longValue(LAST_SERVER_TIME_OFFSET_UPDATE, 0)
/**
* Sets the last-known server time.
*/
fun setLastKnownServerTime(serverTime: Long, currentTime: Long) {
store
.beginWrite()
.putLong(SERVER_TIME_OFFSET, currentTime - serverTime)
.putLong(LAST_SERVER_TIME_OFFSET_UPDATE, System.currentTimeMillis())
.apply()
}
/**
* Whether or not we should attempt to restore the user's username and link.
*/
var needsUsernameRestore by booleanValue(NEEDS_USERNAME_RESTORE, false)
/**
* How long it's been since the last foreground CDS sync, which we do in response to new threads being created.
*/
var lastCdsForegroundSyncTime by longValue(LAST_CDS_FOREGROUND_SYNC, 0)
}

View File

@@ -28,6 +28,10 @@ internal fun SignalStoreValues.blobValue(key: String, default: ByteArray): Signa
return BlobValue(key, default, this.store)
}
internal fun SignalStoreValues.nullableBlobValue(key: String, default: ByteArray?): SignalStoreValueDelegate<ByteArray?> {
return NullableBlobValue(key, default, this.store)
}
internal fun <T : Any?> SignalStoreValues.enumValue(key: String, default: T, serializer: LongSerializer<T>): SignalStoreValueDelegate<T> {
return KeyValueEnumValue(key, default, serializer, this.store)
}
@@ -114,6 +118,16 @@ 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) {
override fun getValue(values: KeyValueStore): ByteArray? {
return values.getBlob(key, default)
}
override fun setValue(values: KeyValueStore, value: ByteArray?) {
values.beginWrite().putBlob(key, value).apply()
}
}
private class KeyValueProtoValue<M>(
private val key: String,
private val adapter: ProtoAdapter<M>,

View File

@@ -405,13 +405,13 @@ public final class Megaphones {
}
private static boolean shouldShowAddAProfilePhotoMegaphone(@NonNull Context context) {
if (SignalStore.misc().hasEverHadAnAvatar()) {
if (SignalStore.misc().getHasEverHadAnAvatar()) {
return false;
}
boolean hasAnAvatar = AvatarHelper.hasAvatar(context, Recipient.self().getId());
if (hasAnAvatar) {
SignalStore.misc().markHasEverHadAnAvatar();
SignalStore.misc().setHasEverHadAnAvatar(true);
return false;
}

View File

@@ -135,7 +135,7 @@ public class OnboardingMegaphoneView extends FrameLayout {
data.add(TYPE_INVITE);
}
if (SignalStore.onboarding().shouldShowAddPhoto() && !SignalStore.misc().hasEverHadAnAvatar()) {
if (SignalStore.onboarding().shouldShowAddPhoto() && !SignalStore.misc().getHasEverHadAnAvatar()) {
data.add(TYPE_ADD_PHOTO);
}

View File

@@ -167,7 +167,7 @@ public class ApplicationMigrations {
return;
} else {
Log.d(TAG, "About to update. Clearing deprecation flag.");
SignalStore.misc().clearClientDeprecated();
SignalStore.misc().setClientDeprecated(false);
}
final int lastSeenVersion = TextSecurePreferences.getAppMigrationVersion(context);

View File

@@ -23,7 +23,7 @@ public final class RemoteDeprecationDetectorInterceptor implements Interceptor {
if (response.code() == 499 && !SignalStore.misc().isClientDeprecated()) {
Log.w(TAG, "Received 499. Client version is deprecated.");
SignalStore.misc().markClientDeprecated();
SignalStore.misc().setClientDeprecated(true);
}
return response;

View File

@@ -148,7 +148,7 @@ public class EditSelfProfileRepository implements EditProfileRepository {
RegistrationUtil.maybeMarkRegistrationComplete();
if (avatar != null) {
SignalStore.misc().markHasEverHadAnAvatar();
SignalStore.misc().setHasEverHadAnAvatar(true);
}
return UploadResult.SUCCESS;

View File

@@ -59,7 +59,7 @@ final class EditProfileRepository {
try {
ProfileUtil.uploadProfileWithAvatar(new StreamDetails(new ByteArrayInputStream(data), contentType, data.length));
AvatarHelper.setAvatar(context, Recipient.self().getId(), new ByteArrayInputStream(data));
SignalStore.misc().markHasEverHadAnAvatar();
SignalStore.misc().setHasEverHadAnAvatar(true);
ApplicationDependencies.getJobManager().add(new MultiDeviceProfileContentUpdateJob());
callback.accept(Result.SUCCESS);

View File

@@ -130,7 +130,7 @@ object UsernameRepository {
@WorkerThread
@JvmStatic
fun reclaimUsernameIfNecessary(): UsernameReclaimResult {
if (!SignalStore.misc().needsUsernameRestore()) {
if (!SignalStore.misc().needsUsernameRestore) {
Log.d(TAG, "[reclaimUsernameIfNecessary] No need to restore username. Skipping.")
return UsernameReclaimResult.SUCCESS
}
@@ -140,7 +140,7 @@ object UsernameRepository {
if (username == null || link == null) {
Log.d(TAG, "[reclaimUsernameIfNecessary] No username or link to restore. Skipping.")
SignalStore.misc().setNeedsUsernameRestore(false)
SignalStore.misc().needsUsernameRestore = false
return UsernameReclaimResult.SUCCESS
}
@@ -149,13 +149,13 @@ object UsernameRepository {
when (result) {
UsernameReclaimResult.SUCCESS -> {
Log.i(TAG, "[reclaimUsernameIfNecessary] Successfully reclaimed username and link.")
SignalStore.misc().setNeedsUsernameRestore(false)
SignalStore.misc().needsUsernameRestore = false
}
UsernameReclaimResult.PERMANENT_ERROR -> {
Log.w(TAG, "[reclaimUsernameIfNecessary] Permanently failed to reclaim username and link. User will see an error.")
SignalStore.account().usernameSyncState = AccountValues.UsernameSyncState.USERNAME_AND_LINK_CORRUPTED
SignalStore.misc().setNeedsUsernameRestore(false)
SignalStore.misc().needsUsernameRestore = false
}
UsernameReclaimResult.NETWORK_ERROR -> {

View File

@@ -25,7 +25,7 @@ object VersionTracker {
if (currentVersionCode != lastVersionCode) {
Log.i(TAG, "Upgraded from $lastVersionCode to $currentVersionCode")
SignalStore.misc().clearClientDeprecated()
SignalStore.misc().isClientDeprecated = false
val jobChain = listOf(RemoteConfigRefreshJob(), RefreshAttributesJob())
ApplicationDependencies.getJobManager().startChain(jobChain).enqueue()
RetrieveRemoteAnnouncementsJob.enqueue(true)