Prevent corner-case where link previews were generated for SMS.

Also added some hardening to make sure that it's impossible for any link
previews to be fetched if the setting is disabled (this was already the
case in practice, we just have some assertions in there now).

Fixes #9956
master
Greyson Parrelli 2020-08-27 10:52:47 -04:00 committed by Alan Evans
parent d3c9f66de6
commit c09dbfa47c
2 changed files with 30 additions and 8 deletions

View File

@ -1840,6 +1840,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
sendButton.addOnTransportChangedListener((newTransport, manuallySelected) -> { sendButton.addOnTransportChangedListener((newTransport, manuallySelected) -> {
calculateCharactersRemaining(); calculateCharactersRemaining();
updateLinkPreviewState(); updateLinkPreviewState();
linkPreviewViewModel.onTransportChanged(newTransport.isSms());
composeText.setTransport(newTransport); composeText.setTransport(newTransport);
buttonToggle.getBackground().setColorFilter(newTransport.getBackgroundColor(), PorterDuff.Mode.MULTIPLY); buttonToggle.getBackground().setColorFilter(newTransport.getBackgroundColor(), PorterDuff.Mode.MULTIPLY);
@ -2692,7 +2693,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
} }
private void updateLinkPreviewState() { private void updateLinkPreviewState() {
if (SignalStore.settings().isLinkPreviewsEnabled() && !sendButton.getSelectedTransport().isSms() && !attachmentManager.isAttachmentPresent()) { if (SignalStore.settings().isLinkPreviewsEnabled() && isSecureText && !sendButton.getSelectedTransport().isSms() && !attachmentManager.isAttachmentPresent()) {
linkPreviewViewModel.onEnabled(); linkPreviewViewModel.onEnabled();
linkPreviewViewModel.onTextChanged(this, composeText.getTextTrimmed().toString(), composeText.getSelectionStart(), composeText.getSelectionEnd()); linkPreviewViewModel.onTextChanged(this, composeText.getTextTrimmed().toString(), composeText.getSelectionStart(), composeText.getSelectionEnd());
} else { } else {

View File

@ -7,9 +7,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.RequestController; import org.thoughtcrime.securesms.net.RequestController;
import org.thoughtcrime.securesms.util.Debouncer; import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.Util;
@ -23,32 +25,36 @@ public class LinkPreviewViewModel extends ViewModel {
private final LinkPreviewRepository repository; private final LinkPreviewRepository repository;
private final MutableLiveData<LinkPreviewState> linkPreviewState; private final MutableLiveData<LinkPreviewState> linkPreviewState;
private final LiveData<LinkPreviewState> linkPreviewSafeState;
private String activeUrl; private String activeUrl;
private RequestController activeRequest; private RequestController activeRequest;
private boolean userCanceled; private boolean userCanceled;
private Debouncer debouncer; private Debouncer debouncer;
private boolean enabled;
private LinkPreviewViewModel(@NonNull LinkPreviewRepository repository) { private LinkPreviewViewModel(@NonNull LinkPreviewRepository repository) {
this.repository = repository; this.repository = repository;
this.linkPreviewState = new MutableLiveData<>(); this.linkPreviewState = new MutableLiveData<>();
this.debouncer = new Debouncer(250); this.debouncer = new Debouncer(250);
this.enabled = SignalStore.settings().isLinkPreviewsEnabled();
this.linkPreviewSafeState = Transformations.map(linkPreviewState, state -> enabled ? state : LinkPreviewState.forNoLinks());
} }
public LiveData<LinkPreviewState> getLinkPreviewState() { public LiveData<LinkPreviewState> getLinkPreviewState() {
return linkPreviewState; return linkPreviewSafeState;
} }
public boolean hasLinkPreview() { public boolean hasLinkPreview() {
return linkPreviewState.getValue() != null && linkPreviewState.getValue().getLinkPreview().isPresent(); return linkPreviewSafeState.getValue() != null && linkPreviewSafeState.getValue().getLinkPreview().isPresent();
} }
public boolean hasLinkPreviewUi() { public boolean hasLinkPreviewUi() {
return linkPreviewState.getValue() != null && linkPreviewState.getValue().hasContent(); return linkPreviewSafeState.getValue() != null && linkPreviewSafeState.getValue().hasContent();
} }
public @NonNull List<LinkPreview> getActiveLinkPreviews() { public @NonNull List<LinkPreview> getActiveLinkPreviews() {
final LinkPreviewState state = linkPreviewState.getValue(); final LinkPreviewState state = linkPreviewSafeState.getValue();
if (state == null || !state.getLinkPreview().isPresent()) { if (state == null || !state.getLinkPreview().isPresent()) {
return Collections.emptyList(); return Collections.emptyList();
@ -58,6 +64,8 @@ public class LinkPreviewViewModel extends ViewModel {
} }
public void onTextChanged(@NonNull Context context, @NonNull String text, int cursorStart, int cursorEnd) { public void onTextChanged(@NonNull Context context, @NonNull String text, int cursorStart, int cursorEnd) {
if (!enabled) return;
debouncer.publish(() -> { debouncer.publish(() -> {
if (TextUtils.isEmpty(text)) { if (TextUtils.isEmpty(text)) {
userCanceled = false; userCanceled = false;
@ -129,6 +137,14 @@ public class LinkPreviewViewModel extends ViewModel {
linkPreviewState.setValue(LinkPreviewState.forNoLinks()); linkPreviewState.setValue(LinkPreviewState.forNoLinks());
} }
public void onTransportChanged(boolean isSms) {
enabled = !isSms;
if (isSms) {
onUserCancel();
}
}
public void onSend() { public void onSend() {
if (activeRequest != null) { if (activeRequest != null) {
activeRequest.cancel(); activeRequest.cancel();
@ -143,7 +159,12 @@ public class LinkPreviewViewModel extends ViewModel {
} }
public void onEnabled() { public void onEnabled() {
if (!SignalStore.settings().isLinkPreviewsEnabled()) {
throw new AssertionError();
}
userCanceled = false; userCanceled = false;
enabled = true;
} }
@Override @Override