mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 20:48:43 +00:00
Convert MiscellaneousValues to kotlin.
This commit is contained in:
committed by
Cody Henthorne
parent
e6a11c1ccf
commit
e24c951d83
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -291,7 +291,7 @@ class ChangeNumberRepository(
|
||||
true
|
||||
)
|
||||
|
||||
SignalStore.misc().setPniInitializedDevices(true)
|
||||
SignalStore.misc().hasPniInitializedDevices = true
|
||||
ApplicationDependencies.getGroupsV2Authorization().clear()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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>,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -148,7 +148,7 @@ public class EditSelfProfileRepository implements EditProfileRepository {
|
||||
RegistrationUtil.maybeMarkRegistrationComplete();
|
||||
|
||||
if (avatar != null) {
|
||||
SignalStore.misc().markHasEverHadAnAvatar();
|
||||
SignalStore.misc().setHasEverHadAnAvatar(true);
|
||||
}
|
||||
|
||||
return UploadResult.SUCCESS;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user