From b3555f2f9498ff75944cdb19e032ca6a239773ae Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Thu, 27 Aug 2020 16:34:26 -0400 Subject: [PATCH] Use updated Safety Number Change dialog for calls. Fixes [#9940](https://github.com/signalapp/Signal-Android/issues/9940) --- .../securesms/WebRtcCallActivity.java | 54 ++++++------------- .../conversation/ConversationActivity.java | 9 ++-- .../ui/error/SafetyNumberChangeDialog.java | 41 ++++++++++---- app/src/main/res/values/strings.xml | 1 + 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java index dea9841587..4a95288e98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java @@ -27,9 +27,6 @@ import android.content.res.Configuration; import android.media.AudioManager; import android.os.Build; import android.os.Bundle; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.method.LinkMovementMethod; import android.util.Rational; import android.view.Window; import android.view.WindowManager; @@ -37,7 +34,6 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.AppCompatTextView; import androidx.core.content.ContextCompat; import androidx.lifecycle.ViewModelProviders; @@ -48,7 +44,7 @@ import org.thoughtcrime.securesms.components.TooltipPopup; import org.thoughtcrime.securesms.components.webrtc.WebRtcAudioOutput; import org.thoughtcrime.securesms.components.webrtc.WebRtcCallView; import org.thoughtcrime.securesms.components.webrtc.WebRtcCallViewModel; -import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; +import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog; import org.thoughtcrime.securesms.events.WebRtcViewModel; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.messagerequests.CalleeMustAcceptMessageRequestActivity; @@ -57,17 +53,12 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.ringrtc.RemotePeer; import org.thoughtcrime.securesms.service.WebRtcCallService; import org.thoughtcrime.securesms.util.EllapsedTimeFormatter; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.VerifySpan; import org.thoughtcrime.securesms.util.ViewUtil; import org.whispersystems.libsignal.IdentityKey; -import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.signalservice.api.messages.calls.HangupMessage; -import static org.whispersystems.libsignal.SessionCipher.SESSION_LOCK; - -public class WebRtcCallActivity extends AppCompatActivity { +public class WebRtcCallActivity extends AppCompatActivity implements SafetyNumberChangeDialog.Callback { private static final String TAG = WebRtcCallActivity.class.getSimpleName(); @@ -470,37 +461,24 @@ public class WebRtcCallActivity extends AppCompatActivity { handleTerminate(recipient, HangupMessage.Type.NORMAL); } - String name = recipient.getDisplayName(this); - String introduction = getString(R.string.WebRtcCallScreen_new_safety_numbers, name, name); - SpannableString spannableString = new SpannableString(introduction + " " + getString(R.string.WebRtcCallScreen_you_may_wish_to_verify_this_contact)); + SafetyNumberChangeDialog.showForCall(getSupportFragmentManager(), recipient.getId()); + } - spannableString.setSpan(new VerifySpan(this, recipient.getId(), theirKey), introduction.length() + 1, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + @Override + public void onSendAnywayAfterSafetyNumberChange() { + Intent intent = new Intent(WebRtcCallActivity.this, WebRtcCallService.class); + intent.setAction(WebRtcCallService.ACTION_OUTGOING_CALL) + .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER, new RemotePeer(viewModel.getRecipient().getId())); - AppCompatTextView untrustedIdentityExplanation = new AppCompatTextView(this); - untrustedIdentityExplanation.setText(spannableString); - untrustedIdentityExplanation.setMovementMethod(LinkMovementMethod.getInstance()); + startService(intent); + } - new AlertDialog.Builder(this) - .setView(untrustedIdentityExplanation) - .setPositiveButton(R.string.WebRtcCallScreen_accept, (d, w) -> { - synchronized (SESSION_LOCK) { - TextSecureIdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(WebRtcCallActivity.this); - identityKeyStore.saveIdentity(new SignalProtocolAddress(recipient.requireServiceId(), 1), theirKey, true); - } + @Override + public void onMessageResentAfterSafetyNumberChange() { } - d.dismiss(); - - Intent intent = new Intent(WebRtcCallActivity.this, WebRtcCallService.class); - intent.setAction(WebRtcCallService.ACTION_OUTGOING_CALL) - .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER, new RemotePeer(recipient.getId())); - - startService(intent); - }) - .setNegativeButton(R.string.WebRtcCallScreen_end_call, (d, w) -> { - d.dismiss(); - handleTerminate(recipient, HangupMessage.Type.NORMAL); - }) - .show(); + @Override + public void onCanceled() { + handleTerminate(viewModel.getRecipient().get(), HangupMessage.Type.NORMAL); } private boolean isSystemPipEnabledAndAvailable() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 76cb4a365f..f9ace5bfd2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -300,8 +300,6 @@ public class ConversationActivity extends PassphraseRequiredActivity private static final String TAG = ConversationActivity.class.getSimpleName(); - public static final String SAFETY_NUMBER_DIALOG = "SAFETY_NUMBER"; - private static final String STATE_REACT_WITH_ANY_PAGE = "STATE_REACT_WITH_ANY_PAGE"; public static final String RECIPIENT_EXTRA = "recipient_id"; @@ -1362,7 +1360,7 @@ public class ConversationActivity extends PassphraseRequiredActivity private void handleRecentSafetyNumberChange() { List records = identityRecords.getUnverifiedRecords(); records.addAll(identityRecords.getUntrustedRecords()); - SafetyNumberChangeDialog.create(records).show(getSupportFragmentManager(), SAFETY_NUMBER_DIALOG); + SafetyNumberChangeDialog.show(getSupportFragmentManager(), records); } @Override @@ -1383,6 +1381,9 @@ public class ConversationActivity extends PassphraseRequiredActivity }); } + @Override + public void onCanceled() { } + private void handleSecurityChange(boolean isSecureText, boolean isDefaultSms) { Log.i(TAG, "handleSecurityChange(" + isSecureText + ", " + isDefaultSms + ")"); @@ -3095,7 +3096,7 @@ public class ConversationActivity extends PassphraseRequiredActivity .setPositiveButton(R.string.conversation_activity__send, (dialog, which) -> MessageSender.resend(this, messageRecord)) .show(); } else if (messageRecord.isIdentityMismatchFailure()) { - SafetyNumberChangeDialog.create(this, messageRecord).show(getSupportFragmentManager(), SAFETY_NUMBER_DIALOG); + SafetyNumberChangeDialog.show(this, messageRecord); } else { startActivity(MessageDetailsActivity.getIntentForMessageDetails(this, messageRecord, messageRecord.getRecipient().getId(), messageRecord.getThreadId())); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeDialog.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeDialog.java index c3c95a28a0..a323827ec7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/SafetyNumberChangeDialog.java @@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.conversation.ui.error; import android.app.Activity; import android.app.Dialog; -import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; +import android.telecom.Call; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -13,6 +13,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; @@ -28,21 +30,22 @@ import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.recipients.RecipientId; -import java.util.HashSet; import java.util.List; -import java.util.Set; public final class SafetyNumberChangeDialog extends DialogFragment implements SafetyNumberChangeAdapter.Callbacks { + public static final String SAFETY_NUMBER_DIALOG = "SAFETY_NUMBER"; + private static final String RECIPIENT_IDS_EXTRA = "recipient_ids"; private static final String MESSAGE_ID_EXTRA = "message_id"; private static final String MESSAGE_TYPE_EXTRA = "message_type"; + private static final String IS_CALL_EXTRA = "is_call"; private SafetyNumberChangeViewModel viewModel; private SafetyNumberChangeAdapter adapter; private View dialogView; - public static @NonNull SafetyNumberChangeDialog create(List identityRecords) { + public static void show(@NonNull FragmentManager fragmentManager, @NonNull List identityRecords) { List ids = Stream.of(identityRecords) .filterNot(IdentityDatabase.IdentityRecord::isFirstUse) .map(record -> record.getRecipientId().serialize()) @@ -53,12 +56,12 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa arguments.putStringArray(RECIPIENT_IDS_EXTRA, ids.toArray(new String[0])); SafetyNumberChangeDialog fragment = new SafetyNumberChangeDialog(); fragment.setArguments(arguments); - return fragment; + fragment.show(fragmentManager, SAFETY_NUMBER_DIALOG); } - public static @NonNull SafetyNumberChangeDialog create(Context context, MessageRecord messageRecord) { + public static void show(@NonNull FragmentActivity fragmentActivity, @NonNull MessageRecord messageRecord) { List ids = Stream.of(messageRecord.getIdentityKeyMismatches()) - .map(mismatch -> mismatch.getRecipientId(context).serialize()) + .map(mismatch -> mismatch.getRecipientId(fragmentActivity).serialize()) .distinct() .toList(); @@ -68,7 +71,16 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa arguments.putString(MESSAGE_TYPE_EXTRA, messageRecord.isMms() ? MmsSmsDatabase.MMS_TRANSPORT : MmsSmsDatabase.SMS_TRANSPORT); SafetyNumberChangeDialog fragment = new SafetyNumberChangeDialog(); fragment.setArguments(arguments); - return fragment; + fragment.show(fragmentActivity.getSupportFragmentManager(), SAFETY_NUMBER_DIALOG); + } + + public static void showForCall(@NonNull FragmentManager fragmentManager, @NonNull RecipientId recipientId) { + Bundle arguments = new Bundle(); + arguments.putStringArray(RECIPIENT_IDS_EXTRA, new String[] { recipientId.serialize() }); + arguments.putBoolean(IS_CALL_EXTRA, true); + SafetyNumberChangeDialog fragment = new SafetyNumberChangeDialog(); + fragment.setArguments(arguments); + fragment.show(fragmentManager, SAFETY_NUMBER_DIALOG); } private SafetyNumberChangeDialog() { } @@ -93,6 +105,8 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa @Override public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + boolean isCall = requireArguments().getBoolean(IS_CALL_EXTRA, false); + dialogView = LayoutInflater.from(requireActivity()).inflate(R.layout.safety_number_change_dialog, null); AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity(), getTheme()); @@ -101,8 +115,8 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa builder.setTitle(R.string.safety_number_change_dialog__safety_number_changes) .setView(dialogView) - .setPositiveButton(R.string.safety_number_change_dialog__send_anyway, this::handleSendAnyway) - .setNegativeButton(android.R.string.cancel, null); + .setPositiveButton(isCall ? R.string.safety_number_change_dialog__call_anyway : R.string.safety_number_change_dialog__send_anyway, this::handleSendAnyway) + .setNegativeButton(android.R.string.cancel, this::handleCancel); return builder.create(); } @@ -151,6 +165,12 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa trustOrVerifyResultLiveData.observeForever(observer); } + private void handleCancel(@NonNull DialogInterface dialogInterface, int which) { + if (getActivity() instanceof Callback) { + ((Callback) getActivity()).onCanceled(); + } + } + @Override public void onViewIdentityRecord(@NonNull IdentityDatabase.IdentityRecord identityRecord) { startActivity(VerifyIdentityActivity.newIntent(requireContext(), identityRecord)); @@ -159,5 +179,6 @@ public final class SafetyNumberChangeDialog extends DialogFragment implements Sa public interface Callback { void onSendAnywayAfterSafetyNumberChange(); void onMessageResentAfterSafetyNumberChange(); + void onCanceled(); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1669cd0e50..2a7a0bdaa5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1687,6 +1687,7 @@ Safety Number Changes Send anyway + Call anyway The following people may have reinstalled or changed devices. Verify your safety number with them to ensure privacy. View Previous verified