mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Sync whether or not our primary device can send SMS.
This commit is contained in:
@@ -159,6 +159,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
||||
.addNonBlocking(() -> DownloadLatestEmojiDataJob.scheduleIfNecessary(this))
|
||||
.addPostRender(() -> RateLimitUtil.retryAllRateLimitedMessages(this))
|
||||
.addPostRender(this::initializeExpiringMessageManager)
|
||||
.addPostRender(() -> SignalStore.settings().setDefaultSms(Util.isDefaultSmsProvider(this)))
|
||||
.execute();
|
||||
|
||||
Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||
|
||||
@@ -12,7 +12,9 @@ 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.util.SmsUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
|
||||
private const val SMS_REQUEST_CODE: Short = 1234
|
||||
|
||||
@@ -33,6 +35,10 @@ class SmsSettingsFragment : DSLSettingsFragment(R.string.preferences__sms_mms) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
SignalStore.settings().setDefaultSms(Util.isDefaultSmsProvider(requireContext()))
|
||||
}
|
||||
|
||||
private fun getConfiguration(state: SmsSettingsState): DSLConfiguration {
|
||||
return configure {
|
||||
clickPref(
|
||||
@@ -79,12 +85,12 @@ class SmsSettingsFragment : DSLSettingsFragment(R.string.preferences__sms_mms) {
|
||||
// Linter isn't smart enough to figure out the else only happens if API >= 24
|
||||
@SuppressLint("InlinedApi")
|
||||
private fun startDefaultAppSelectionIntent() {
|
||||
startActivity(
|
||||
when {
|
||||
Build.VERSION.SDK_INT < 23 -> Intent(Settings.ACTION_WIRELESS_SETTINGS)
|
||||
Build.VERSION.SDK_INT < 24 -> Intent(Settings.ACTION_SETTINGS)
|
||||
else -> Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
|
||||
}
|
||||
)
|
||||
val intent: Intent = when {
|
||||
Build.VERSION.SDK_INT < 23 -> Intent(Settings.ACTION_WIRELESS_SETTINGS)
|
||||
Build.VERSION.SDK_INT < 24 -> Intent(Settings.ACTION_SETTINGS)
|
||||
else -> Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
|
||||
}
|
||||
|
||||
startActivityForResult(intent, SMS_REQUEST_CODE.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +249,7 @@ import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.stickers.StickerManagementActivity;
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent;
|
||||
import org.thoughtcrime.securesms.stickers.StickerSearchRepository;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.AsynchronousCallback;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
@@ -643,6 +644,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
(resultCode != RESULT_OK && reqCode != SMS_DEFAULT))
|
||||
{
|
||||
updateLinkPreviewState();
|
||||
SignalStore.settings().setDefaultSms(Util.isDefaultSmsProvider(this));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdFollowUpJobMi
|
||||
import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdJobMigration;
|
||||
import org.thoughtcrime.securesms.jobmanager.migrations.RetrieveProfileJobMigration;
|
||||
import org.thoughtcrime.securesms.jobmanager.migrations.SendReadReceiptsJobMigration;
|
||||
import org.thoughtcrime.securesms.migrations.AccountRecordMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.AttributesMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.AvatarIdRemovalMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.AvatarMigrationJob;
|
||||
@@ -157,6 +158,7 @@ public final class JobManagerFactories {
|
||||
put(ProfileUploadJob.KEY, new ProfileUploadJob.Factory());
|
||||
|
||||
// Migrations
|
||||
put(AccountRecordMigrationJob.KEY, new AccountRecordMigrationJob.Factory());
|
||||
put(AttributesMigrationJob.KEY, new AttributesMigrationJob.Factory());
|
||||
put(AvatarIdRemovalMigrationJob.KEY, new AvatarIdRemovalMigrationJob.Factory());
|
||||
put(AvatarMigrationJob.KEY, new AvatarMigrationJob.Factory());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -9,10 +10,14 @@ import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference;
|
||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.webrtc.CallBandwidthMode;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -21,6 +26,8 @@ import java.util.List;
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class SettingsValues extends SignalStoreValues {
|
||||
|
||||
private static final String TAG = Log.tag(SettingsValues.class);
|
||||
|
||||
public static final String LINK_PREVIEWS = "settings.link_previews";
|
||||
public static final String KEEP_MESSAGES_DURATION = "settings.keep_messages_duration";
|
||||
|
||||
@@ -57,6 +64,8 @@ public final class SettingsValues extends SignalStoreValues {
|
||||
|
||||
private final SingleLiveEvent<String> onConfigurationSettingChanged = new SingleLiveEvent<>();
|
||||
|
||||
private static final String DEFAULT_SMS = "settings.default_sms";
|
||||
|
||||
SettingsValues(@NonNull KeyValueStore store) {
|
||||
super(store);
|
||||
}
|
||||
@@ -341,6 +350,25 @@ public final class SettingsValues extends SignalStoreValues {
|
||||
putBoolean(NOTIFY_WHEN_CONTACT_JOINS_SIGNAL, notifyWhenContactJoinsSignal);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to keep track of when the default status changes so we can sync to storage service.
|
||||
* So call this when you think it might have changed, but *don't* rely on it for knowing if we
|
||||
* *are* the default SMS. For that, continue to use
|
||||
* {@link org.thoughtcrime.securesms.util.Util#isDefaultSmsProvider(Context)}.
|
||||
*/
|
||||
public void setDefaultSms(boolean value) {
|
||||
boolean lastKnown = getBoolean(DEFAULT_SMS, false);
|
||||
|
||||
if (value != lastKnown) {
|
||||
Log.i(TAG, "Default SMS state changed! Scheduling a storage sync.");
|
||||
putBoolean(DEFAULT_SMS, value);
|
||||
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().getId());
|
||||
StorageSyncHelper.scheduleSyncForDataChange();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Uri getUri(@NonNull String key) {
|
||||
String uri = getString(key, "");
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.thoughtcrime.securesms.migrations;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
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.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
/**
|
||||
* Marks the AccountRecord as dirty and runs a storage sync. Can be enqueued when we've added a new
|
||||
* attribute to the AccountRecord.
|
||||
*/
|
||||
public class AccountRecordMigrationJob extends MigrationJob {
|
||||
|
||||
private static final String TAG = Log.tag(AccountRecordMigrationJob.class);
|
||||
|
||||
public static final String KEY = "AccountRecordMigrationJob";
|
||||
|
||||
AccountRecordMigrationJob() {
|
||||
this(new Parameters.Builder().build());
|
||||
}
|
||||
|
||||
private AccountRecordMigrationJob(@NonNull Parameters parameters) {
|
||||
super(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUiBlocking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalUuid(context) == null) {
|
||||
Log.w(TAG, "Not registered!");
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId());
|
||||
ApplicationDependencies.getJobManager().add(new StorageSyncJob());
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean shouldRetry(@NonNull Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class Factory implements Job.Factory<AccountRecordMigrationJob> {
|
||||
@Override
|
||||
public @NonNull AccountRecordMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new AccountRecordMigrationJob(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class ApplicationMigrations {
|
||||
|
||||
private static final int LEGACY_CANONICAL_VERSION = 455;
|
||||
|
||||
public static final int CURRENT_VERSION = 32;
|
||||
public static final int CURRENT_VERSION = 33;
|
||||
|
||||
private static final class Version {
|
||||
static final int LEGACY = 1;
|
||||
@@ -74,6 +74,7 @@ public class ApplicationMigrations {
|
||||
// Versions 29, 30 accidentally skipped
|
||||
static final int MUTE_SYNC = 31;
|
||||
static final int PROFILE_SHARING_UPDATE = 32;
|
||||
static final int SMS_STORAGE_SYNC = 33;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,6 +313,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.PROFILE_SHARING_UPDATE, new ProfileSharingUpdateMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.SMS_STORAGE_SYNC) {
|
||||
jobs.put(Version.SMS_STORAGE_SYNC, new AccountRecordMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,20 +28,18 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
private static final String TAG = Log.tag(AccountRecordProcessor.class);
|
||||
|
||||
private final Context context;
|
||||
private final RecipientDatabase recipientDatabase;
|
||||
private final SignalAccountRecord localAccountRecord;
|
||||
private final Recipient self;
|
||||
|
||||
private boolean foundAccountRecord = false;
|
||||
|
||||
public AccountRecordProcessor(@NonNull Context context, @NonNull Recipient self) {
|
||||
this(context, self, StorageSyncHelper.buildAccountRecord(context, self).getAccount().get(), DatabaseFactory.getRecipientDatabase(context));
|
||||
this(context, self, StorageSyncHelper.buildAccountRecord(context, self).getAccount().get());
|
||||
}
|
||||
|
||||
AccountRecordProcessor(@NonNull Context context, @NonNull Recipient self, @NonNull SignalAccountRecord localAccountRecord, @NonNull RecipientDatabase recipientDatabase) {
|
||||
AccountRecordProcessor(@NonNull Context context, @NonNull Recipient self, @NonNull SignalAccountRecord localAccountRecord) {
|
||||
this.context = context;
|
||||
this.self = self;
|
||||
this.recipientDatabase = recipientDatabase;
|
||||
this.localAccountRecord = localAccountRecord;
|
||||
}
|
||||
|
||||
@@ -99,8 +97,9 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
List<PinnedConversation> pinnedConversations = remote.getPinnedConversations();
|
||||
AccountRecord.PhoneNumberSharingMode phoneNumberSharingMode = remote.getPhoneNumberSharingMode();
|
||||
boolean preferContactAvatars = remote.isPreferContactAvatars();
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments);
|
||||
boolean primarySendsSms = local.isPrimarySendsSms();
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, primarySendsSms);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, primarySendsSms);
|
||||
|
||||
if (matchesRemote) {
|
||||
return remote;
|
||||
@@ -125,6 +124,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
.setPinnedConversations(pinnedConversations)
|
||||
.setPreferContactAvatars(preferContactAvatars)
|
||||
.setPayments(payments.isEnabled(), payments.getEntropy().orNull())
|
||||
.setPrimarySendsSms(primarySendsSms)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,8 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
boolean unlistedPhoneNumber,
|
||||
@NonNull List<PinnedConversation> pinnedConversations,
|
||||
boolean preferContactAvatars,
|
||||
SignalAccountRecord.Payments payments)
|
||||
SignalAccountRecord.Payments payments,
|
||||
boolean primarySendsSms)
|
||||
{
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getGivenName().or(""), givenName) &&
|
||||
@@ -177,6 +178,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
contact.getPhoneNumberSharingMode() == phoneNumberSharingMode &&
|
||||
contact.isPhoneNumberUnlisted() == unlistedPhoneNumber &&
|
||||
contact.isPreferContactAvatars() == preferContactAvatars &&
|
||||
contact.isPrimarySendsSms() == primarySendsSms &&
|
||||
Objects.equals(contact.getPinnedConversations(), pinnedConversations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@ public final class StorageSyncHelper {
|
||||
.setPinnedConversations(StorageSyncModels.localToRemotePinnedConversations(pinned))
|
||||
.setPreferContactAvatars(SignalStore.settings().isPreferSystemContactPhotos())
|
||||
.setPayments(SignalStore.paymentsValues().mobileCoinPaymentsEnabled(), Optional.fromNullable(SignalStore.paymentsValues().getPaymentsEntropy()).transform(Entropy::getBytes).orNull())
|
||||
.setPrimarySendsSms(Util.isDefaultSmsProvider(context))
|
||||
.build();
|
||||
|
||||
return SignalStorageRecord.forAccount(account);
|
||||
|
||||
Reference in New Issue
Block a user