From b49e4004ab3d121089989f9eb13bdcb63a7373a3 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Sat, 23 Jan 2021 17:39:35 -0400 Subject: [PATCH] Restrict SMS in multishare. --- .../contacts/ContactsCursorLoader.java | 12 ++++- .../securesms/sharing/ShareActivity.java | 46 ++++++++++++++++++- .../securesms/sharing/ShareViewModel.java | 40 ++++++++++++++-- app/src/main/res/values/strings.xml | 1 + 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java index 955c7e32e..9f6fb4527 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactsCursorLoader.java @@ -63,6 +63,7 @@ public class ContactsCursorLoader extends CursorLoader { public static final int FLAG_SELF = 1 << 4; public static final int FLAG_BLOCK = 1 << 5; public static final int FLAG_HIDE_GROUPS_V1 = 1 << 5; + public static final int FLAG_HIDE_NEW = 1 << 6; public static final int FLAG_ALL = FLAG_PUSH | FLAG_SMS | FLAG_ACTIVE_GROUPS | FLAG_INACTIVE_GROUPS | FLAG_SELF; } @@ -135,8 +136,11 @@ public class ContactsCursorLoader extends CursorLoader { addContactsSection(cursorList); addGroupsSection(cursorList); - addNewNumberSection(cursorList); - addUsernameSearchSection(cursorList); + + if (!hideNewNumberOrUsername(mode)) { + addNewNumberSection(cursorList); + addUsernameSearchSection(cursorList); + } return cursorList; } @@ -429,6 +433,10 @@ public class ContactsCursorLoader extends CursorLoader { return flagSet(mode, DisplayMode.FLAG_HIDE_GROUPS_V1); } + private static boolean hideNewNumberOrUsername(int mode) { + return flagSet(mode, DisplayMode.FLAG_HIDE_NEW); + } + private static boolean flagSet(int mode, int flag) { return (mode & flag) > 0; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java index fcd8a6846..05e417e62 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java @@ -98,6 +98,7 @@ public class ShareActivity extends PassphraseRequiredActivity private ImageView searchAction; private View shareConfirm; private ShareSelectionAdapter adapter; + private boolean disallowMultiShare; private ShareViewModel viewModel; @@ -173,7 +174,12 @@ public class ShareActivity extends PassphraseRequiredActivity @Override public boolean onBeforeContactSelected(Optional recipientId, String number) { - return viewModel.onContactSelected(new ShareContact(recipientId, number)); + if (disallowMultiShare) { + Toast.makeText(this, R.string.ShareActivity__sharing_to_multiple_chats_is, Toast.LENGTH_LONG).show(); + return false; + } else { + return viewModel.onContactSelected(new ShareContact(recipientId, number)); + } } @Override @@ -203,7 +209,7 @@ public class ShareActivity extends PassphraseRequiredActivity private void initializeIntent() { if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) { - int mode = DisplayMode.FLAG_PUSH | DisplayMode.FLAG_ACTIVE_GROUPS | DisplayMode.FLAG_SELF; + int mode = DisplayMode.FLAG_PUSH | DisplayMode.FLAG_ACTIVE_GROUPS | DisplayMode.FLAG_SELF | DisplayMode.FLAG_HIDE_NEW; if (TextSecurePreferences.isSmsEnabled(this) && viewModel.isExternalShare()) { mode |= DisplayMode.FLAG_SMS; @@ -269,6 +275,42 @@ public class ShareActivity extends PassphraseRequiredActivity animateInSelection(); } }); + + viewModel.getSmsShareRestriction().observe(this, smsShareRestriction -> { + final int displayMode; + + switch (smsShareRestriction) { + case NO_RESTRICTIONS: + disallowMultiShare = false; + displayMode = getIntent().getIntExtra(ContactSelectionListFragment.DISPLAY_MODE, -1); + + if (displayMode == -1) { + Log.w(TAG, "DisplayMode not set yet."); + return; + } + + if (TextSecurePreferences.isSmsEnabled(this) && viewModel.isExternalShare() && (displayMode & DisplayMode.FLAG_SMS) == 0) { + getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode | DisplayMode.FLAG_SMS); + contactsFragment.setQueryFilter(null); + } + break; + case DISALLOW_SMS_CONTACTS: + disallowMultiShare = false; + displayMode = getIntent().getIntExtra(ContactSelectionListFragment.DISPLAY_MODE, -1); + + if (displayMode == -1) { + Log.w(TAG, "DisplayMode not set yet."); + return; + } + + getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode & ~DisplayMode.FLAG_SMS); + contactsFragment.setQueryFilter(null); + break; + case DISALLOW_MULTI_SHARE: + disallowMultiShare = true; + break; + } + }); } private void initializeViewModel() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java index 877b09512..aa8a814a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareViewModel.java @@ -5,6 +5,7 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Transformations; @@ -16,8 +17,10 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.providers.BlobProvider; +import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.DefaultValueLiveData; import org.thoughtcrime.securesms.util.MappingModel; +import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.whispersystems.libsignal.util.guava.Optional; import java.util.Collections; @@ -33,15 +36,17 @@ public class ShareViewModel extends ViewModel { private final ShareRepository shareRepository; private final MutableLiveData> shareData; private final MutableLiveData> selectedContacts; + private final LiveData smsShareRestriction; private boolean mediaUsed; private boolean externalShare; private ShareViewModel() { - this.context = ApplicationDependencies.getApplication(); - this.shareRepository = new ShareRepository(); - this.shareData = new MutableLiveData<>(); - this.selectedContacts = new DefaultValueLiveData<>(Collections.emptySet()); + this.context = ApplicationDependencies.getApplication(); + this.shareRepository = new ShareRepository(); + this.shareData = new MutableLiveData<>(); + this.selectedContacts = new DefaultValueLiveData<>(Collections.emptySet()); + this.smsShareRestriction = Transformations.map(selectedContacts, this::updateShareRestriction); } void onSingleMediaShared(@NonNull Uri uri, @Nullable String mimeType) { @@ -90,6 +95,10 @@ public class ShareViewModel extends ViewModel { .toList()); } + @NonNull LiveData getSmsShareRestriction() { + return Transformations.distinctUntilChanged(smsShareRestriction); + } + void onNonExternalShare() { externalShare = false; } @@ -116,6 +125,23 @@ public class ShareViewModel extends ViewModel { } } + private @NonNull SmsShareRestriction updateShareRestriction(@NonNull Set shareContacts) { + if (shareContacts.isEmpty()) { + return SmsShareRestriction.NO_RESTRICTIONS; + } else if (shareContacts.size() == 1) { + ShareContact shareContact = shareContacts.iterator().next(); + Recipient recipient = Recipient.live(shareContact.getRecipientId().get()).get(); + + if (!recipient.isRegistered() || recipient.isForceSmsSelection()) { + return SmsShareRestriction.DISALLOW_MULTI_SHARE; + } else { + return SmsShareRestriction.DISALLOW_SMS_CONTACTS; + } + } else { + return SmsShareRestriction.DISALLOW_SMS_CONTACTS; + } + } + public static class Factory extends ViewModelProvider.NewInstanceFactory { @Override public @NonNull T create(@NonNull Class modelClass) { @@ -123,4 +149,10 @@ public class ShareViewModel extends ViewModel { return modelClass.cast(new ShareViewModel()); } } + + enum SmsShareRestriction { + NO_RESTRICTIONS, + DISALLOW_SMS_CONTACTS, + DISALLOW_MULTI_SHARE + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a78240df..a88d7ac18 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2827,6 +2827,7 @@ Share Send %1$s, + Sharing to multiple chats is only supported for Signal messages Failed to send to some users