kopia lustrzana https://github.com/ryukoposting/Signal-Android
Migrate local account data into SignalStore.
rodzic
87f175a96b
commit
8aea20f147
|
@ -159,7 +159,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
|||
.addNonBlocking(this::cleanAvatarStorage)
|
||||
.addNonBlocking(this::initializeRevealableMessageManager)
|
||||
.addNonBlocking(this::initializePendingRetryReceiptManager)
|
||||
.addNonBlocking(this::initializeGcmCheck)
|
||||
.addNonBlocking(this::initializeFcmCheck)
|
||||
.addNonBlocking(this::initializeSignedPreKeyCheck)
|
||||
.addNonBlocking(this::initializePeriodicTasks)
|
||||
.addNonBlocking(this::initializeCircumvention)
|
||||
|
@ -300,11 +300,11 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
|||
}
|
||||
}
|
||||
|
||||
private void initializeGcmCheck() {
|
||||
if (TextSecurePreferences.isPushRegistered(this)) {
|
||||
long nextSetTime = TextSecurePreferences.getFcmTokenLastSetTime(this) + TimeUnit.HOURS.toMillis(6);
|
||||
private void initializeFcmCheck() {
|
||||
if (SignalStore.account().isRegistered()) {
|
||||
long nextSetTime = SignalStore.account().getFcmTokenLastSetTime() + TimeUnit.HOURS.toMillis(6);
|
||||
|
||||
if (TextSecurePreferences.getFcmToken(this) == null || nextSetTime <= System.currentTimeMillis()) {
|
||||
if (SignalStore.account().getFcmToken() == null || nextSetTime <= System.currentTimeMillis()) {
|
||||
ApplicationDependencies.getJobManager().add(new FcmRefreshJob());
|
||||
}
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
|||
|
||||
@WorkerThread
|
||||
private void initializeCircumvention() {
|
||||
if (ApplicationDependencies.getSignalServiceNetworkAccess().isCensored(ApplicationContext.this)) {
|
||||
if (ApplicationDependencies.getSignalServiceNetworkAccess().isCensored()) {
|
||||
try {
|
||||
ProviderInstaller.installIfNeeded(ApplicationContext.this);
|
||||
} catch (Throwable t) {
|
||||
|
|
|
@ -191,7 +191,6 @@ public class DeviceActivity extends PassphraseRequiredActivity
|
|||
Optional<byte[]> profileKey = Optional.of(ProfileKeyUtil.getProfileKey(getContext()));
|
||||
|
||||
TextSecurePreferences.setMultiDevice(DeviceActivity.this, true);
|
||||
TextSecurePreferences.setIsUnidentifiedDeliveryEnabled(context, false);
|
||||
accountManager.addDevice(ephemeralId, publicKey, identityKeyPair, profileKey, verificationCode);
|
||||
|
||||
return SUCCESS;
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.conversation.ConversationIntents;
|
|||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -67,7 +68,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
|||
} else {
|
||||
Log.i(TAG, "[onContactSelected] Maybe creating a new recipient.");
|
||||
|
||||
if (TextSecurePreferences.isPushRegistered(this) && NetworkConstraint.isMet(this)) {
|
||||
if (SignalStore.account().isRegistered() && NetworkConstraint.isMet(this)) {
|
||||
Log.i(TAG, "[onContactSelected] Doing contact refresh.");
|
||||
|
||||
AlertDialog progress = SimpleProgressDialog.show(this);
|
||||
|
|
|
@ -84,7 +84,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
|||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (networkAccess.isCensored(this)) {
|
||||
if (networkAccess.isCensored()) {
|
||||
ApplicationDependencies.getJobManager().add(new PushNotificationReceiveJob());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ public class VerifyIdentityActivity extends PassphraseRequiredActivity implement
|
|||
extras.putParcelable(VerifyDisplayFragment.RECIPIENT_ID, getIntent().getParcelableExtra(RECIPIENT_EXTRA));
|
||||
extras.putParcelable(VerifyDisplayFragment.REMOTE_IDENTITY, getIntent().getParcelableExtra(IDENTITY_EXTRA));
|
||||
extras.putParcelable(VerifyDisplayFragment.LOCAL_IDENTITY, new IdentityKeyParcelable(IdentityKeyUtil.getIdentityKey(this)));
|
||||
extras.putString(VerifyDisplayFragment.LOCAL_NUMBER, TextSecurePreferences.getLocalNumber(this));
|
||||
extras.putString(VerifyDisplayFragment.LOCAL_NUMBER, Recipient.self().requireE164());
|
||||
extras.putBoolean(VerifyDisplayFragment.VERIFIED_STATE, getIntent().getBooleanExtra(VERIFIED_EXTRA, false));
|
||||
|
||||
scanFragment.setScanListener(this);
|
||||
|
@ -326,12 +326,12 @@ public class VerifyIdentityActivity extends PassphraseRequiredActivity implement
|
|||
if (FeatureFlags.verifyV2() && resolved.getAci().isPresent()) {
|
||||
Log.i(TAG, "Using UUID (version 2).");
|
||||
version = 2;
|
||||
localId = TextSecurePreferences.getLocalAci(requireContext()).toByteArray();
|
||||
localId = Recipient.self().requireAci().toByteArray();
|
||||
remoteId = resolved.requireAci().toByteArray();
|
||||
} else if (!FeatureFlags.verifyV2() && resolved.getE164().isPresent()) {
|
||||
Log.i(TAG, "Using E164 (version 1).");
|
||||
version = 1;
|
||||
localId = TextSecurePreferences.getLocalNumber(requireContext()).getBytes();
|
||||
localId = Recipient.self().requireE164().getBytes();
|
||||
remoteId = resolved.requireE164().getBytes();
|
||||
} else {
|
||||
Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getAci().isPresent(), resolved.getE164().isPresent()));
|
||||
|
|
|
@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
@SuppressLint("BatteryLife")
|
||||
|
@ -31,18 +32,13 @@ public class DozeReminder extends Reminder {
|
|||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
setDismissListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextSecurePreferences.setPromptedOptimizeDoze(context, true);
|
||||
}
|
||||
});
|
||||
setDismissListener(v -> TextSecurePreferences.setPromptedOptimizeDoze(context, true));
|
||||
}
|
||||
|
||||
public static boolean isEligible(Context context) {
|
||||
return TextSecurePreferences.isFcmDisabled(context) &&
|
||||
return !SignalStore.account().isFcmEnabled() &&
|
||||
!TextSecurePreferences.hasPromptedOptimizeDoze(context) &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
Build.VERSION.SDK_INT >= 23 &&
|
||||
!((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isIgnoringBatteryOptimizations(context.getPackageName());
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.components.reminder;
|
|||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -21,6 +22,6 @@ public class PushRegistrationReminder extends Reminder {
|
|||
}
|
||||
|
||||
public static boolean isEligible(Context context) {
|
||||
return !TextSecurePreferences.isPushRegistered(context);
|
||||
return !SignalStore.account().isRegistered();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
|||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import java.util.Objects
|
||||
|
||||
private val TAG: String = Log.tag(ChangeNumberLockActivity::class.java)
|
||||
|
@ -53,11 +52,11 @@ class ChangeNumberLockActivity : PassphraseRequiredActivity() {
|
|||
disposables.add(
|
||||
changeNumberRepository.whoAmI()
|
||||
.flatMap { whoAmI ->
|
||||
if (Objects.equals(whoAmI.number, TextSecurePreferences.getLocalNumber(this))) {
|
||||
if (Objects.equals(whoAmI.number, SignalStore.account().e164)) {
|
||||
Log.i(TAG, "Local and remote numbers match, nothing needs to be done.")
|
||||
Single.just(false)
|
||||
} else {
|
||||
Log.i(TAG, "Local (${TextSecurePreferences.getLocalNumber(this)}) and remote (${whoAmI.number}) numbers do not match, updating local.")
|
||||
Log.i(TAG, "Local (${SignalStore.account().e164}) and remote (${whoAmI.number}) numbers do not match, updating local.")
|
||||
changeNumberRepository.changeLocalNumber(whoAmI.number)
|
||||
.map { true }
|
||||
}
|
||||
|
@ -72,7 +71,7 @@ class ChangeNumberLockActivity : PassphraseRequiredActivity() {
|
|||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.ChangeNumberLockActivity__change_status_confirmed)
|
||||
.setMessage(getString(R.string.ChangeNumberLockActivity__your_number_has_been_confirmed_as_s, PhoneNumberFormatter.prettyPrint(TextSecurePreferences.getLocalNumber(this))))
|
||||
.setMessage(getString(R.string.ChangeNumberLockActivity__your_number_has_been_confirmed_as_s, PhoneNumberFormatter.prettyPrint(SignalStore.account().e164!!)))
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
startActivity(MainActivity.clearTop(this))
|
||||
finish()
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.pin.KbsRepository
|
|||
import org.thoughtcrime.securesms.pin.KeyBackupSystemWrongPinException
|
||||
import org.thoughtcrime.securesms.pin.TokenData
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountRepository
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.KbsPinData
|
||||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
|
@ -62,7 +61,7 @@ class ChangeNumberRepository(private val context: Context) {
|
|||
fun changeLocalNumber(e164: String): Single<Unit> {
|
||||
DatabaseFactory.getRecipientDatabase(context).updateSelfPhone(e164)
|
||||
|
||||
TextSecurePreferences.setLocalNumber(context, e164)
|
||||
SignalStore.account().setE164(e164)
|
||||
|
||||
ApplicationDependencies.closeConnections()
|
||||
ApplicationDependencies.getIncomingMessageObserver()
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.thoughtcrime.securesms.registration.VerifyProcessor
|
|||
import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewModel
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
||||
import org.thoughtcrime.securesms.util.DefaultValueLiveData
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
||||
import java.util.Objects
|
||||
|
@ -167,8 +166,8 @@ class ChangeNumberViewModel(
|
|||
|
||||
override fun <T : ViewModel?> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
|
||||
val context: Application = ApplicationDependencies.getApplication()
|
||||
val localNumber: String = TextSecurePreferences.getLocalNumber(context)
|
||||
val password: String = TextSecurePreferences.getPushServerPassword(context)
|
||||
val localNumber: String = SignalStore.account().e164!!
|
||||
val password: String = SignalStore.account().servicePassword!!
|
||||
|
||||
val viewModel = ChangeNumberViewModel(
|
||||
localNumber = localNumber,
|
||||
|
|
|
@ -18,11 +18,11 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
|||
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
|
||||
class AdvancedPrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__advanced) {
|
||||
|
@ -168,7 +168,7 @@ class AdvancedPrivacySettingsFragment : DSLSettingsFragment(R.string.preferences
|
|||
|
||||
private fun getPushToggleSummary(isPushEnabled: Boolean): String {
|
||||
return if (isPushEnabled) {
|
||||
PhoneNumberFormatter.prettyPrint(TextSecurePreferences.getLocalNumber(requireContext()))
|
||||
PhoneNumberFormatter.prettyPrint(SignalStore.account().e164!!)
|
||||
} else {
|
||||
getString(R.string.preferences__free_private_messages_and_calls)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class AdvancedPrivacySettingsRepository(private val context: Context) {
|
|||
} catch (e: AuthorizationFailedException) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
if (!TextSecurePreferences.isFcmDisabled(context)) {
|
||||
if (SignalStore.account().fcmEnabled) {
|
||||
Tasks.await(FirebaseInstallations.getInstance().delete())
|
||||
}
|
||||
DisablePushMessagesResult.SUCCESS
|
||||
|
|
|
@ -28,7 +28,7 @@ class AdvancedPrivacySettingsViewModel(
|
|||
repository.disablePushMessages {
|
||||
when (it) {
|
||||
AdvancedPrivacySettingsRepository.DisablePushMessagesResult.SUCCESS -> {
|
||||
TextSecurePreferences.setPushRegistered(ApplicationDependencies.getApplication(), false)
|
||||
SignalStore.account().setRegistered(false)
|
||||
SignalStore.registrationValues().clearRegistrationComplete()
|
||||
SignalStore.registrationValues().clearHasUploadedProfile()
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class AdvancedPrivacySettingsViewModel(
|
|||
}
|
||||
|
||||
private fun getState() = AdvancedPrivacySettingsState(
|
||||
isPushEnabled = TextSecurePreferences.isPushRegistered(ApplicationDependencies.getApplication()),
|
||||
isPushEnabled = SignalStore.account().isRegistered,
|
||||
alwaysRelayCalls = TextSecurePreferences.isTurnOnly(ApplicationDependencies.getApplication()),
|
||||
showSealedSenderStatusIcon = TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(
|
||||
ApplicationDependencies.getApplication()
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
|
|||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -43,7 +44,7 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
|
||||
Context context = getContext();
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.i(TAG, "Not push registered. Just syncing contact info.");
|
||||
DirectoryHelper.syncRecipientInfoWithSystemContacts(context);
|
||||
return;
|
||||
|
|
|
@ -82,7 +82,7 @@ public class DirectoryHelper {
|
|||
|
||||
@WorkerThread
|
||||
public static void refreshDirectory(@NonNull Context context, boolean notifyOfNewUsers) throws IOException {
|
||||
if (TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) {
|
||||
if (TextUtils.isEmpty(SignalStore.account().getE164())) {
|
||||
Log.w(TAG, "Have not yet set our own local number. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1853,7 +1853,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
|||
} else if (ServiceOutageReminder.isEligible(this)) {
|
||||
ApplicationDependencies.getJobManager().add(new ServiceOutageDetectionJob());
|
||||
reminderView.get().showReminder(new ServiceOutageReminder(this));
|
||||
} else if (TextSecurePreferences.isPushRegistered(this) &&
|
||||
} else if (SignalStore.account().isRegistered() &&
|
||||
TextSecurePreferences.isShowInviteReminders(this) &&
|
||||
!isSecureText &&
|
||||
inviteReminder.isPresent() &&
|
||||
|
@ -2736,14 +2736,6 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
|||
return record.isPresent() && record.get().isActive();
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean isSelfConversation() {
|
||||
if (!TextSecurePreferences.isPushRegistered(this)) return false;
|
||||
if (recipient.get().isGroup()) return false;
|
||||
|
||||
return recipient.get().isSelf();
|
||||
}
|
||||
|
||||
private boolean isGroupConversation() {
|
||||
return getRecipient() != null && getRecipient().isGroup();
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ public final class ConversationUpdateItem extends FrameLayout
|
|||
|
||||
int text = 0;
|
||||
if (Util.hasItems(acis)) {
|
||||
if (acis.contains(TextSecurePreferences.getLocalAci(getContext()))) {
|
||||
if (acis.contains(Recipient.self().requireAci())) {
|
||||
text = R.string.ConversationUpdateItem_return_to_call;
|
||||
} else if (GroupCallUpdateDetailsUtil.parse(conversationMessage.getMessageRecord().getBody()).getIsCallFull()) {
|
||||
text = R.string.ConversationUpdateItem_call_is_full;
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
|||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityStoreRecord;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
|
@ -57,7 +58,7 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore {
|
|||
|
||||
@Override
|
||||
public int getLocalRegistrationId() {
|
||||
return TextSecurePreferences.getLocalRegistrationId(context);
|
||||
return SignalStore.account().getRegistrationId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,8 +123,10 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore {
|
|||
|
||||
@Override
|
||||
public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) {
|
||||
boolean isSelf = address.getName().equals(TextSecurePreferences.getLocalAci(context).toString()) ||
|
||||
address.getName().equals(TextSecurePreferences.getLocalNumber(context));
|
||||
Recipient self = Recipient.self();
|
||||
|
||||
boolean isSelf = address.getName().equals(self.requireAci().toString()) ||
|
||||
address.getName().equals(self.requireE164());
|
||||
|
||||
if (isSelf) {
|
||||
return identityKey.equals(IdentityKeyUtil.getIdentityKey(context));
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.database.Cursor;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabaseHook;
|
||||
import net.zetetic.database.sqlcipher.SQLiteOpenHelper;
|
||||
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
|
@ -15,8 +14,8 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
|
||||
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider;
|
||||
import org.thoughtcrime.securesms.keyvalue.KeyValueDataSet;
|
||||
import org.thoughtcrime.securesms.keyvalue.KeyValuePersistentStorage;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
@ -27,7 +26,7 @@ import java.util.Map;
|
|||
* This is it's own separate physical database, so it cannot do joins or queries with any other
|
||||
* tables.
|
||||
*/
|
||||
public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase {
|
||||
public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase, KeyValuePersistentStorage {
|
||||
|
||||
private static final String TAG = Log.tag(KeyValueDatabase.class);
|
||||
|
||||
|
@ -99,6 +98,7 @@ public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull KeyValueDataSet getDataSet() {
|
||||
KeyValueDataSet dataSet = new KeyValueDataSet();
|
||||
|
||||
|
@ -133,6 +133,7 @@ public class KeyValueDatabase extends SQLiteOpenHelper implements SignalDatabase
|
|||
return dataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDataSet(@NonNull KeyValueDataSet dataSet, @NonNull Collection<String> removes) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
|||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
|
@ -500,7 +501,7 @@ public class RecipientDatabase extends Database {
|
|||
} else if (!byE164.isPresent() && byAci.isPresent()) {
|
||||
if (e164 != null) {
|
||||
if (highTrust) {
|
||||
if (Objects.equals(aci, TextSecurePreferences.getLocalAci(context)) && !changeSelf) {
|
||||
if (Objects.equals(aci, SignalStore.account().getAci()) && !changeSelf) {
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about an E164 (%s) for our own ACI user (%s). High-trust but not change self, doing nothing.", e164, byAci.get()), true);
|
||||
finalId = byAci.get();
|
||||
} else {
|
||||
|
|
|
@ -791,7 +791,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
|
|||
db.execSQL("UPDATE part SET pending_push = '2' WHERE pending_push = '1'");
|
||||
}
|
||||
|
||||
if (oldVersion < NO_MORE_CANONICAL_ADDRESS_DATABASE && isValidNumber(TextSecurePreferences.getLocalNumber(context))) {
|
||||
if (oldVersion < NO_MORE_CANONICAL_ADDRESS_DATABASE && isValidNumber(TextSecurePreferences.getStringPreference(context, "pref_local_number", null))) {
|
||||
SQLiteOpenHelper canonicalAddressDatabaseHelper = new SQLiteOpenHelper(context, "canonical_address.db", null, 1) {
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
|
@ -803,7 +803,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
|
|||
};
|
||||
|
||||
SQLiteDatabase canonicalAddressDatabase = canonicalAddressDatabaseHelper.getReadableDatabase();
|
||||
NumberMigrator numberMigrator = new NumberMigrator(TextSecurePreferences.getLocalNumber(context));
|
||||
NumberMigrator numberMigrator = new NumberMigrator(TextSecurePreferences.getStringPreference(context, "pref_local_number", null));
|
||||
|
||||
// Migrate Thread Database
|
||||
Cursor cursor = db.query("thread", new String[] {"_id", "recipient_ids"}, null, null, null, null, null);
|
||||
|
@ -1131,7 +1131,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
|
|||
members.add(DelimiterUtil.escape(DelimiterUtil.unescape(address, ' '), ','));
|
||||
}
|
||||
|
||||
members.add(DelimiterUtil.escape(TextSecurePreferences.getLocalNumber(context), ','));
|
||||
members.add(DelimiterUtil.escape(TextSecurePreferences.getStringPreference(context, "pref_local_number", null), ','));
|
||||
|
||||
Collections.sort(members);
|
||||
|
||||
|
@ -1188,14 +1188,14 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
|
|||
if (oldVersion < INTERNAL_DIRECTORY) {
|
||||
db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN registered INTEGER DEFAULT 0");
|
||||
|
||||
if (isValidNumber(TextSecurePreferences.getLocalNumber(context))) {
|
||||
if (isValidNumber(TextSecurePreferences.getStringPreference(context, "pref_local_number", null))) {
|
||||
OldDirectoryDatabaseHelper directoryDatabaseHelper = new OldDirectoryDatabaseHelper(context);
|
||||
SQLiteDatabase directoryDatabase = directoryDatabaseHelper.getWritableDatabase();
|
||||
|
||||
Cursor cursor = directoryDatabase.query("directory", new String[] {"number", "registered"}, null, null, null, null, null);
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String address = new NumberMigrator(TextSecurePreferences.getLocalNumber(context)).migrate(cursor.getString(0));
|
||||
String address = new NumberMigrator(TextSecurePreferences.getStringPreference(context, "pref_local_number", null)).migrate(cursor.getString(0));
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
|
||||
contentValues.put("registered", cursor.getInt(1) == 1 ? 1 : 2);
|
||||
|
|
|
@ -559,7 +559,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab
|
|||
}
|
||||
|
||||
if (oldVersion < SELF_ATTACHMENT_CLEANUP) {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
|
||||
if (!TextUtils.isEmpty(localNumber)) {
|
||||
try (Cursor threadCursor = db.rawQuery("SELECT _id FROM thread WHERE recipient_ids = ?", new String[]{ localNumber })) {
|
||||
|
@ -651,7 +651,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab
|
|||
if (oldVersion < RECIPIENT_SEARCH) {
|
||||
db.execSQL("ALTER TABLE recipient ADD COLUMN system_phone_type INTEGER DEFAULT -1");
|
||||
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
if (!TextUtils.isEmpty(localNumber)) {
|
||||
try (Cursor cursor = db.query("recipient", null, "phone = ?", new String[] { localNumber }, null, null, null)) {
|
||||
if (cursor == null || !cursor.moveToFirst()) {
|
||||
|
@ -834,7 +834,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab
|
|||
}
|
||||
|
||||
if (oldVersion < PROFILE_KEY_TO_DB) {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
if (!TextUtils.isEmpty(localNumber)) {
|
||||
String encodedProfileKey = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_key", null);
|
||||
byte[] profileKey = encodedProfileKey != null ? Base64.decodeOrThrow(encodedProfileKey) : Util.getSecretBytes(32);
|
||||
|
@ -903,7 +903,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab
|
|||
}
|
||||
|
||||
if (oldVersion < PROFILE_DATA_MIGRATION) {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
if (localNumber != null) {
|
||||
String encodedProfileName = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_profile_name", null);
|
||||
ProfileName profileName = ProfileName.fromSerialized(encodedProfileName);
|
||||
|
|
|
@ -36,7 +36,7 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
|||
this.joinedMembers = new ArrayList<>(joinedMembers);
|
||||
this.withTime = withTime;
|
||||
this.groupCallUpdateDetails = groupCallUpdateDetails;
|
||||
this.selfAci = TextSecurePreferences.getLocalAci(context);
|
||||
this.selfAci = Recipient.self().requireAci();
|
||||
|
||||
boolean removed = this.joinedMembers.remove(selfAci);
|
||||
if (removed) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Application;
|
|||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import org.signal.core.util.concurrent.DeadlockDetector;
|
||||
import org.signal.zkgroup.receipts.ClientZkReceiptOperations;
|
||||
|
@ -126,6 +127,11 @@ public class ApplicationDependencies {
|
|||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static boolean isInitialized() {
|
||||
return ApplicationDependencies.application != null;
|
||||
}
|
||||
|
||||
public static @NonNull Application getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.jobs.PushProcessMessageJob;
|
|||
import org.thoughtcrime.securesms.jobs.PushTextSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.ReactionSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.TypingSendJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
|
||||
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
|
||||
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
|
||||
|
@ -94,7 +95,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
}
|
||||
|
||||
private @NonNull ClientZkOperations provideClientZkOperations() {
|
||||
return ClientZkOperations.create(provideSignalServiceNetworkAccess().getConfiguration(context));
|
||||
return ClientZkOperations.create(provideSignalServiceNetworkAccess().getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,8 +105,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
@Override
|
||||
public @NonNull SignalServiceAccountManager provideSignalServiceAccountManager() {
|
||||
return new SignalServiceAccountManager(provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
new DynamicCredentialsProvider(context),
|
||||
return new SignalServiceAccountManager(provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
new DynamicCredentialsProvider(),
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
provideGroupsV2Operations(),
|
||||
FeatureFlags.okHttpAutomaticRetry());
|
||||
|
@ -113,8 +114,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
@Override
|
||||
public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket) {
|
||||
return new SignalServiceMessageSender(provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
new DynamicCredentialsProvider(context),
|
||||
return new SignalServiceMessageSender(provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
new DynamicCredentialsProvider(),
|
||||
new SignalProtocolStoreImpl(context),
|
||||
ReentrantSessionLock.INSTANCE,
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
|
@ -128,8 +129,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
@Override
|
||||
public @NonNull SignalServiceMessageReceiver provideSignalServiceMessageReceiver() {
|
||||
return new SignalServiceMessageReceiver(provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
new DynamicCredentialsProvider(context),
|
||||
return new SignalServiceMessageReceiver(provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
new DynamicCredentialsProvider(),
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
provideClientZkOperations().getProfileOperations(),
|
||||
FeatureFlags.okHttpAutomaticRetry());
|
||||
|
@ -263,7 +264,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
@Override
|
||||
public @NonNull SignalWebSocket provideSignalWebSocket() {
|
||||
SleepTimer sleepTimer = TextSecurePreferences.isFcmDisabled(context) ? new AlarmSleepTimer(context) : new UptimeSleepTimer();
|
||||
SleepTimer sleepTimer = SignalStore.account().isFcmEnabled() ? new UptimeSleepTimer() : new AlarmSleepTimer(context);
|
||||
SignalWebSocketHealthMonitor healthMonitor = new SignalWebSocketHealthMonitor(context, sleepTimer);
|
||||
SignalWebSocket signalWebSocket = new SignalWebSocket(provideWebSocketFactory(healthMonitor));
|
||||
|
||||
|
@ -309,8 +310,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
@Override
|
||||
public @NonNull DonationsService provideDonationsService() {
|
||||
return new DonationsService(provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
new DynamicCredentialsProvider(context),
|
||||
return new DonationsService(provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
new DynamicCredentialsProvider(),
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
provideGroupsV2Operations(),
|
||||
FeatureFlags.okHttpAutomaticRetry());
|
||||
|
@ -333,8 +334,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
@Override
|
||||
public WebSocketConnection createWebSocket() {
|
||||
return new WebSocketConnection("normal",
|
||||
provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
Optional.of(new DynamicCredentialsProvider(context)),
|
||||
provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
Optional.of(new DynamicCredentialsProvider()),
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
healthMonitor);
|
||||
}
|
||||
|
@ -342,7 +343,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
@Override
|
||||
public WebSocketConnection createUnidentifiedWebSocket() {
|
||||
return new WebSocketConnection("unidentified",
|
||||
provideSignalServiceNetworkAccess().getConfiguration(context),
|
||||
provideSignalServiceNetworkAccess().getConfiguration(),
|
||||
Optional.absent(),
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
healthMonitor);
|
||||
|
@ -352,25 +353,19 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||
|
||||
private static class DynamicCredentialsProvider implements CredentialsProvider {
|
||||
|
||||
private final Context context;
|
||||
|
||||
private DynamicCredentialsProvider(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ACI getAci() {
|
||||
return TextSecurePreferences.getLocalAci(context);
|
||||
return SignalStore.account().getAci();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getE164() {
|
||||
return TextSecurePreferences.getLocalNumber(context);
|
||||
return SignalStore.account().getE164();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return TextSecurePreferences.getPushServerPassword(context);
|
||||
return SignalStore.account().getServicePassword();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class FcmJobService extends JobService {
|
|||
public boolean onStartJob(JobParameters params) {
|
||||
Log.d(TAG, "onStartJob()");
|
||||
|
||||
if (BackgroundMessageRetriever.shouldIgnoreFetch(this)) {
|
||||
if (BackgroundMessageRetriever.shouldIgnoreFetch()) {
|
||||
Log.i(TAG, "App is foregrounded. No need to run.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.SubmitRateLimitPushChallengeJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.registration.PushChallengeRequest;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -53,7 +54,7 @@ public class FcmReceiveService extends FirebaseMessagingService {
|
|||
public void onNewToken(String token) {
|
||||
Log.i(TAG, "onNewToken()");
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(ApplicationDependencies.getApplication())) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.i(TAG, "Got a new FCM token, but the user isn't registered.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
|
@ -54,7 +55,7 @@ public class CreateSignedPreKeyJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Not yet registered...");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.gcm.FcmUtil;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationIds;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
|
@ -78,7 +79,7 @@ public class FcmRefreshJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws Exception {
|
||||
if (TextSecurePreferences.isFcmDisabled(context)) return;
|
||||
if (!SignalStore.account().isFcmEnabled()) return;
|
||||
|
||||
Log.i(TAG, "Reregistering FCM...");
|
||||
|
||||
|
@ -90,7 +91,7 @@ public class FcmRefreshJob extends BaseJob {
|
|||
Optional<String> token = FcmUtil.getToken();
|
||||
|
||||
if (token.isPresent()) {
|
||||
String oldToken = TextSecurePreferences.getFcmToken(context);
|
||||
String oldToken = SignalStore.account().getFcmToken();
|
||||
|
||||
if (!token.get().equals(oldToken)) {
|
||||
int oldLength = oldToken != null ? oldToken.length() : -1;
|
||||
|
@ -100,9 +101,7 @@ public class FcmRefreshJob extends BaseJob {
|
|||
}
|
||||
|
||||
ApplicationDependencies.getSignalServiceAccountManager().setGcmId(token);
|
||||
TextSecurePreferences.setFcmToken(context, token.get());
|
||||
TextSecurePreferences.setFcmTokenLastSetTime(context, System.currentTimeMillis());
|
||||
TextSecurePreferences.setWebsocketRegistered(context, true);
|
||||
SignalStore.account().setFcmToken(token.get());
|
||||
} else {
|
||||
throw new RetryLaterException(new IOException("Failed to retrieve a token."));
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ public class GroupV1MigrationJob extends BaseJob {
|
|||
|
||||
public static void enqueueRoutineMigrationsIfNecessary(@NonNull Application application) {
|
||||
if (!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
!TextSecurePreferences.isPushRegistered(application) ||
|
||||
TextSecurePreferences.getLocalAci(application) == null)
|
||||
!SignalStore.account().isRegistered() ||
|
||||
SignalStore.account().getAci() == null)
|
||||
{
|
||||
Log.i(TAG, "Registration not complete. Skipping.");
|
||||
return;
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.ApnUnavailableException;
|
||||
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
|
@ -105,7 +106,7 @@ public class MmsDownloadJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() {
|
||||
if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
if (SignalStore.account().getE164() == null) {
|
||||
throw new NotReadyException();
|
||||
}
|
||||
|
||||
|
@ -122,7 +123,7 @@ public class MmsDownloadJob extends BaseJob {
|
|||
throw new MmsException("Notification content location was null.");
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
throw new MmsException("Not registered");
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
|||
import org.thoughtcrime.securesms.jobmanager.JobLogger;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
|
@ -235,7 +236,7 @@ public final class MmsSendJob extends SendJob {
|
|||
if (!TextUtils.isEmpty(lineNumber)) {
|
||||
req.setFrom(new EncodedStringValue(lineNumber));
|
||||
} else {
|
||||
req.setFrom(new EncodedStringValue(TextSecurePreferences.getLocalNumber(context)));
|
||||
req.setFrom(new EncodedStringValue(SignalStore.account().getE164()));
|
||||
}
|
||||
|
||||
if (message.getRecipient().isMmsGroup()) {
|
||||
|
|
|
@ -37,7 +37,7 @@ public final class ProfileUploadJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
protected void onRun() throws Exception {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Not registered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
@ -226,7 +227,7 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) {
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess);
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ public abstract class PushSendJob extends SendJob {
|
|||
}
|
||||
|
||||
protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional<UnidentifiedAccessPair> syncAccess) {
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), TextSecurePreferences.getLocalNumber(context));
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
|
||||
SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress),
|
||||
message.getTimestamp(),
|
||||
message,
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
|
@ -188,7 +189,7 @@ public class PushTextSendJob extends PushSendJob {
|
|||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) {
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public class RefreshAttributesJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
if (!SignalStore.account().isRegistered() || SignalStore.account().getE164() == null) {
|
||||
Log.w(TAG, "Not yet registered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ public class RefreshAttributesJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
boolean fetchesMessages = TextSecurePreferences.isFcmDisabled(context);
|
||||
int registrationId = SignalStore.account().getRegistrationId();
|
||||
boolean fetchesMessages = !SignalStore.account().isFcmEnabled();
|
||||
byte[] unidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey());
|
||||
boolean universalUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context);
|
||||
String registrationLockV1 = null;
|
||||
|
|
|
@ -76,7 +76,7 @@ public class RefreshOwnProfileJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
protected void onRun() throws Exception {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) {
|
||||
if (!SignalStore.account().isRegistered() || TextUtils.isEmpty(SignalStore.account().getE164())) {
|
||||
Log.w(TAG, "Not yet registered!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public class RefreshPreKeysJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Not registered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
@ -46,7 +47,7 @@ public class RemoteConfigRefreshJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
protected void onRun() throws Exception {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Not registered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
@ -63,7 +64,7 @@ public class ReportSpamJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,8 +170,8 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
*/
|
||||
public static void enqueueRoutineFetchIfNecessary(Application application) {
|
||||
if (!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
!TextSecurePreferences.isPushRegistered(application) ||
|
||||
TextSecurePreferences.getLocalAci(application) == null)
|
||||
!SignalStore.account().isRegistered() ||
|
||||
SignalStore.account().getAci() == null)
|
||||
{
|
||||
Log.i(TAG, "Registration not complete. Skipping.");
|
||||
return;
|
||||
|
@ -236,7 +236,7 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException, RetryLaterException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Unregistered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public final class RotateCertificateJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.w(TAG, "Not yet registered. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationIds;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
@ -89,7 +90,7 @@ public class SmsReceiveJob extends BaseJob {
|
|||
public void onRun() throws MigrationPendingException, RetryLaterException {
|
||||
Optional<IncomingTextMessage> message = assembleMessageFragments(pdus, subscriptionId);
|
||||
|
||||
if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
if (SignalStore.account().getE164() == null) {
|
||||
Log.i(TAG, "Received an SMS before we're registered...");
|
||||
|
||||
if (message.isPresent()) {
|
||||
|
|
|
@ -166,7 +166,7 @@ public class StorageSyncJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
Log.i(TAG, "Not registered. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
package org.thoughtcrime.securesms.keyvalue
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.whispersystems.signalservice.api.push.ACI
|
||||
import org.whispersystems.signalservice.api.push.PNI
|
||||
|
||||
internal class AccountValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(AccountValues::class.java)
|
||||
private const val KEY_ACI = "account.aci"
|
||||
private const val KEY_PNI = "account.pni"
|
||||
private const val KEY_SERVICE_PASSWORD = "account.service_password"
|
||||
private const val KEY_IS_REGISTERED = "account.is_registered"
|
||||
private const val KEY_REGISTRATION_ID = "account.registration_id"
|
||||
private const val KEY_FCM_ENABLED = "account.fcm_enabled"
|
||||
private const val KEY_FCM_TOKEN = "account.fcm_token"
|
||||
private const val KEY_FCM_TOKEN_VERSION = "account.fcm_token_version"
|
||||
private const val KEY_FCM_TOKEN_LAST_SET_TIME = "account.fcm_token_last_set_time"
|
||||
|
||||
@VisibleForTesting
|
||||
const val KEY_E164 = "account.e164"
|
||||
}
|
||||
|
||||
init {
|
||||
if (!store.containsKey(KEY_ACI)) {
|
||||
migrateFromSharedPrefs(ApplicationDependencies.getApplication())
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onFirstEverAppLaunch() = Unit
|
||||
|
||||
public override fun getKeysToIncludeInBackup(): List<String> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
/** The local user's [ACI]. */
|
||||
val aci: ACI?
|
||||
get() = ACI.parseOrNull(getString(KEY_ACI, null))
|
||||
|
||||
fun setAci(aci: ACI) {
|
||||
putString(KEY_ACI, aci.toString())
|
||||
}
|
||||
|
||||
/** The local user's [PNI]. */
|
||||
val pni: PNI?
|
||||
get() = PNI.parseOrNull(getString(KEY_ACI, null))
|
||||
|
||||
fun setPni(pni: PNI) {
|
||||
putString(KEY_PNI, pni.toString())
|
||||
}
|
||||
|
||||
/** The local user's E164. */
|
||||
val e164: String?
|
||||
get() = getString(KEY_E164, null)
|
||||
|
||||
fun setE164(e164: String) {
|
||||
putString(KEY_E164, e164)
|
||||
}
|
||||
|
||||
/** The password for communicating with the Signal service. */
|
||||
val servicePassword: String?
|
||||
get() = getString(KEY_SERVICE_PASSWORD, null)
|
||||
|
||||
fun setServicePassword(servicePassword: String) {
|
||||
putString(KEY_SERVICE_PASSWORD, servicePassword)
|
||||
}
|
||||
|
||||
/** A randomly-generated value that represents this registration instance. Helps the server know if you reinstalled. */
|
||||
var registrationId: Int
|
||||
get() = getInteger(KEY_REGISTRATION_ID, 0)
|
||||
set(value) = putInteger(KEY_REGISTRATION_ID, value)
|
||||
|
||||
/** Indicates whether the user has the ability to receive FCM messages. Largely coupled to whether they have Play Service. */
|
||||
var fcmEnabled: Boolean
|
||||
@JvmName("isFcmEnabled")
|
||||
get() = getBoolean(KEY_FCM_ENABLED, false)
|
||||
set(value) = putBoolean(KEY_FCM_ENABLED, value)
|
||||
|
||||
/** The FCM token, which allows the server to send us FCM messages. */
|
||||
var fcmToken: String?
|
||||
get() {
|
||||
val tokenVersion: Int = getInteger(KEY_FCM_TOKEN_VERSION, 0)
|
||||
return if (tokenVersion == Util.getCanonicalVersionCode()) {
|
||||
getString(KEY_FCM_TOKEN, null)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
set(value) {
|
||||
store.beginWrite()
|
||||
.putString(KEY_FCM_TOKEN, value)
|
||||
.putInteger(KEY_FCM_TOKEN_VERSION, Util.getCanonicalVersionCode())
|
||||
.putLong(KEY_FCM_TOKEN_LAST_SET_TIME, System.currentTimeMillis())
|
||||
.apply()
|
||||
}
|
||||
|
||||
/** When we last set the [fcmToken] */
|
||||
val fcmTokenLastSetTime: Long
|
||||
get() = getLong(KEY_FCM_TOKEN_LAST_SET_TIME, 0)
|
||||
|
||||
/** Whether or not the user is registered with the Signal service. */
|
||||
val isRegistered: Boolean
|
||||
get() = getBoolean(KEY_IS_REGISTERED, false)
|
||||
|
||||
fun setRegistered(registered: Boolean) {
|
||||
Log.i(TAG, "Setting push registered: $registered", Throwable())
|
||||
|
||||
val previous = isRegistered
|
||||
|
||||
putBoolean(KEY_IS_REGISTERED, registered)
|
||||
|
||||
ApplicationDependencies.getIncomingMessageObserver().notifyRegistrationChanged()
|
||||
|
||||
if (previous != registered) {
|
||||
Recipient.self().live().refresh()
|
||||
}
|
||||
|
||||
if (previous && !registered) {
|
||||
clearLocalCredentials(ApplicationDependencies.getApplication())
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearLocalCredentials(context: Context) {
|
||||
putString(KEY_SERVICE_PASSWORD, Util.getSecret(18))
|
||||
|
||||
val newProfileKey = ProfileKeyUtil.createNew()
|
||||
val self = Recipient.self()
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileKey(self.id, newProfileKey)
|
||||
ApplicationDependencies.getGroupsV2Authorization().clear()
|
||||
}
|
||||
|
||||
private fun migrateFromSharedPrefs(context: Context) {
|
||||
Log.i(TAG, "Migrating account values from shared prefs.")
|
||||
|
||||
putString(KEY_ACI, TextSecurePreferences.getStringPreference(context, "pref_local_uuid", null))
|
||||
putString(KEY_E164, TextSecurePreferences.getStringPreference(context, "pref_local_number", null))
|
||||
putString(KEY_SERVICE_PASSWORD, TextSecurePreferences.getStringPreference(context, "pref_gcm_password", null))
|
||||
putBoolean(KEY_IS_REGISTERED, TextSecurePreferences.getBooleanPreference(context, "pref_gcm_registered", false))
|
||||
putInteger(KEY_REGISTRATION_ID, TextSecurePreferences.getIntegerPreference(context, "pref_local_registration_id", 0))
|
||||
putBoolean(KEY_FCM_ENABLED, !TextSecurePreferences.getBooleanPreference(context, "pref_gcm_disabled", false))
|
||||
putString(KEY_FCM_TOKEN, TextSecurePreferences.getStringPreference(context, "pref_gcm_registration_id", null))
|
||||
putInteger(KEY_FCM_TOKEN_VERSION, TextSecurePreferences.getIntegerPreference(context, "pref_gcm_registration_id_version", 0))
|
||||
putLong(KEY_FCM_TOKEN_LAST_SET_TIME, TextSecurePreferences.getLongPreference(context, "pref_gcm_registration_id_last_set_time", 0))
|
||||
}
|
||||
}
|
|
@ -7,11 +7,9 @@ import org.signal.donations.StripeApi
|
|||
import org.thoughtcrime.securesms.badges.Badges
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.payments.currency.CurrencyUtil
|
||||
import org.thoughtcrime.securesms.subscription.LevelUpdateOperation
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.subscriptions.IdempotencyKey
|
||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||
import java.util.Currency
|
||||
|
@ -52,7 +50,7 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
|||
val currency: Currency? = if (currencyCode == null) {
|
||||
val localeCurrency = CurrencyUtil.getCurrencyByLocale(Locale.getDefault())
|
||||
if (localeCurrency == null) {
|
||||
val e164 = TextSecurePreferences.getLocalNumber(ApplicationDependencies.getApplication())
|
||||
val e164: String? = SignalStore.account().e164
|
||||
if (e164 == null) {
|
||||
null
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface KeyValuePersistentStorage {
|
||||
void writeDataSet(@NonNull KeyValueDataSet dataSet, @NonNull Collection<String> removes);
|
||||
@NonNull KeyValueDataSet getDataSet();
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -11,8 +8,6 @@ import androidx.annotation.WorkerThread;
|
|||
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.KeyValueDatabase;
|
||||
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -35,14 +30,14 @@ public final class KeyValueStore implements KeyValueReader {
|
|||
|
||||
private static final String TAG = Log.tag(KeyValueStore.class);
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final KeyValueDatabase database;
|
||||
private final ExecutorService executor;
|
||||
private final KeyValuePersistentStorage storage;
|
||||
|
||||
private KeyValueDataSet dataSet;
|
||||
|
||||
public KeyValueStore(@NonNull Application application) {
|
||||
public KeyValueStore(@NonNull KeyValuePersistentStorage storage) {
|
||||
this.executor = SignalExecutors.newCachedSingleThreadExecutor("signal-KeyValueStore");
|
||||
this.database = KeyValueDatabase.getInstance(application);
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
|
@ -150,12 +145,12 @@ public final class KeyValueStore implements KeyValueReader {
|
|||
dataSet.putAll(newDataSet);
|
||||
dataSet.removeAll(removes);
|
||||
|
||||
executor.execute(() -> database.writeDataSet(newDataSet, removes));
|
||||
executor.execute(() -> storage.writeDataSet(newDataSet, removes));
|
||||
}
|
||||
|
||||
private void initializeIfNecessary() {
|
||||
if (dataSet != null) return;
|
||||
this.dataSet = database.getDataSet();
|
||||
this.dataSet = storage.getDataSet();
|
||||
}
|
||||
|
||||
class Writer {
|
||||
|
|
|
@ -1,366 +0,0 @@
|
|||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Transformations;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.mobilecoin.lib.Mnemonics;
|
||||
import com.mobilecoin.lib.exceptions.BadMnemonicException;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.lock.v2.PinKeyboardType;
|
||||
import org.thoughtcrime.securesms.payments.Balance;
|
||||
import org.thoughtcrime.securesms.payments.Entropy;
|
||||
import org.thoughtcrime.securesms.payments.GeographicalRestrictions;
|
||||
import org.thoughtcrime.securesms.payments.Mnemonic;
|
||||
import org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper;
|
||||
import org.thoughtcrime.securesms.payments.currency.CurrencyUtil;
|
||||
import org.thoughtcrime.securesms.payments.proto.MobileCoinLedger;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.api.payments.Money;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PaymentsValues extends SignalStoreValues {
|
||||
|
||||
private static final String TAG = Log.tag(PaymentsValues.class);
|
||||
|
||||
private static final String PAYMENTS_ENTROPY = "payments_entropy";
|
||||
private static final String MOB_PAYMENTS_ENABLED = "mob_payments_enabled";
|
||||
private static final String MOB_LEDGER = "mob_ledger";
|
||||
private static final String PAYMENTS_CURRENT_CURRENCY = "payments_current_currency";
|
||||
private static final String DEFAULT_CURRENCY_CODE = "GBP";
|
||||
private static final String USER_CONFIRMED_MNEMONIC = "mob_payments_user_confirmed_mnemonic";
|
||||
|
||||
private static final String SHOW_ABOUT_MOBILE_COIN_INFO_CARD = "mob_payments_show_about_mobile_coin_info_card";
|
||||
private static final String SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD = "mob_payments_show_adding_to_your_wallet_info_card";
|
||||
private static final String SHOW_CASHING_OUT_INFO_CARD = "mob_payments_show_cashing_out_info_card";
|
||||
private static final String SHOW_RECOVERY_PHRASE_INFO_CARD = "mob_payments_show_recovery_phrase_info_card";
|
||||
private static final String SHOW_UPDATE_PIN_INFO_CARD = "mob_payments_show_update_pin_info_card";
|
||||
|
||||
private static final Money.MobileCoin LARGE_BALANCE_THRESHOLD = Money.mobileCoin(BigDecimal.valueOf(500));
|
||||
|
||||
private final MutableLiveData<Currency> liveCurrentCurrency;
|
||||
private final MutableLiveData<MobileCoinLedgerWrapper> liveMobileCoinLedger;
|
||||
private final LiveData<Balance> liveMobileCoinBalance;
|
||||
|
||||
PaymentsValues(@NonNull KeyValueStore store) {
|
||||
super(store);
|
||||
this.liveCurrentCurrency = new MutableLiveData<>(currentCurrency());
|
||||
this.liveMobileCoinLedger = new MutableLiveData<>(mobileCoinLatestFullLedger());
|
||||
this.liveMobileCoinBalance = Transformations.map(liveMobileCoinLedger, MobileCoinLedgerWrapper::getBalance);
|
||||
}
|
||||
|
||||
@Override void onFirstEverAppLaunch() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull List<String> getKeysToIncludeInBackup() {
|
||||
return Arrays.asList(PAYMENTS_ENTROPY,
|
||||
MOB_PAYMENTS_ENABLED,
|
||||
MOB_LEDGER,
|
||||
PAYMENTS_CURRENT_CURRENCY,
|
||||
DEFAULT_CURRENCY_CODE,
|
||||
USER_CONFIRMED_MNEMONIC,
|
||||
SHOW_ABOUT_MOBILE_COIN_INFO_CARD,
|
||||
SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD,
|
||||
SHOW_CASHING_OUT_INFO_CARD,
|
||||
SHOW_RECOVERY_PHRASE_INFO_CARD,
|
||||
SHOW_UPDATE_PIN_INFO_CARD);
|
||||
}
|
||||
|
||||
public boolean userConfirmedMnemonic() {
|
||||
return getStore().getBoolean(USER_CONFIRMED_MNEMONIC, false);
|
||||
}
|
||||
|
||||
public void setUserConfirmedMnemonic(boolean userConfirmedMnemonic) {
|
||||
getStore().beginWrite().putBoolean(USER_CONFIRMED_MNEMONIC, userConfirmedMnemonic).commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Consider using {@link #getPaymentsAvailability} which includes feature flag and region status.
|
||||
*/
|
||||
public boolean mobileCoinPaymentsEnabled() {
|
||||
KeyValueReader reader = getStore().beginRead();
|
||||
|
||||
return reader.getBoolean(MOB_PAYMENTS_ENABLED, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies feature flags and region restrictions to return an enum which describes the available feature set for the user.
|
||||
*/
|
||||
public PaymentsAvailability getPaymentsAvailability() {
|
||||
Context context = ApplicationDependencies.getApplication();
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
!GeographicalRestrictions.e164Allowed(TextSecurePreferences.getLocalNumber(context)))
|
||||
{
|
||||
return PaymentsAvailability.NOT_IN_REGION;
|
||||
}
|
||||
|
||||
if (FeatureFlags.payments()) {
|
||||
if (mobileCoinPaymentsEnabled()) {
|
||||
return PaymentsAvailability.WITHDRAW_AND_SEND;
|
||||
} else {
|
||||
return PaymentsAvailability.REGISTRATION_AVAILABLE;
|
||||
}
|
||||
} else {
|
||||
if (mobileCoinPaymentsEnabled()) {
|
||||
return PaymentsAvailability.WITHDRAW_ONLY;
|
||||
} else {
|
||||
return PaymentsAvailability.DISABLED_REMOTELY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public void setMobileCoinPaymentsEnabled(boolean isMobileCoinPaymentsEnabled) {
|
||||
if (mobileCoinPaymentsEnabled() == isMobileCoinPaymentsEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMobileCoinPaymentsEnabled) {
|
||||
Entropy entropy = getPaymentsEntropy();
|
||||
if (entropy == null) {
|
||||
entropy = Entropy.generateNew();
|
||||
Log.i(TAG, "Generated new payments entropy");
|
||||
}
|
||||
|
||||
getStore().beginWrite()
|
||||
.putBlob(PAYMENTS_ENTROPY, entropy.getBytes())
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, true)
|
||||
.putString(PAYMENTS_CURRENT_CURRENCY, currentCurrency().getCurrencyCode())
|
||||
.commit();
|
||||
} else {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, false)
|
||||
.putBoolean(USER_CONFIRMED_MNEMONIC, false)
|
||||
.commit();
|
||||
}
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().getId());
|
||||
StorageSyncHelper.scheduleSyncForDataChange();
|
||||
}
|
||||
|
||||
public @NonNull Mnemonic getPaymentsMnemonic() {
|
||||
Entropy paymentsEntropy = getPaymentsEntropy();
|
||||
if (paymentsEntropy == null) {
|
||||
throw new IllegalStateException("Entropy has not been set");
|
||||
}
|
||||
|
||||
return paymentsEntropy.asMnemonic();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if a local entropy is set, regardless of whether payments is currently enabled.
|
||||
*/
|
||||
public boolean hasPaymentsEntropy() {
|
||||
return getPaymentsEntropy() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local payments entropy, regardless of whether payments is currently enabled.
|
||||
* <p>
|
||||
* And null if has never been set.
|
||||
*/
|
||||
public @Nullable Entropy getPaymentsEntropy() {
|
||||
return Entropy.fromBytes(getStore().getBlob(PAYMENTS_ENTROPY, null));
|
||||
}
|
||||
|
||||
public @NonNull Balance mobileCoinLatestBalance() {
|
||||
return mobileCoinLatestFullLedger().getBalance();
|
||||
}
|
||||
|
||||
public @NonNull LiveData<MobileCoinLedgerWrapper> liveMobileCoinLedger() {
|
||||
return liveMobileCoinLedger;
|
||||
}
|
||||
|
||||
public @NonNull LiveData<Balance> liveMobileCoinBalance() {
|
||||
return liveMobileCoinBalance;
|
||||
}
|
||||
|
||||
public void setCurrentCurrency(@NonNull Currency currentCurrency) {
|
||||
getStore().beginWrite()
|
||||
.putString(PAYMENTS_CURRENT_CURRENCY, currentCurrency.getCurrencyCode())
|
||||
.commit();
|
||||
|
||||
liveCurrentCurrency.postValue(currentCurrency);
|
||||
}
|
||||
|
||||
public @NonNull Currency currentCurrency() {
|
||||
String currencyCode = getStore().getString(PAYMENTS_CURRENT_CURRENCY, null);
|
||||
return currencyCode == null ? determineCurrency()
|
||||
: Currency.getInstance(currencyCode);
|
||||
}
|
||||
|
||||
public @NonNull MutableLiveData<Currency> liveCurrentCurrency() {
|
||||
return liveCurrentCurrency;
|
||||
}
|
||||
|
||||
public boolean showAboutMobileCoinInfoCard() {
|
||||
return getStore().getBoolean(SHOW_ABOUT_MOBILE_COIN_INFO_CARD, true);
|
||||
}
|
||||
|
||||
public boolean showAddingToYourWalletInfoCard() {
|
||||
return getStore().getBoolean(SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD, true);
|
||||
}
|
||||
|
||||
public boolean showCashingOutInfoCard() {
|
||||
return getStore().getBoolean(SHOW_CASHING_OUT_INFO_CARD, true);
|
||||
}
|
||||
|
||||
public boolean showRecoveryPhraseInfoCard() {
|
||||
if (userHasLargeBalance()) {
|
||||
return getStore().getBoolean(SHOW_CASHING_OUT_INFO_CARD, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean showUpdatePinInfoCard() {
|
||||
if (userHasLargeBalance() &&
|
||||
SignalStore.kbsValues().hasPin() &&
|
||||
!SignalStore.kbsValues().hasOptedOut() &&
|
||||
SignalStore.pinValues().getKeyboardType().equals(PinKeyboardType.NUMERIC)) {
|
||||
return getStore().getBoolean(SHOW_CASHING_OUT_INFO_CARD, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void dismissAboutMobileCoinInfoCard() {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(SHOW_ABOUT_MOBILE_COIN_INFO_CARD, false)
|
||||
.apply();
|
||||
}
|
||||
|
||||
public void dismissAddingToYourWalletInfoCard() {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD, false)
|
||||
.apply();
|
||||
}
|
||||
|
||||
public void dismissCashingOutInfoCard() {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(SHOW_CASHING_OUT_INFO_CARD, false)
|
||||
.apply();
|
||||
}
|
||||
|
||||
public void dismissRecoveryPhraseInfoCard() {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(SHOW_RECOVERY_PHRASE_INFO_CARD, false)
|
||||
.apply();
|
||||
}
|
||||
|
||||
public void dismissUpdatePinInfoCard() {
|
||||
getStore().beginWrite()
|
||||
.putBoolean(SHOW_UPDATE_PIN_INFO_CARD, false)
|
||||
.apply();
|
||||
}
|
||||
|
||||
public void setMobileCoinFullLedger(@NonNull MobileCoinLedgerWrapper ledger) {
|
||||
getStore().beginWrite()
|
||||
.putBlob(MOB_LEDGER, ledger.serialize())
|
||||
.commit();
|
||||
|
||||
liveMobileCoinLedger.postValue(ledger);
|
||||
}
|
||||
|
||||
public @NonNull MobileCoinLedgerWrapper mobileCoinLatestFullLedger() {
|
||||
byte[] blob = getStore().getBlob(MOB_LEDGER, null);
|
||||
|
||||
if (blob == null) {
|
||||
return new MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance());
|
||||
}
|
||||
|
||||
try {
|
||||
return new MobileCoinLedgerWrapper(MobileCoinLedger.parseFrom(blob));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
Log.w(TAG, "Bad cached ledger, clearing", e);
|
||||
setMobileCoinFullLedger(new MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance()));
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull Currency determineCurrency() {
|
||||
String localE164 = TextSecurePreferences.getLocalNumber(ApplicationDependencies.getApplication());
|
||||
if (localE164 == null) {
|
||||
localE164 = "";
|
||||
}
|
||||
return Util.firstNonNull(CurrencyUtil.getCurrencyByE164(localE164),
|
||||
CurrencyUtil.getCurrencyByLocale(Locale.getDefault()),
|
||||
Currency.getInstance(DEFAULT_CURRENCY_CODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not trigger a storage sync.
|
||||
*/
|
||||
public void setEnabledAndEntropy(boolean enabled, @Nullable Entropy entropy) {
|
||||
KeyValueStore.Writer writer = getStore().beginWrite();
|
||||
|
||||
if (entropy != null) {
|
||||
writer.putBlob(PAYMENTS_ENTROPY, entropy.getBytes());
|
||||
}
|
||||
|
||||
writer.putBoolean(MOB_PAYMENTS_ENABLED, enabled)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public WalletRestoreResult restoreWallet(@NonNull String mnemonic) {
|
||||
byte[] entropyFromMnemonic;
|
||||
try {
|
||||
entropyFromMnemonic = Mnemonics.bip39EntropyFromMnemonic(mnemonic);
|
||||
} catch (BadMnemonicException e) {
|
||||
return WalletRestoreResult.MNEMONIC_ERROR;
|
||||
}
|
||||
Entropy paymentsEntropy = getPaymentsEntropy();
|
||||
if (paymentsEntropy != null) {
|
||||
byte[] existingEntropy = paymentsEntropy.getBytes();
|
||||
if (Arrays.equals(existingEntropy, entropyFromMnemonic)) {
|
||||
setMobileCoinPaymentsEnabled(true);
|
||||
setUserConfirmedMnemonic(true);
|
||||
return WalletRestoreResult.ENTROPY_UNCHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
getStore().beginWrite()
|
||||
.putBlob(PAYMENTS_ENTROPY, entropyFromMnemonic)
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, true)
|
||||
.remove(MOB_LEDGER)
|
||||
.putBoolean(USER_CONFIRMED_MNEMONIC, true)
|
||||
.commit();
|
||||
|
||||
liveMobileCoinLedger.postValue(new MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance()));
|
||||
|
||||
StorageSyncHelper.scheduleSyncForDataChange();
|
||||
|
||||
return WalletRestoreResult.ENTROPY_CHANGED;
|
||||
}
|
||||
|
||||
public enum WalletRestoreResult {
|
||||
ENTROPY_CHANGED,
|
||||
ENTROPY_UNCHANGED,
|
||||
MNEMONIC_ERROR
|
||||
}
|
||||
|
||||
private boolean userHasLargeBalance() {
|
||||
return mobileCoinLatestBalance().getFullAmount().requireMobileCoin().greaterThan(LARGE_BALANCE_THRESHOLD);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
package org.thoughtcrime.securesms.keyvalue
|
||||
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import com.mobilecoin.lib.Mnemonics
|
||||
import com.mobilecoin.lib.exceptions.BadMnemonicException
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.PaymentsValues.WalletRestoreResult
|
||||
import org.thoughtcrime.securesms.lock.v2.PinKeyboardType
|
||||
import org.thoughtcrime.securesms.payments.Balance
|
||||
import org.thoughtcrime.securesms.payments.Entropy
|
||||
import org.thoughtcrime.securesms.payments.GeographicalRestrictions
|
||||
import org.thoughtcrime.securesms.payments.Mnemonic
|
||||
import org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper
|
||||
import org.thoughtcrime.securesms.payments.currency.CurrencyUtil
|
||||
import org.thoughtcrime.securesms.payments.proto.MobileCoinLedger
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.whispersystems.signalservice.api.payments.Money
|
||||
import java.lang.AssertionError
|
||||
import java.lang.IllegalStateException
|
||||
import java.math.BigDecimal
|
||||
import java.util.Arrays
|
||||
import java.util.Currency
|
||||
import java.util.Locale
|
||||
|
||||
internal class PaymentsValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(PaymentsValues::class.java)
|
||||
|
||||
private const val PAYMENTS_ENTROPY = "payments_entropy"
|
||||
private const val MOB_PAYMENTS_ENABLED = "mob_payments_enabled"
|
||||
private const val MOB_LEDGER = "mob_ledger"
|
||||
private const val PAYMENTS_CURRENT_CURRENCY = "payments_current_currency"
|
||||
private const val DEFAULT_CURRENCY_CODE = "GBP"
|
||||
private const val USER_CONFIRMED_MNEMONIC = "mob_payments_user_confirmed_mnemonic"
|
||||
private const val SHOW_ABOUT_MOBILE_COIN_INFO_CARD = "mob_payments_show_about_mobile_coin_info_card"
|
||||
private const val SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD = "mob_payments_show_adding_to_your_wallet_info_card"
|
||||
private const val SHOW_CASHING_OUT_INFO_CARD = "mob_payments_show_cashing_out_info_card"
|
||||
private const val SHOW_RECOVERY_PHRASE_INFO_CARD = "mob_payments_show_recovery_phrase_info_card"
|
||||
private const val SHOW_UPDATE_PIN_INFO_CARD = "mob_payments_show_update_pin_info_card"
|
||||
|
||||
private val LARGE_BALANCE_THRESHOLD = Money.mobileCoin(BigDecimal.valueOf(500))
|
||||
}
|
||||
|
||||
private val liveCurrentCurrency: MutableLiveData<Currency> by lazy { MutableLiveData(currentCurrency()) }
|
||||
private val liveMobileCoinLedger: MutableLiveData<MobileCoinLedgerWrapper> by lazy { MutableLiveData(mobileCoinLatestFullLedger()) }
|
||||
private val liveMobileCoinBalance: LiveData<Balance> by lazy { Transformations.map(liveMobileCoinLedger) { obj: MobileCoinLedgerWrapper -> obj.balance } }
|
||||
|
||||
public override fun onFirstEverAppLaunch() {}
|
||||
|
||||
public override fun getKeysToIncludeInBackup(): List<String> {
|
||||
return listOf(
|
||||
PAYMENTS_ENTROPY,
|
||||
MOB_PAYMENTS_ENABLED,
|
||||
MOB_LEDGER,
|
||||
PAYMENTS_CURRENT_CURRENCY,
|
||||
DEFAULT_CURRENCY_CODE,
|
||||
USER_CONFIRMED_MNEMONIC,
|
||||
SHOW_ABOUT_MOBILE_COIN_INFO_CARD,
|
||||
SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD,
|
||||
SHOW_CASHING_OUT_INFO_CARD,
|
||||
SHOW_RECOVERY_PHRASE_INFO_CARD,
|
||||
SHOW_UPDATE_PIN_INFO_CARD
|
||||
)
|
||||
}
|
||||
|
||||
fun userConfirmedMnemonic(): Boolean {
|
||||
return store.getBoolean(USER_CONFIRMED_MNEMONIC, false)
|
||||
}
|
||||
|
||||
fun setUserConfirmedMnemonic(userConfirmedMnemonic: Boolean) {
|
||||
store.beginWrite().putBoolean(USER_CONFIRMED_MNEMONIC, userConfirmedMnemonic).commit()
|
||||
}
|
||||
|
||||
/**
|
||||
* Consider using [.getPaymentsAvailability] which includes feature flag and region status.
|
||||
*/
|
||||
fun mobileCoinPaymentsEnabled(): Boolean {
|
||||
return getBoolean(MOB_PAYMENTS_ENABLED, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies feature flags and region restrictions to return an enum which describes the available feature set for the user.
|
||||
*/
|
||||
val paymentsAvailability: PaymentsAvailability
|
||||
get() {
|
||||
if (!SignalStore.account().isRegistered ||
|
||||
!GeographicalRestrictions.e164Allowed(Recipient.self().requireE164())
|
||||
) {
|
||||
return PaymentsAvailability.NOT_IN_REGION
|
||||
}
|
||||
return if (FeatureFlags.payments()) {
|
||||
if (mobileCoinPaymentsEnabled()) {
|
||||
PaymentsAvailability.WITHDRAW_AND_SEND
|
||||
} else {
|
||||
PaymentsAvailability.REGISTRATION_AVAILABLE
|
||||
}
|
||||
} else {
|
||||
if (mobileCoinPaymentsEnabled()) {
|
||||
PaymentsAvailability.WITHDRAW_ONLY
|
||||
} else {
|
||||
PaymentsAvailability.DISABLED_REMOTELY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun setMobileCoinPaymentsEnabled(isMobileCoinPaymentsEnabled: Boolean) {
|
||||
if (mobileCoinPaymentsEnabled() == isMobileCoinPaymentsEnabled) {
|
||||
return
|
||||
}
|
||||
if (isMobileCoinPaymentsEnabled) {
|
||||
var entropy = paymentsEntropy
|
||||
if (entropy == null) {
|
||||
entropy = Entropy.generateNew()
|
||||
Log.i(TAG, "Generated new payments entropy")
|
||||
}
|
||||
store.beginWrite()
|
||||
.putBlob(PAYMENTS_ENTROPY, entropy.bytes)
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, true)
|
||||
.putString(PAYMENTS_CURRENT_CURRENCY, currentCurrency().currencyCode)
|
||||
.commit()
|
||||
} else {
|
||||
store.beginWrite()
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, false)
|
||||
.putBoolean(USER_CONFIRMED_MNEMONIC, false)
|
||||
.commit()
|
||||
}
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().id)
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
}
|
||||
|
||||
val paymentsMnemonic: Mnemonic
|
||||
get() {
|
||||
val paymentsEntropy = paymentsEntropy ?: throw IllegalStateException("Entropy has not been set")
|
||||
return paymentsEntropy.asMnemonic()
|
||||
}
|
||||
|
||||
/**
|
||||
* True if a local entropy is set, regardless of whether payments is currently enabled.
|
||||
*/
|
||||
fun hasPaymentsEntropy(): Boolean {
|
||||
return paymentsEntropy != null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local payments entropy, regardless of whether payments is currently enabled.
|
||||
*
|
||||
*
|
||||
* And null if has never been set.
|
||||
*/
|
||||
val paymentsEntropy: Entropy?
|
||||
get() = Entropy.fromBytes(store.getBlob(PAYMENTS_ENTROPY, null))
|
||||
|
||||
fun mobileCoinLatestBalance(): Balance {
|
||||
return mobileCoinLatestFullLedger().balance
|
||||
}
|
||||
|
||||
fun liveMobileCoinLedger(): LiveData<MobileCoinLedgerWrapper> {
|
||||
return liveMobileCoinLedger
|
||||
}
|
||||
|
||||
fun liveMobileCoinBalance(): LiveData<Balance> {
|
||||
return liveMobileCoinBalance
|
||||
}
|
||||
|
||||
fun setCurrentCurrency(currentCurrency: Currency) {
|
||||
store.beginWrite()
|
||||
.putString(PAYMENTS_CURRENT_CURRENCY, currentCurrency.currencyCode)
|
||||
.commit()
|
||||
liveCurrentCurrency.postValue(currentCurrency)
|
||||
}
|
||||
|
||||
fun currentCurrency(): Currency {
|
||||
val currencyCode = store.getString(PAYMENTS_CURRENT_CURRENCY, null)
|
||||
return if (currencyCode == null) determineCurrency() else Currency.getInstance(currencyCode)
|
||||
}
|
||||
|
||||
fun liveCurrentCurrency(): MutableLiveData<Currency> {
|
||||
return liveCurrentCurrency
|
||||
}
|
||||
|
||||
fun showAboutMobileCoinInfoCard(): Boolean {
|
||||
return store.getBoolean(SHOW_ABOUT_MOBILE_COIN_INFO_CARD, true)
|
||||
}
|
||||
|
||||
fun showAddingToYourWalletInfoCard(): Boolean {
|
||||
return store.getBoolean(SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD, true)
|
||||
}
|
||||
|
||||
fun showCashingOutInfoCard(): Boolean {
|
||||
return store.getBoolean(SHOW_CASHING_OUT_INFO_CARD, true)
|
||||
}
|
||||
|
||||
fun showRecoveryPhraseInfoCard(): Boolean {
|
||||
return if (userHasLargeBalance()) {
|
||||
store.getBoolean(SHOW_CASHING_OUT_INFO_CARD, true)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun showUpdatePinInfoCard(): Boolean {
|
||||
return if (userHasLargeBalance() &&
|
||||
SignalStore.kbsValues().hasPin() &&
|
||||
!SignalStore.kbsValues().hasOptedOut() && SignalStore.pinValues().keyboardType == PinKeyboardType.NUMERIC
|
||||
) {
|
||||
store.getBoolean(SHOW_CASHING_OUT_INFO_CARD, true)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun dismissAboutMobileCoinInfoCard() {
|
||||
store.beginWrite()
|
||||
.putBoolean(SHOW_ABOUT_MOBILE_COIN_INFO_CARD, false)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun dismissAddingToYourWalletInfoCard() {
|
||||
store.beginWrite()
|
||||
.putBoolean(SHOW_ADDING_TO_YOUR_WALLET_INFO_CARD, false)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun dismissCashingOutInfoCard() {
|
||||
store.beginWrite()
|
||||
.putBoolean(SHOW_CASHING_OUT_INFO_CARD, false)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun dismissRecoveryPhraseInfoCard() {
|
||||
store.beginWrite()
|
||||
.putBoolean(SHOW_RECOVERY_PHRASE_INFO_CARD, false)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun dismissUpdatePinInfoCard() {
|
||||
store.beginWrite()
|
||||
.putBoolean(SHOW_UPDATE_PIN_INFO_CARD, false)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun setMobileCoinFullLedger(ledger: MobileCoinLedgerWrapper) {
|
||||
store.beginWrite()
|
||||
.putBlob(MOB_LEDGER, ledger.serialize())
|
||||
.commit()
|
||||
liveMobileCoinLedger.postValue(ledger)
|
||||
}
|
||||
|
||||
fun mobileCoinLatestFullLedger(): MobileCoinLedgerWrapper {
|
||||
val blob = store.getBlob(MOB_LEDGER, null) ?: return MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance())
|
||||
return try {
|
||||
MobileCoinLedgerWrapper(MobileCoinLedger.parseFrom(blob))
|
||||
} catch (e: InvalidProtocolBufferException) {
|
||||
Log.w(TAG, "Bad cached ledger, clearing", e)
|
||||
setMobileCoinFullLedger(MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance()))
|
||||
throw AssertionError(e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun determineCurrency(): Currency {
|
||||
val localE164: String = SignalStore.account().e164 ?: ""
|
||||
|
||||
return Util.firstNonNull(
|
||||
CurrencyUtil.getCurrencyByE164(localE164),
|
||||
CurrencyUtil.getCurrencyByLocale(Locale.getDefault()),
|
||||
Currency.getInstance(DEFAULT_CURRENCY_CODE)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not trigger a storage sync.
|
||||
*/
|
||||
fun setEnabledAndEntropy(enabled: Boolean, entropy: Entropy?) {
|
||||
val writer = store.beginWrite()
|
||||
|
||||
if (entropy != null) {
|
||||
writer.putBlob(PAYMENTS_ENTROPY, entropy.bytes)
|
||||
}
|
||||
|
||||
writer.putBoolean(MOB_PAYMENTS_ENABLED, enabled).commit()
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun restoreWallet(mnemonic: String): WalletRestoreResult {
|
||||
val entropyFromMnemonic: ByteArray = try {
|
||||
Mnemonics.bip39EntropyFromMnemonic(mnemonic)
|
||||
} catch (e: BadMnemonicException) {
|
||||
return WalletRestoreResult.MNEMONIC_ERROR
|
||||
}
|
||||
|
||||
val paymentsEntropy = paymentsEntropy
|
||||
|
||||
if (paymentsEntropy != null) {
|
||||
val existingEntropy = paymentsEntropy.bytes
|
||||
if (Arrays.equals(existingEntropy, entropyFromMnemonic)) {
|
||||
setMobileCoinPaymentsEnabled(true)
|
||||
setUserConfirmedMnemonic(true)
|
||||
return WalletRestoreResult.ENTROPY_UNCHANGED
|
||||
}
|
||||
}
|
||||
|
||||
store.beginWrite()
|
||||
.putBlob(PAYMENTS_ENTROPY, entropyFromMnemonic)
|
||||
.putBoolean(MOB_PAYMENTS_ENABLED, true)
|
||||
.remove(MOB_LEDGER)
|
||||
.putBoolean(USER_CONFIRMED_MNEMONIC, true)
|
||||
.commit()
|
||||
|
||||
liveMobileCoinLedger.postValue(MobileCoinLedgerWrapper(MobileCoinLedger.getDefaultInstance()))
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
|
||||
return WalletRestoreResult.ENTROPY_CHANGED
|
||||
}
|
||||
|
||||
enum class WalletRestoreResult {
|
||||
ENTROPY_CHANGED, ENTROPY_UNCHANGED, MNEMONIC_ERROR
|
||||
}
|
||||
|
||||
private fun userHasLargeBalance(): Boolean {
|
||||
return mobileCoinLatestBalance().fullAmount.requireMobileCoin().greaterThan(LARGE_BALANCE_THRESHOLD)
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceDataStore;
|
||||
|
||||
import org.thoughtcrime.securesms.database.KeyValueDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
||||
|
||||
|
@ -15,9 +16,9 @@ import java.util.List;
|
|||
*/
|
||||
public final class SignalStore {
|
||||
|
||||
private static final SignalStore INSTANCE = new SignalStore();
|
||||
private KeyValueStore store;
|
||||
|
||||
private final KeyValueStore store;
|
||||
private final AccountValues accountValues;
|
||||
private final KbsValues kbsValues;
|
||||
private final RegistrationValues registrationValues;
|
||||
private final PinValues pinValues;
|
||||
|
@ -40,8 +41,23 @@ public final class SignalStore {
|
|||
private final ChatColorsValues chatColorsValues;
|
||||
private final ImageEditorValues imageEditorValues;
|
||||
|
||||
private SignalStore() {
|
||||
this.store = new KeyValueStore(ApplicationDependencies.getApplication());
|
||||
private static volatile SignalStore instance;
|
||||
|
||||
private static @NonNull SignalStore getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (SignalStore.class) {
|
||||
if (instance == null) {
|
||||
instance = new SignalStore(new KeyValueStore(KeyValueDatabase.getInstance(ApplicationDependencies.getApplication())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private SignalStore(@NonNull KeyValueStore store) {
|
||||
this.store = store;
|
||||
this.accountValues = new AccountValues(store);
|
||||
this.kbsValues = new KbsValues(store);
|
||||
this.registrationValues = new RegistrationValues(store);
|
||||
this.pinValues = new PinValues(store);
|
||||
|
@ -66,6 +82,7 @@ public final class SignalStore {
|
|||
}
|
||||
|
||||
public static void onFirstEverAppLaunch() {
|
||||
account().onFirstEverAppLaunch();
|
||||
kbsValues().onFirstEverAppLaunch();
|
||||
registrationValues().onFirstEverAppLaunch();
|
||||
pinValues().onFirstEverAppLaunch();
|
||||
|
@ -91,6 +108,7 @@ public final class SignalStore {
|
|||
|
||||
public static List<String> getKeysToIncludeInBackup() {
|
||||
List<String> keys = new ArrayList<>();
|
||||
keys.addAll(account().getKeysToIncludeInBackup());
|
||||
keys.addAll(kbsValues().getKeysToIncludeInBackup());
|
||||
keys.addAll(registrationValues().getKeysToIncludeInBackup());
|
||||
keys.addAll(pinValues().getKeysToIncludeInBackup());
|
||||
|
@ -121,91 +139,95 @@ public final class SignalStore {
|
|||
*/
|
||||
@VisibleForTesting
|
||||
public static void resetCache() {
|
||||
INSTANCE.store.resetCache();
|
||||
getInstance().store.resetCache();
|
||||
}
|
||||
|
||||
public static @NonNull AccountValues account() {
|
||||
return getInstance().accountValues;
|
||||
}
|
||||
|
||||
public static @NonNull KbsValues kbsValues() {
|
||||
return INSTANCE.kbsValues;
|
||||
return getInstance().kbsValues;
|
||||
}
|
||||
|
||||
public static @NonNull RegistrationValues registrationValues() {
|
||||
return INSTANCE.registrationValues;
|
||||
return getInstance().registrationValues;
|
||||
}
|
||||
|
||||
public static @NonNull PinValues pinValues() {
|
||||
return INSTANCE.pinValues;
|
||||
return getInstance().pinValues;
|
||||
}
|
||||
|
||||
public static @NonNull RemoteConfigValues remoteConfigValues() {
|
||||
return INSTANCE.remoteConfigValues;
|
||||
return getInstance().remoteConfigValues;
|
||||
}
|
||||
|
||||
public static @NonNull StorageServiceValues storageService() {
|
||||
return INSTANCE.storageServiceValues;
|
||||
return getInstance().storageServiceValues;
|
||||
}
|
||||
|
||||
public static @NonNull UiHints uiHints() {
|
||||
return INSTANCE.uiHints;
|
||||
return getInstance().uiHints;
|
||||
}
|
||||
|
||||
public static @NonNull TooltipValues tooltips() {
|
||||
return INSTANCE.tooltipValues;
|
||||
return getInstance().tooltipValues;
|
||||
}
|
||||
|
||||
public static @NonNull MiscellaneousValues misc() {
|
||||
return INSTANCE.misc;
|
||||
return getInstance().misc;
|
||||
}
|
||||
|
||||
public static @NonNull InternalValues internalValues() {
|
||||
return INSTANCE.internalValues;
|
||||
return getInstance().internalValues;
|
||||
}
|
||||
|
||||
public static @NonNull EmojiValues emojiValues() {
|
||||
return INSTANCE.emojiValues;
|
||||
return getInstance().emojiValues;
|
||||
}
|
||||
|
||||
public static @NonNull SettingsValues settings() {
|
||||
return INSTANCE.settingsValues;
|
||||
return getInstance().settingsValues;
|
||||
}
|
||||
|
||||
public static @NonNull CertificateValues certificateValues() {
|
||||
return INSTANCE.certificateValues;
|
||||
return getInstance().certificateValues;
|
||||
}
|
||||
|
||||
public static @NonNull PhoneNumberPrivacyValues phoneNumberPrivacy() {
|
||||
return INSTANCE.phoneNumberPrivacyValues;
|
||||
return getInstance().phoneNumberPrivacyValues;
|
||||
}
|
||||
|
||||
public static @NonNull OnboardingValues onboarding() {
|
||||
return INSTANCE.onboardingValues;
|
||||
return getInstance().onboardingValues;
|
||||
}
|
||||
|
||||
public static @NonNull WallpaperValues wallpaper() {
|
||||
return INSTANCE.wallpaperValues;
|
||||
return getInstance().wallpaperValues;
|
||||
}
|
||||
|
||||
public static @NonNull PaymentsValues paymentsValues() {
|
||||
return INSTANCE.paymentsValues;
|
||||
return getInstance().paymentsValues;
|
||||
}
|
||||
|
||||
public static @NonNull DonationsValues donationsValues() {
|
||||
return INSTANCE.donationsValues;
|
||||
return getInstance().donationsValues;
|
||||
}
|
||||
|
||||
public static @NonNull ProxyValues proxy() {
|
||||
return INSTANCE.proxyValues;
|
||||
return getInstance().proxyValues;
|
||||
}
|
||||
|
||||
public static @NonNull RateLimitValues rateLimit() {
|
||||
return INSTANCE.rateLimitValues;
|
||||
return getInstance().rateLimitValues;
|
||||
}
|
||||
|
||||
public static @NonNull ChatColorsValues chatColorsValues() {
|
||||
return INSTANCE.chatColorsValues;
|
||||
return getInstance().chatColorsValues;
|
||||
}
|
||||
|
||||
public static @NonNull ImageEditorValues imageEditorValues() {
|
||||
return INSTANCE.imageEditorValues;
|
||||
return getInstance().imageEditorValues;
|
||||
}
|
||||
|
||||
public static @NonNull GroupsV2AuthorizationSignalStoreCache groupsV2AuthorizationCache() {
|
||||
|
@ -225,6 +247,14 @@ public final class SignalStore {
|
|||
}
|
||||
|
||||
private static @NonNull KeyValueStore getStore() {
|
||||
return INSTANCE.store;
|
||||
return getInstance().store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to set a custom KeyValueStore to read from. Only for testing!
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static void inject(@NonNull KeyValueStore store) {
|
||||
instance = new SignalStore(store);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.AppCapabilities;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.account.AccountAttributes;
|
||||
|
@ -18,11 +19,11 @@ public final class LogSectionCapabilities implements LogSection {
|
|||
|
||||
@Override
|
||||
public @NonNull CharSequence getContent(@NonNull Context context) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
return "Unregistered";
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.getLocalNumber(context) == null || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
if (SignalStore.account().getE164() == null || SignalStore.account().getAci() == null) {
|
||||
return "Self not yet available!";
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ final class LogSectionKeyPreferences implements LogSection {
|
|||
.append("Prefer Contact Photos: ").append(SignalStore.settings().isPreferSystemContactPhotos()).append("\n")
|
||||
.append("Call Bandwidth Mode : ").append(SignalStore.settings().getCallBandwidthMode()).append("\n")
|
||||
.append("Client Deprecated : ").append(SignalStore.misc().isClientDeprecated()).append("\n")
|
||||
.append("Push Registered : ").append(TextSecurePreferences.isPushRegistered(context)).append("\n")
|
||||
.append("Push Registered : ").append(SignalStore.account().isRegistered()).append("\n")
|
||||
.append("Unauthorized Received: ").append(TextSecurePreferences.isUnauthorizedRecieved(context)).append("\n")
|
||||
.append("self.isRegistered() : ").append(TextSecurePreferences.getLocalAci(context) == null ? "false" : Recipient.self().isRegistered()).append("\n")
|
||||
.append("self.isRegistered() : ").append(SignalStore.account().getAci() == null ? "false" : Recipient.self().isRegistered()).append("\n")
|
||||
.append("Thread Trimming : ").append(getThreadTrimmingString()).append("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@ import com.google.android.gms.common.ConnectionResult;
|
|||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.emoji.EmojiFiles;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.AppSignatureUtil;
|
||||
import org.thoughtcrime.securesms.util.ByteUnit;
|
||||
import org.thoughtcrime.securesms.util.CensorshipUtil;
|
||||
import org.thoughtcrime.securesms.util.DeviceProperties;
|
||||
import org.thoughtcrime.securesms.util.ScreenDensity;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
@ -31,7 +31,6 @@ import org.whispersystems.signalservice.api.push.ACI;
|
|||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LogSectionSystemInfo implements LogSection {
|
||||
|
||||
|
@ -63,9 +62,9 @@ public class LogSectionSystemInfo implements LogSection {
|
|||
builder.append("OS Host : ").append(Build.HOST).append("\n");
|
||||
builder.append("RecipientId : ").append(SignalStore.registrationValues().isRegistrationComplete() ? Recipient.self().getId() : "N/A").append("\n");
|
||||
builder.append("ACI : ").append(getCensoredAci(context)).append("\n");
|
||||
builder.append("Censored : ").append(CensorshipUtil.isCensored(context)).append("\n");
|
||||
builder.append("Censored : ").append(ApplicationDependencies.getSignalServiceNetworkAccess().isCensored()).append("\n");
|
||||
builder.append("Play Services : ").append(getPlayServicesString(context)).append("\n");
|
||||
builder.append("FCM : ").append(!TextSecurePreferences.isFcmDisabled(context)).append("\n");
|
||||
builder.append("FCM : ").append(SignalStore.account().isFcmEnabled()).append("\n");
|
||||
builder.append("BkgRestricted : ").append(Build.VERSION.SDK_INT >= 28 ? DeviceProperties.isBackgroundRestricted(context) : "N/A").append("\n");
|
||||
builder.append("Locale : ").append(Locale.getDefault().toString()).append("\n");
|
||||
builder.append("Linked Devices: ").append(TextSecurePreferences.isMultiDevice(context)).append("\n");
|
||||
|
@ -165,7 +164,7 @@ public class LogSectionSystemInfo implements LogSection {
|
|||
}
|
||||
|
||||
private static String getCensoredAci(@NonNull Context context) {
|
||||
ACI aci = TextSecurePreferences.getLocalAci(context);
|
||||
ACI aci = SignalStore.account().getAci();
|
||||
|
||||
if (aci != null) {
|
||||
String aciString = aci.toString();
|
||||
|
|
|
@ -20,7 +20,7 @@ final class SignalPinReminderSchedule implements MegaphoneSchedule {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(ApplicationDependencies.getApplication())) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public class BackgroundMessageRetriever {
|
|||
*/
|
||||
@WorkerThread
|
||||
public boolean retrieveMessages(@NonNull Context context, long showNotificationAfterMs, MessageRetrievalStrategy... strategies) {
|
||||
if (shouldIgnoreFetch(context)) {
|
||||
if (shouldIgnoreFetch()) {
|
||||
Log.i(TAG, "Skipping retrieval -- app is in the foreground.");
|
||||
return true;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class BackgroundMessageRetriever {
|
|||
boolean success = false;
|
||||
|
||||
for (MessageRetrievalStrategy strategy : strategies) {
|
||||
if (shouldIgnoreFetch(context)) {
|
||||
if (shouldIgnoreFetch()) {
|
||||
Log.i(TAG, "Stopping further strategy attempts -- app is in the foreground." + logSuffix(startTime));
|
||||
success = true;
|
||||
break;
|
||||
|
@ -121,9 +121,9 @@ public class BackgroundMessageRetriever {
|
|||
* @return True if there is no need to execute a message fetch, because the websocket will take
|
||||
* care of it.
|
||||
*/
|
||||
public static boolean shouldIgnoreFetch(@NonNull Context context) {
|
||||
public static boolean shouldIgnoreFetch() {
|
||||
return ApplicationDependencies.getAppForegroundObserver().isForegrounded() &&
|
||||
!ApplicationDependencies.getSignalServiceNetworkAccess().isCensored(context);
|
||||
!ApplicationDependencies.getSignalServiceNetworkAccess().isCensored();
|
||||
}
|
||||
|
||||
private static String logSuffix(long startTime) {
|
||||
|
|
|
@ -40,6 +40,11 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* The application-level manager of our websocket connection.
|
||||
*
|
||||
* This class is responsible for opening/closing the websocket based on the app's state and observing new inbound messages received on the websocket.
|
||||
*/
|
||||
public class IncomingMessageObserver {
|
||||
|
||||
private static final String TAG = Log.tag(IncomingMessageObserver.class);
|
||||
|
@ -71,7 +76,7 @@ public class IncomingMessageObserver {
|
|||
|
||||
new MessageRetrievalThread().start();
|
||||
|
||||
if (TextSecurePreferences.isFcmDisabled(context)) {
|
||||
if (!SignalStore.account().isFcmEnabled()) {
|
||||
ContextCompat.startForegroundService(context, new Intent(context, ForegroundService.class));
|
||||
}
|
||||
|
||||
|
@ -117,7 +122,7 @@ public class IncomingMessageObserver {
|
|||
}
|
||||
|
||||
public boolean isDecryptionDrained() {
|
||||
return decryptionDrained || networkAccess.isCensored(context);
|
||||
return decryptionDrained || networkAccess.isCensored();
|
||||
}
|
||||
|
||||
public void notifyDecryptionsDrained() {
|
||||
|
@ -147,20 +152,18 @@ public class IncomingMessageObserver {
|
|||
}
|
||||
|
||||
private synchronized boolean isConnectionNecessary() {
|
||||
boolean registered = TextSecurePreferences.isPushRegistered(context);
|
||||
boolean websocketRegistered = TextSecurePreferences.isWebsocketRegistered(context);
|
||||
boolean isGcmDisabled = TextSecurePreferences.isFcmDisabled(context);
|
||||
boolean hasNetwork = NetworkConstraint.isMet(context);
|
||||
boolean hasProxy = SignalStore.proxy().isProxyEnabled();
|
||||
boolean registered = SignalStore.account().isRegistered();
|
||||
boolean fcmEnabled = SignalStore.account().isFcmEnabled();
|
||||
boolean hasNetwork = NetworkConstraint.isMet(context);
|
||||
boolean hasProxy = SignalStore.proxy().isProxyEnabled();
|
||||
|
||||
Log.d(TAG, String.format("Network: %s, Foreground: %s, FCM: %s, Censored: %s, Registered: %s, Websocket Registered: %s, Proxy: %s",
|
||||
hasNetwork, appVisible, !isGcmDisabled, networkAccess.isCensored(context), registered, websocketRegistered, hasProxy));
|
||||
Log.d(TAG, String.format("Network: %s, Foreground: %s, FCM: %s, Censored: %s, Registered: %s, Proxy: %s",
|
||||
hasNetwork, appVisible, fcmEnabled, networkAccess.isCensored(), registered, hasProxy));
|
||||
|
||||
return registered &&
|
||||
websocketRegistered &&
|
||||
(appVisible || isGcmDisabled) &&
|
||||
hasNetwork &&
|
||||
!networkAccess.isCensored(context);
|
||||
return registered &&
|
||||
(appVisible || !fcmEnabled) &&
|
||||
hasNetwork &&
|
||||
!networkAccess.isCensored();
|
||||
}
|
||||
|
||||
private synchronized void waitForConnectionNecessary() {
|
||||
|
|
|
@ -78,7 +78,7 @@ public final class MessageDecryptionUtil {
|
|||
*/
|
||||
public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) {
|
||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), Optional.of(TextSecurePreferences.getLocalNumber(context)));
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
|
||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator());
|
||||
List<Job> jobs = new LinkedList<>();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class AccountRecordMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null) {
|
||||
Log.w(TAG, "Not registered!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -45,7 +46,7 @@ public class ApplyUnknownFieldsToSelfMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null) {
|
||||
Log.w(TAG, "Not registered!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ public final class DirectoryRefreshMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
public void performMigration() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
if (!SignalStore.account().isRegistered() ||
|
||||
!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
TextSecurePreferences.getLocalAci(context) == null)
|
||||
SignalStore.account().getAci() == null)
|
||||
{
|
||||
Log.w(TAG, "Not registered! Skipping.");
|
||||
return;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
|
|||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
|
@ -190,7 +191,7 @@ public class LegacyMigrationJob extends MigrationJob {
|
|||
}
|
||||
|
||||
if (lastSeenVersion < INTERNALIZE_CONTACTS) {
|
||||
if (TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (SignalStore.account().isRegistered()) {
|
||||
TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
|
||||
}
|
||||
}
|
||||
|
@ -239,11 +240,6 @@ public class LegacyMigrationJob extends MigrationJob {
|
|||
}
|
||||
|
||||
if (lastSeenVersion < UNIDENTIFIED_DELIVERY) {
|
||||
if (TextSecurePreferences.isMultiDevice(context)) {
|
||||
Log.i(TAG, "MultiDevice: Disabling UD (will be re-enabled if possible after pending refresh).");
|
||||
TextSecurePreferences.setIsUnidentifiedDeliveryEnabled(context, false);
|
||||
}
|
||||
|
||||
Log.i(TAG, "Scheduling UD attributes refresh.");
|
||||
ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
|||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceKeysUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -42,7 +43,7 @@ public class StorageServiceMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (TextSecurePreferences.getLocalAci(context) == null) {
|
||||
if (SignalStore.account().getAci() == null) {
|
||||
Log.w(TAG, "Self not yet available.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,9 +56,9 @@ public class UserNotificationMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
TextSecurePreferences.getLocalNumber(context) == null ||
|
||||
TextSecurePreferences.getLocalAci(context) == null)
|
||||
if (!SignalStore.account().isRegistered() ||
|
||||
SignalStore.account().getE164() == null ||
|
||||
SignalStore.account().getAci() == null)
|
||||
{
|
||||
Log.w(TAG, "Not registered! Skipping.");
|
||||
return;
|
||||
|
|
|
@ -11,12 +11,14 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -51,7 +53,7 @@ public class UuidMigrationJob extends MigrationJob {
|
|||
|
||||
@Override
|
||||
void performMigration() throws Exception {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) {
|
||||
if (!SignalStore.account().isRegistered() || TextUtils.isEmpty(SignalStore.account().getE164())) {
|
||||
Log.w(TAG, "Not registered! Skipping migration, as it wouldn't do anything.");
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +68,7 @@ public class UuidMigrationJob extends MigrationJob {
|
|||
}
|
||||
|
||||
private static void ensureSelfRecipientExists(@NonNull Context context) {
|
||||
DatabaseFactory.getRecipientDatabase(context).getOrInsertFromE164(TextSecurePreferences.getLocalNumber(context));
|
||||
DatabaseFactory.getRecipientDatabase(context).getOrInsertFromE164(Objects.requireNonNull(SignalStore.account().getE164()));
|
||||
}
|
||||
|
||||
private static void fetchOwnUuid(@NonNull Context context) throws IOException {
|
||||
|
@ -74,7 +76,7 @@ public class UuidMigrationJob extends MigrationJob {
|
|||
ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci();
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).markRegisteredOrThrow(self, localUuid);
|
||||
TextSecurePreferences.setLocalAci(context, localUuid);
|
||||
SignalStore.account().setAci(localUuid);
|
||||
}
|
||||
|
||||
public static class Factory implements Job.Factory<UuidMigrationJob> {
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -17,7 +18,7 @@ public enum ReplyMethod {
|
|||
public static @NonNull ReplyMethod forRecipient(Context context, Recipient recipient) {
|
||||
if (recipient.isGroup()) {
|
||||
return ReplyMethod.GroupMessage;
|
||||
} else if (TextSecurePreferences.isPushRegistered(context) && recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED && !recipient.isForceSmsSelection()) {
|
||||
} else if (SignalStore.account().isRegistered() && recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED && !recipient.isForceSmsSelection()) {
|
||||
return ReplyMethod.SecureMessage;
|
||||
} else {
|
||||
return ReplyMethod.UnsecuredSmsMessage;
|
||||
|
|
|
@ -14,6 +14,8 @@ import com.google.i18n.phonenumbers.ShortNumberInfo;
|
|||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -48,9 +50,9 @@ public class PhoneNumberFormatter {
|
|||
private final Pattern ALPHA_PATTERN = Pattern.compile("[a-zA-Z]");
|
||||
|
||||
public static @NonNull PhoneNumberFormatter get(Context context) {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
|
||||
if (!TextUtils.isEmpty(localNumber)) {
|
||||
if (!Util.isEmpty(localNumber)) {
|
||||
Pair<String, PhoneNumberFormatter> cached = cachedFormatter.get();
|
||||
|
||||
if (cached != null && cached.first().equals(localNumber)) return cached.second();
|
||||
|
|
|
@ -32,10 +32,10 @@ public class EditProxyViewModel extends ViewModel {
|
|||
this.events = new SingleLiveEvent<>();
|
||||
this.uiState = new MutableLiveData<>();
|
||||
this.saveState = new MutableLiveData<>(SaveState.IDLE);
|
||||
this.pipeState = TextSecurePreferences.getLocalNumber(ApplicationDependencies.getApplication()) == null ? new MutableLiveData<>()
|
||||
: fromPublisher(ApplicationDependencies.getSignalWebSocket()
|
||||
.getWebSocketState()
|
||||
.toFlowable(BackpressureStrategy.LATEST));
|
||||
this.pipeState = SignalStore.account().getE164() == null ? new MutableLiveData<>()
|
||||
: fromPublisher(ApplicationDependencies.getSignalWebSocket()
|
||||
.getWebSocketState()
|
||||
.toFlowable(BackpressureStrategy.LATEST));
|
||||
|
||||
if (SignalStore.proxy().isProxyEnabled()) {
|
||||
uiState.setValue(UiState.ALL_ENABLED);
|
||||
|
|
|
@ -307,8 +307,8 @@ public class SignalServiceNetworkAccess {
|
|||
this.censoredCountries = this.censorshipConfiguration.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
public SignalServiceConfiguration getConfiguration(Context context) {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
public SignalServiceConfiguration getConfiguration() {
|
||||
String localNumber = SignalStore.account().getE164();
|
||||
return getConfiguration(localNumber);
|
||||
}
|
||||
|
||||
|
@ -330,8 +330,8 @@ public class SignalServiceNetworkAccess {
|
|||
return this.uncensoredConfiguration;
|
||||
}
|
||||
|
||||
public boolean isCensored(Context context) {
|
||||
return getConfiguration(context) != this.uncensoredConfiguration;
|
||||
public boolean isCensored() {
|
||||
return getConfiguration() != this.uncensoredConfiguration;
|
||||
}
|
||||
|
||||
public boolean isCensored(String number) {
|
||||
|
|
|
@ -153,8 +153,8 @@ public final class LiveRecipientCache {
|
|||
}
|
||||
|
||||
if (selfId == null) {
|
||||
ACI localAci = TextSecurePreferences.getLocalAci(context);
|
||||
String localE164 = TextSecurePreferences.getLocalNumber(context);
|
||||
ACI localAci = SignalStore.account().getAci();
|
||||
String localE164 = SignalStore.account().getE164();
|
||||
|
||||
if (localAci != null) {
|
||||
selfId = recipientDatabase.getByAci(localAci).or(recipientDatabase.getByE164(localE164)).orNull();
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
@ -200,13 +201,13 @@ public class RecipientDetails {
|
|||
|
||||
public static @NonNull RecipientDetails forIndividual(@NonNull Context context, @NonNull RecipientSettings settings) {
|
||||
boolean systemContact = !settings.getSystemProfileName().isEmpty();
|
||||
boolean isSelf = (settings.getE164() != null && settings.getE164().equals(TextSecurePreferences.getLocalNumber(context))) ||
|
||||
(settings.getAci() != null && settings.getAci().equals(TextSecurePreferences.getLocalAci(context)));
|
||||
boolean isSelf = (settings.getE164() != null && settings.getE164().equals(SignalStore.account().getE164())) ||
|
||||
(settings.getAci() != null && settings.getAci().equals(SignalStore.account().getAci()));
|
||||
|
||||
RegisteredState registeredState = settings.getRegistered();
|
||||
|
||||
if (isSelf) {
|
||||
if (TextSecurePreferences.isPushRegistered(context) && !TextSecurePreferences.isUnauthorizedRecieved(context)) {
|
||||
if (SignalStore.account().isRegistered() && !TextSecurePreferences.isUnauthorizedRecieved(context)) {
|
||||
registeredState = RegisteredState.REGISTERED;
|
||||
} else {
|
||||
registeredState = RegisteredState.NOT_REGISTERED;
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.RotateCertificateJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.pin.PinState;
|
||||
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
@ -63,10 +64,10 @@ public final class RegistrationRepository {
|
|||
}
|
||||
|
||||
public int getRegistrationId() {
|
||||
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
int registrationId = SignalStore.account().getRegistrationId();
|
||||
if (registrationId == 0) {
|
||||
registrationId = KeyHelper.generateRegistrationId(false);
|
||||
TextSecurePreferences.setLocalRegistrationId(context, registrationId);
|
||||
SignalStore.account().setRegistrationId(registrationId);
|
||||
}
|
||||
return registrationId;
|
||||
}
|
||||
|
@ -148,14 +149,13 @@ public final class RegistrationRepository {
|
|||
recipientDatabase.setProfileSharing(selfId, true);
|
||||
recipientDatabase.markRegisteredOrThrow(selfId, aci);
|
||||
|
||||
TextSecurePreferences.setLocalNumber(context, registrationData.getE164());
|
||||
TextSecurePreferences.setLocalAci(context, aci);
|
||||
SignalStore.account().setE164(registrationData.getE164());
|
||||
SignalStore.account().setAci(aci);
|
||||
recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey());
|
||||
ApplicationDependencies.getRecipientCache().clearSelf();
|
||||
|
||||
TextSecurePreferences.setFcmToken(context, registrationData.getFcmToken());
|
||||
TextSecurePreferences.setFcmDisabled(context, registrationData.isNotFcm());
|
||||
TextSecurePreferences.setWebsocketRegistered(context, true);
|
||||
SignalStore.account().setFcmToken(registrationData.getFcmToken());
|
||||
SignalStore.account().setFcmEnabled(registrationData.isFcm());
|
||||
|
||||
ApplicationDependencies.getIdentityStore()
|
||||
.saveIdentityWithoutSideEffects(selfId,
|
||||
|
@ -165,8 +165,8 @@ public final class RegistrationRepository {
|
|||
System.currentTimeMillis(),
|
||||
true);
|
||||
|
||||
TextSecurePreferences.setPushServerPassword(context, registrationData.getPassword());
|
||||
TextSecurePreferences.setPushRegistered(context, true);
|
||||
SignalStore.account().setServicePassword(registrationData.getPassword());
|
||||
SignalStore.account().setRegistered(true);
|
||||
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
||||
TextSecurePreferences.setPromptedPushRegistration(context, true);
|
||||
TextSecurePreferences.setUnauthorizedReceived(context, false);
|
||||
|
|
|
@ -25,7 +25,7 @@ public final class RegistrationUtil {
|
|||
*/
|
||||
public static void maybeMarkRegistrationComplete(@NonNull Context context) {
|
||||
if (!SignalStore.registrationValues().isRegistrationComplete() &&
|
||||
TextSecurePreferences.isPushRegistered(context) &&
|
||||
SignalStore.account().isRegistered() &&
|
||||
!Recipient.self().getProfileName().isEmpty() &&
|
||||
(SignalStore.kbsValues().hasPin() || SignalStore.kbsValues().hasOptedOut()))
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.LoggingFragment;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.LabeledEditText;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountRepository.Mode;
|
||||
import org.thoughtcrime.securesms.registration.util.RegistrationNumberInputController;
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState;
|
||||
|
@ -221,7 +222,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
|||
NavController navController = NavHostFragment.findNavController(this);
|
||||
|
||||
Disposable request = viewModel.requestVerificationCode(mode)
|
||||
.doOnSubscribe(unused -> TextSecurePreferences.setPushRegistered(ApplicationDependencies.getApplication(), false))
|
||||
.doOnSubscribe(unused -> SignalStore.account().setRegistered(false))
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(processor -> {
|
||||
if (processor.hasResult()) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
|||
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class DirectoryRefreshListener extends PersistentAlarmManagerListener {
|
|||
|
||||
@Override
|
||||
protected long onAlarm(Context context, long scheduledTime) {
|
||||
if (scheduledTime != 0 && TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (scheduledTime != 0 && SignalStore.account().isRegistered()) {
|
||||
ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(true));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
|||
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -21,7 +22,7 @@ public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener {
|
|||
|
||||
@Override
|
||||
protected long onAlarm(Context context, long scheduledTime) {
|
||||
if (scheduledTime != 0 && TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (scheduledTime != 0 && SignalStore.account().isRegistered()) {
|
||||
ApplicationDependencies.getJobManager().add(new RotateSignedPreKeyJob());
|
||||
}
|
||||
|
||||
|
|
|
@ -459,7 +459,7 @@ public class MessageSender {
|
|||
}
|
||||
|
||||
private static boolean isPushTextSend(Context context, Recipient recipient, boolean keyExchange) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ public class MessageSender {
|
|||
}
|
||||
|
||||
private static boolean isPushMediaSend(Context context, Recipient recipient) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!SignalStore.account().isRegistered()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -503,10 +503,10 @@ public class MessageSender {
|
|||
}
|
||||
|
||||
public static boolean isLocalSelfSend(@NonNull Context context, @Nullable Recipient recipient, boolean forceSms) {
|
||||
return recipient != null &&
|
||||
recipient.isSelf() &&
|
||||
!forceSms &&
|
||||
TextSecurePreferences.isPushRegistered(context) &&
|
||||
return recipient != null &&
|
||||
recipient.isSelf() &&
|
||||
!forceSms &&
|
||||
SignalStore.account().isRegistered() &&
|
||||
!TextSecurePreferences.isMultiDevice(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ public final class StorageSyncHelper {
|
|||
.setPayments(SignalStore.paymentsValues().mobileCoinPaymentsEnabled(), Optional.fromNullable(SignalStore.paymentsValues().getPaymentsEntropy()).transform(Entropy::getBytes).orNull())
|
||||
.setPrimarySendsSms(Util.isDefaultSmsProvider(context))
|
||||
.setUniversalExpireTimer(SignalStore.settings().getUniversalExpireTimer())
|
||||
.setE164(TextSecurePreferences.getLocalNumber(context))
|
||||
.setE164(self.requireE164())
|
||||
.setDefaultReactions(SignalStore.emojiValues().getReactions())
|
||||
.setSubscriber(StorageSyncModels.localToRemoteSubscriber(SignalStore.donationsValues().getSubscriber()))
|
||||
.setDisplayBadgesOnProfile(SignalStore.donationsValues().getDisplayBadgesOnProfile())
|
||||
|
|
|
@ -16,7 +16,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
* A wrapper around {@link ProcessLifecycleOwner} that allows for safely adding/removing observers
|
||||
* on multiple threads.
|
||||
*/
|
||||
public final class AppForegroundObserver {
|
||||
public class AppForegroundObserver {
|
||||
|
||||
private final Set<Listener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
|
||||
public final class CensorshipUtil {
|
||||
|
||||
private CensorshipUtil() {}
|
||||
|
||||
public static boolean isCensored(@NonNull Context context) {
|
||||
return ApplicationDependencies.getSignalServiceNetworkAccess().isCensored(context);
|
||||
}
|
||||
}
|
|
@ -77,7 +77,7 @@ public final class SignalProxyUtil {
|
|||
public static boolean testWebsocketConnection(long timeout) {
|
||||
startListeningToWebsocket();
|
||||
|
||||
if (TextSecurePreferences.getLocalNumber(ApplicationDependencies.getApplication()) == null) {
|
||||
if (SignalStore.account().getE164() == null) {
|
||||
Log.i(TAG, "User is unregistered! Doing simple check.");
|
||||
return testWebsocketConnectionUnregistered(timeout);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ public class TextSecurePreferences {
|
|||
|
||||
private static final String TAG = Log.tag(TextSecurePreferences.class);
|
||||
|
||||
public static final String IDENTITY_PREF = "pref_choose_identity";
|
||||
public static final String CHANGE_PASSPHRASE_PREF = "pref_change_passphrase";
|
||||
public static final String DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase";
|
||||
public static final String THEME_PREF = "pref_theme";
|
||||
|
@ -64,7 +63,6 @@ public class TextSecurePreferences {
|
|||
|
||||
private static final String LAST_VERSION_CODE_PREF = "last_version_code";
|
||||
private static final String LAST_EXPERIENCE_VERSION_PREF = "last_experience_version_code";
|
||||
private static final String EXPERIENCE_DISMISSED_PREF = "experience_dismissed";
|
||||
public static final String RINGTONE_PREF = "pref_key_ringtone";
|
||||
public static final String VIBRATE_PREF = "pref_key_vibrate";
|
||||
private static final String NOTIFICATION_PREF = "pref_key_enable_notifications";
|
||||
|
@ -81,11 +79,6 @@ public class TextSecurePreferences {
|
|||
private static final String SMS_DELIVERY_REPORT_PREF = "pref_delivery_report_sms";
|
||||
public static final String MMS_USER_AGENT = "pref_mms_user_agent";
|
||||
private static final String MMS_CUSTOM_USER_AGENT = "pref_custom_mms_user_agent";
|
||||
private static final String LOCAL_NUMBER_PREF = "pref_local_number";
|
||||
private static final String LOCAL_ACI_PREF = "pref_local_uuid";
|
||||
private static final String LOCAL_USERNAME_PREF = "pref_local_username";
|
||||
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
|
||||
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
||||
private static final String SEEN_WELCOME_SCREEN_PREF = "pref_seen_welcome_screen";
|
||||
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
|
||||
private static final String PROMPTED_OPTIMIZE_DOZE_PREF = "pref_prompted_optimize_doze";
|
||||
|
@ -99,15 +92,9 @@ public class TextSecurePreferences {
|
|||
private static final String SHOW_INVITE_REMINDER_PREF = "pref_show_invite_reminder";
|
||||
public static final String MESSAGE_BODY_TEXT_SIZE_PREF = "pref_message_body_text_size";
|
||||
|
||||
private static final String LOCAL_REGISTRATION_ID_PREF = "pref_local_registration_id";
|
||||
private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered";
|
||||
private static final String WIFI_SMS_PREF = "pref_wifi_sms";
|
||||
|
||||
private static final String GCM_DISABLED_PREF = "pref_gcm_disabled";
|
||||
private static final String GCM_REGISTRATION_ID_PREF = "pref_gcm_registration_id";
|
||||
private static final String GCM_REGISTRATION_ID_VERSION_PREF = "pref_gcm_registration_id_version";
|
||||
private static final String GCM_REGISTRATION_ID_TIME_PREF = "pref_gcm_registration_id_last_set_time";
|
||||
private static final String WEBSOCKET_REGISTERED_PREF = "pref_websocket_registered";
|
||||
private static final String RATING_LATER_PREF = "pref_rating_later";
|
||||
private static final String RATING_ENABLED_PREF = "pref_rating_enabled";
|
||||
private static final String SIGNED_PREKEY_FAILURE_COUNT_PREF = "pref_signed_prekey_failure_count";
|
||||
|
@ -128,8 +115,6 @@ public class TextSecurePreferences {
|
|||
private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device";
|
||||
public static final String DIRECT_CAPTURE_CAMERA_ID = "pref_direct_capture_camera_id";
|
||||
public static final String ALWAYS_RELAY_CALLS_PREF = "pref_turn_only";
|
||||
private static final String PROFILE_NAME_PREF = "pref_profile_name";
|
||||
private static final String PROFILE_AVATAR_ID_PREF = "pref_profile_avatar_id";
|
||||
public static final String READ_RECEIPTS_PREF = "pref_read_receipts";
|
||||
public static final String INCOGNITO_KEYBORAD_PREF = "pref_incognito_keyboard";
|
||||
private static final String UNAUTHORIZED_RECEIVED = "pref_unauthorized_received";
|
||||
|
@ -195,8 +180,6 @@ public class TextSecurePreferences {
|
|||
|
||||
public static final String LINK_PREVIEWS = "pref_link_previews";
|
||||
|
||||
private static final String GIF_GRID_LAYOUT = "pref_gif_grid_layout";
|
||||
|
||||
private static final String SEEN_STICKER_INTRO_TOOLTIP = "pref_seen_sticker_intro_tooltip";
|
||||
|
||||
private static final String MEDIA_KEYBOARD_MODE = "pref_media_keyboard_mode";
|
||||
|
@ -533,14 +516,6 @@ public class TextSecurePreferences {
|
|||
return getBooleanPreference(context, ALWAYS_RELAY_CALLS_PREF, false);
|
||||
}
|
||||
|
||||
public static boolean isFcmDisabled(Context context) {
|
||||
return getBooleanPreference(context, GCM_DISABLED_PREF, false);
|
||||
}
|
||||
|
||||
public static void setFcmDisabled(Context context, boolean disabled) {
|
||||
setBooleanPreference(context, GCM_DISABLED_PREF, disabled);
|
||||
}
|
||||
|
||||
public static boolean isWebrtcCallingEnabled(Context context) {
|
||||
return getBooleanPreference(context, WEBRTC_CALLING_PREF, false);
|
||||
}
|
||||
|
@ -599,14 +574,6 @@ public class TextSecurePreferences {
|
|||
setBooleanPreference(context, RATING_ENABLED_PREF, enabled);
|
||||
}
|
||||
|
||||
public static boolean isWebsocketRegistered(Context context) {
|
||||
return getBooleanPreference(context, WEBSOCKET_REGISTERED_PREF, false);
|
||||
}
|
||||
|
||||
public static void setWebsocketRegistered(Context context, boolean registered) {
|
||||
setBooleanPreference(context, WEBSOCKET_REGISTERED_PREF, registered);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isWifiSmsEnabled(Context context) {
|
||||
return getBooleanPreference(context, WIFI_SMS_PREF, false);
|
||||
|
@ -630,37 +597,6 @@ public class TextSecurePreferences {
|
|||
setBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, value);
|
||||
}
|
||||
|
||||
public static void setFcmToken(Context context, String registrationId) {
|
||||
setStringPreference(context, GCM_REGISTRATION_ID_PREF, registrationId);
|
||||
setIntegerPrefrence(context, GCM_REGISTRATION_ID_VERSION_PREF, Util.getCanonicalVersionCode());
|
||||
}
|
||||
|
||||
public static String getFcmToken(Context context) {
|
||||
int storedRegistrationIdVersion = getIntegerPreference(context, GCM_REGISTRATION_ID_VERSION_PREF, 0);
|
||||
|
||||
if (storedRegistrationIdVersion != Util.getCanonicalVersionCode()) {
|
||||
return null;
|
||||
} else {
|
||||
return getStringPreference(context, GCM_REGISTRATION_ID_PREF, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static long getFcmTokenLastSetTime(Context context) {
|
||||
return getLongPreference(context, GCM_REGISTRATION_ID_TIME_PREF, 0);
|
||||
}
|
||||
|
||||
public static void setFcmTokenLastSetTime(Context context, long timestamp) {
|
||||
setLongPreference(context, GCM_REGISTRATION_ID_TIME_PREF, timestamp);
|
||||
}
|
||||
|
||||
public static int getLocalRegistrationId(Context context) {
|
||||
return getIntegerPreference(context, LOCAL_REGISTRATION_ID_PREF, 0);
|
||||
}
|
||||
|
||||
public static void setLocalRegistrationId(Context context, int registrationId) {
|
||||
setIntegerPrefrence(context, LOCAL_REGISTRATION_ID_PREF, registrationId);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isInThreadNotifications(Context context) {
|
||||
return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true);
|
||||
|
@ -690,10 +626,6 @@ public class TextSecurePreferences {
|
|||
setBooleanPreference(context, UNIDENTIFIED_DELIVERY_ENABLED, enabled);
|
||||
}
|
||||
|
||||
public static boolean isUnidentifiedDeliveryEnabled(Context context) {
|
||||
return getBooleanPreference(context, UNIDENTIFIED_DELIVERY_ENABLED, true);
|
||||
}
|
||||
|
||||
public static long getSignedPreKeyRotationTime(Context context) {
|
||||
return getLongPreference(context, SIGNED_PREKEY_ROTATION_TIME_PREF, 0L);
|
||||
}
|
||||
|
@ -734,30 +666,6 @@ public class TextSecurePreferences {
|
|||
return getStringPreference(context, UPDATE_APK_DIGEST, null);
|
||||
}
|
||||
|
||||
public static String getLocalNumber(Context context) {
|
||||
return getStringPreference(context, LOCAL_NUMBER_PREF, null);
|
||||
}
|
||||
|
||||
public static void setLocalNumber(Context context, String localNumber) {
|
||||
setStringPreference(context, LOCAL_NUMBER_PREF, localNumber);
|
||||
}
|
||||
|
||||
public static ACI getLocalAci(Context context) {
|
||||
return ACI.parseOrNull(getStringPreference(context, LOCAL_ACI_PREF, null));
|
||||
}
|
||||
|
||||
public static void setLocalAci(Context context, ACI aci) {
|
||||
setStringPreference(context, LOCAL_ACI_PREF, aci.toString());
|
||||
}
|
||||
|
||||
public static String getPushServerPassword(Context context) {
|
||||
return getStringPreference(context, GCM_PASSWORD_PREF, null);
|
||||
}
|
||||
|
||||
public static void setPushServerPassword(Context context, String password) {
|
||||
setStringPreference(context, GCM_PASSWORD_PREF, password);
|
||||
}
|
||||
|
||||
public static boolean isEnterImeKeyEnabled(Context context) {
|
||||
return getBooleanPreference(context, ENTER_PRESENT_PREF, false);
|
||||
}
|
||||
|
@ -867,14 +775,6 @@ public class TextSecurePreferences {
|
|||
else return defaultUserAgent;
|
||||
}
|
||||
|
||||
public static String getIdentityContactUri(Context context) {
|
||||
return getStringPreference(context, IDENTITY_PREF, null);
|
||||
}
|
||||
|
||||
public static void setIdentityContactUri(Context context, String identityUri) {
|
||||
setStringPreference(context, IDENTITY_PREF, identityUri);
|
||||
}
|
||||
|
||||
public static void setScreenSecurityEnabled(Context context, boolean value) {
|
||||
setBooleanPreference(context, SCREEN_SECURITY_PREF, value);
|
||||
}
|
||||
|
@ -905,14 +805,6 @@ public class TextSecurePreferences {
|
|||
setIntegerPrefrence(context, LAST_EXPERIENCE_VERSION_PREF, versionCode);
|
||||
}
|
||||
|
||||
public static int getExperienceDismissedVersionCode(Context context) {
|
||||
return getIntegerPreference(context, EXPERIENCE_DISMISSED_PREF, 0);
|
||||
}
|
||||
|
||||
public static void setExperienceDismissedVersionCode(Context context, int versionCode) {
|
||||
setIntegerPrefrence(context, EXPERIENCE_DISMISSED_PREF, versionCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link SettingsValues#getTheme()} via {@link org.thoughtcrime.securesms.keyvalue.SignalStore} instead.
|
||||
*/
|
||||
|
@ -920,26 +812,6 @@ public class TextSecurePreferences {
|
|||
return getStringPreference(context, THEME_PREF, DynamicTheme.systemThemeAvailable() ? DynamicTheme.SYSTEM : DynamicTheme.LIGHT);
|
||||
}
|
||||
|
||||
public static boolean isPushRegistered(Context context) {
|
||||
return getBooleanPreference(context, REGISTERED_GCM_PREF, false);
|
||||
}
|
||||
|
||||
public static void setPushRegistered(Context context, boolean registered) {
|
||||
Log.i(TAG, "Setting push registered: " + registered);
|
||||
boolean previous = isPushRegistered(context);
|
||||
|
||||
setBooleanPreference(context, REGISTERED_GCM_PREF, registered);
|
||||
ApplicationDependencies.getIncomingMessageObserver().notifyRegistrationChanged();
|
||||
|
||||
if (previous != registered) {
|
||||
Recipient.self().live().refresh();
|
||||
}
|
||||
|
||||
if (previous && !registered) {
|
||||
clearLocalCredentials(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isShowInviteReminders(Context context) {
|
||||
return getBooleanPreference(context, SHOW_INVITE_REMINDER_PREF, true);
|
||||
}
|
||||
|
@ -1269,7 +1141,7 @@ public class TextSecurePreferences {
|
|||
return PreferenceManager.getDefaultSharedPreferences(context).getString(key, defaultValue);
|
||||
}
|
||||
|
||||
private static int getIntegerPreference(Context context, String key, int defaultValue) {
|
||||
public static int getIntegerPreference(Context context, String key, int defaultValue) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context).getInt(key, defaultValue);
|
||||
}
|
||||
|
||||
|
@ -1281,7 +1153,7 @@ public class TextSecurePreferences {
|
|||
return PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(key, value).commit();
|
||||
}
|
||||
|
||||
private static long getLongPreference(Context context, String key, long defaultValue) {
|
||||
public static long getLongPreference(Context context, String key, long defaultValue) {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context).getLong(key, defaultValue);
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1175,6 @@ public class TextSecurePreferences {
|
|||
}
|
||||
|
||||
private static void clearLocalCredentials(Context context) {
|
||||
TextSecurePreferences.setPushServerPassword(context, Util.getSecret(18));
|
||||
|
||||
ProfileKey newProfileKey = ProfileKeyUtil.createNew();
|
||||
Recipient self = Recipient.self();
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
package org.thoughtcrime.securesms.dependencies;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.concurrent.DeadlockDetector;
|
||||
import org.signal.zkgroup.receipts.ClientZkReceiptOperations;
|
||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
||||
import org.thoughtcrime.securesms.database.PendingRetryReceiptCache;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
|
||||
import org.thoughtcrime.securesms.messages.BackgroundMessageRetriever;
|
||||
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
|
||||
import org.thoughtcrime.securesms.messages.IncomingMessageProcessor;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.payments.Payments;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipientCache;
|
||||
import org.thoughtcrime.securesms.revealable.ViewOnceMessageManager;
|
||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||
import org.thoughtcrime.securesms.service.PendingRetryReceiptManager;
|
||||
import org.thoughtcrime.securesms.service.TrimThreadsByDateManager;
|
||||
import org.thoughtcrime.securesms.service.webrtc.SignalCallManager;
|
||||
import org.thoughtcrime.securesms.shakereport.ShakeToReport;
|
||||
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
||||
import org.thoughtcrime.securesms.util.EarlyMessageCache;
|
||||
import org.thoughtcrime.securesms.util.FrameRateTracker;
|
||||
import org.thoughtcrime.securesms.video.exo.GiphyMp4Cache;
|
||||
import org.thoughtcrime.securesms.video.exo.SimpleExoPlayerPool;
|
||||
import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCompat;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.SignalWebSocket;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.services.DonationsService;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class MockApplicationDependencyProvider implements ApplicationDependencies.Provider {
|
||||
@Override
|
||||
public @NonNull GroupsV2Operations provideGroupsV2Operations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalServiceAccountManager provideSignalServiceAccountManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalServiceMessageReceiver provideSignalServiceMessageReceiver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalServiceNetworkAccess provideSignalServiceNetworkAccess() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull IncomingMessageProcessor provideIncomingMessageProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull BackgroundMessageRetriever provideBackgroundMessageRetriever() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull LiveRecipientCache provideRecipientCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull JobManager provideJobManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull FrameRateTracker provideFrameRateTracker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull MegaphoneRepository provideMegaphoneRepository() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EarlyMessageCache provideEarlyMessageCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull MessageNotifier provideMessageNotifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull IncomingMessageObserver provideIncomingMessageObserver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TrimThreadsByDateManager provideTrimThreadsByDateManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ViewOnceMessageManager provideViewOnceMessageManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ExpiringMessageManager provideExpiringMessageManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TypingStatusRepository provideTypingStatusRepository() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TypingStatusSender provideTypingStatusSender() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull DatabaseObserver provideDatabaseObserver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Payments providePayments(@NonNull SignalServiceAccountManager signalServiceAccountManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ShakeToReport provideShakeToReport() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull AppForegroundObserver provideAppForegroundObserver() {
|
||||
return mock(AppForegroundObserver.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalCallManager provideSignalCallManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull PendingRetryReceiptManager providePendingRetryReceiptManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull PendingRetryReceiptCache providePendingRetryReceiptCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalWebSocket provideSignalWebSocket() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TextSecureIdentityKeyStore provideIdentityStore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TextSecureSessionStore provideSessionStore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull TextSecurePreKeyStore providePreKeyStore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalSenderKeyStore provideSenderKeyStore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull GiphyMp4Cache provideGiphyMp4Cache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SimpleExoPlayerPool provideExoPlayerPool() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull AudioManagerCompat provideAndroidCallAudioManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull DonationsService provideDonationsService() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull DeadlockDetector provideDeadlockDetector() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ClientZkReceiptOperations provideClientZkReceiptOperations() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public final class MockKeyValuePersistentStorage implements KeyValuePersistentStorage {
|
||||
|
||||
private final KeyValueDataSet dataSet;
|
||||
|
||||
public static KeyValuePersistentStorage withDataSet(@NonNull KeyValueDataSet dataSet) {
|
||||
return new MockKeyValuePersistentStorage(dataSet);
|
||||
}
|
||||
|
||||
private MockKeyValuePersistentStorage(@NonNull KeyValueDataSet dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDataSet(@NonNull KeyValueDataSet dataSet, @NonNull Collection<String> removes) {
|
||||
this.dataSet.putAll(dataSet);
|
||||
this.dataSet.removeAll(removes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull KeyValueDataSet getDataSet() {
|
||||
return dataSet;
|
||||
}
|
||||
}
|
|
@ -4,10 +4,18 @@ import android.app.Application;
|
|||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.ParameterizedRobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider;
|
||||
import org.thoughtcrime.securesms.keyvalue.AccountValues;
|
||||
import org.thoughtcrime.securesms.keyvalue.KeyValueDataSet;
|
||||
import org.thoughtcrime.securesms.keyvalue.KeyValueStore;
|
||||
import org.thoughtcrime.securesms.keyvalue.MockKeyValuePersistentStorage;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -38,6 +46,18 @@ public class SignalMeUtilText_parseE164FromLink {
|
|||
});
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
if (!ApplicationDependencies.isInitialized()) {
|
||||
ApplicationDependencies.init(ApplicationProvider.getApplicationContext(), new MockApplicationDependencyProvider());
|
||||
}
|
||||
|
||||
KeyValueDataSet dataSet = new KeyValueDataSet();
|
||||
dataSet.putString(AccountValues.KEY_E164, "+15555555555");
|
||||
|
||||
SignalStore.inject(new KeyValueStore(MockKeyValuePersistentStorage.withDataSet(dataSet)));
|
||||
}
|
||||
|
||||
public SignalMeUtilText_parseE164FromLink(String input, String output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
|
@ -45,6 +65,6 @@ public class SignalMeUtilText_parseE164FromLink {
|
|||
|
||||
@Test
|
||||
public void parse() {
|
||||
assertEquals(output, SignalMeUtil.parseE164FromLink(ApplicationProvider.getApplicationContext(), input));
|
||||
assertEquals(output, SignalMeUtil.parseE164FromLink(ApplicationDependencies.getApplication(), input));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.whispersystems.signalservice.api.push;
|
||||
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -12,6 +14,11 @@ public final class PNI extends AccountIdentifier {
|
|||
return new PNI(uuid);
|
||||
}
|
||||
|
||||
public static PNI parseOrNull(String raw) {
|
||||
UUID uuid = UuidUtil.parseOrNull(raw);
|
||||
return uuid != null ? from(uuid) : null;
|
||||
}
|
||||
|
||||
private PNI(UUID uuid) {
|
||||
super(uuid);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue