From 1e250ee95c0fe42c99e57fe42aaab6f623c51b4d Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Mon, 6 Jul 2020 16:27:03 -0400 Subject: [PATCH] Add Calling Requests. --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 6 + .../securesms/WebRtcCallActivity.java | 31 +-- .../components/webrtc/WebRtcCallView.java | 1 + .../securesms/database/SmsDatabase.java | 6 +- .../securesms/database/ThreadDatabase.java | 6 +- .../securesms/events/WebRtcViewModel.java | 1 + ...lleeMustAcceptMessageRequestActivity.java} | 59 +++--- .../securesms/recipients/RecipientUtil.java | 19 +- .../securesms/service/WebRtcCallService.java | 195 ++++++++++-------- .../securesms/util/CommunicationActions.java | 25 +-- .../securesms/util/FeatureFlags.java | 2 +- app/witness-verifications.gradle | 4 +- .../api/messages/calls/HangupMessage.java | 3 +- .../api/messages/calls/OfferMessage.java | 3 +- .../src/main/proto/SignalService.proto | 11 +- 16 files changed, 192 insertions(+), 182 deletions(-) rename app/src/main/java/org/thoughtcrime/securesms/messagerequests/{CalleeMustAcceptMessageRequestDialogFragment.java => CalleeMustAcceptMessageRequestActivity.java} (55%) diff --git a/app/build.gradle b/app/build.gradle index 1ab4df44c3..6ece1df50a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -304,7 +304,7 @@ dependencies { implementation 'org.signal:argon2:13.1@aar' - implementation 'org.signal:ringrtc-android:2.2.0' + implementation 'org.signal:ringrtc-android:2.3.1' implementation "me.leolin:ShortcutBadger:1.1.16" implementation 'se.emilsjolander:stickylistheaders:2.7.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ff5cd0aa9b..ca89c0e19f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -122,6 +122,12 @@ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:launchMode="singleTask"/> + + (messageId, threadId); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 313ee6f789..91680ff431 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -311,7 +311,11 @@ public class ThreadDatabase extends Database { } public boolean hasCalledSince(@NonNull Recipient recipient, long timestamp) { - return DatabaseFactory.getMmsSmsDatabase(context).hasReceivedAnyCallsSince(getThreadIdFor(recipient), timestamp); + return hasReceivedAnyCallsSince(getThreadIdFor(recipient), timestamp); + } + + public boolean hasReceivedAnyCallsSince(long threadId, long timestamp) { + return DatabaseFactory.getMmsSmsDatabase(context).hasReceivedAnyCallsSince(threadId, timestamp); } public List setEntireThreadRead(long threadId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/events/WebRtcViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/events/WebRtcViewModel.java index ef99346822..0a154a25e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/events/WebRtcViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/events/WebRtcViewModel.java @@ -19,6 +19,7 @@ public class WebRtcViewModel { CALL_RINGING, CALL_BUSY, CALL_DISCONNECTED, + CALL_NEEDS_PERMISSION, // Error states NETWORK_FAILURE, diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestActivity.java similarity index 55% rename from app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestDialogFragment.java rename to app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestActivity.java index 1ba3a8437f..f800d51eb0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/CalleeMustAcceptMessageRequestActivity.java @@ -1,20 +1,18 @@ package org.thoughtcrime.securesms.messagerequests; import android.content.Context; -import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; import androidx.lifecycle.ViewModelProviders; +import org.thoughtcrime.securesms.BaseActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; @@ -25,56 +23,45 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import java.util.concurrent.TimeUnit; -public class CalleeMustAcceptMessageRequestDialogFragment extends DialogFragment { +import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; - private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); - private static final String ARG_RECIPIENT_ID = "arg.recipient.id"; +public class CalleeMustAcceptMessageRequestActivity extends BaseActivity { + + private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); + private static final String RECIPIENT_ID_EXTRA = "extra.recipient.id"; private TextView description; private AvatarImageView avatar; private View okay; private final Handler handler = new Handler(Looper.getMainLooper()); - private final Runnable dismisser = this::dismiss; + private final Runnable finisher = this::finish; - public static DialogFragment create(@NonNull RecipientId recipientId) { - DialogFragment fragment = new CalleeMustAcceptMessageRequestDialogFragment(); - Bundle args = new Bundle(); - - args.putParcelable(ARG_RECIPIENT_ID, recipientId); - - fragment.setArguments(args); - - return fragment; + public static Intent createIntent(@NonNull Context context, @NonNull RecipientId recipientId) { + Intent intent = new Intent(context, CalleeMustAcceptMessageRequestActivity.class); + intent.setFlags(FLAG_ACTIVITY_NO_ANIMATION); + intent.putExtra(RECIPIENT_ID_EXTRA, recipientId); + return intent; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.callee_must_accept_message_request_dialog_fragment); - setStyle(DialogFragment.STYLE_NO_FRAME, R.style.TextSecure_DarkNoActionBar); - } - - @Override - public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.callee_must_accept_message_request_dialog_fragment, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - description = view.findViewById(R.id.description); - avatar = view.findViewById(R.id.avatar); - okay = view.findViewById(R.id.okay); + description = findViewById(R.id.description); + avatar = findViewById(R.id.avatar); + okay = findViewById(R.id.okay); avatar.setFallbackPhotoProvider(new FallbackPhotoProvider()); - okay.setOnClickListener(v -> dismiss()); + okay.setOnClickListener(v -> finish()); - RecipientId recipientId = requireArguments().getParcelable(ARG_RECIPIENT_ID); + RecipientId recipientId = getIntent().getParcelableExtra(RECIPIENT_ID_EXTRA); CalleeMustAcceptMessageRequestViewModel.Factory factory = new CalleeMustAcceptMessageRequestViewModel.Factory(recipientId); CalleeMustAcceptMessageRequestViewModel viewModel = ViewModelProviders.of(this, factory).get(CalleeMustAcceptMessageRequestViewModel.class); - viewModel.getRecipient().observe(getViewLifecycleOwner(), recipient -> { - description.setText(getString(R.string.CalleeMustAcceptMessageRequestDialogFragment__s_will_get_a_message_request_from_you, recipient.getDisplayName(requireContext()))); + viewModel.getRecipient().observe(this, recipient -> { + description.setText(getString(R.string.CalleeMustAcceptMessageRequestDialogFragment__s_will_get_a_message_request_from_you, recipient.getDisplayName(this))); avatar.setAvatar(GlideApp.with(this), recipient, false); }); } @@ -83,14 +70,14 @@ public class CalleeMustAcceptMessageRequestDialogFragment extends DialogFragment public void onResume() { super.onResume(); - handler.postDelayed(dismisser, TIMEOUT_MS); + handler.postDelayed(finisher, TIMEOUT_MS); } @Override public void onPause() { super.onPause(); - handler.removeCallbacks(dismisser); + handler.removeCallbacks(finisher); } private static class FallbackPhotoProvider extends Recipient.FallbackPhotoProvider { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index 40e672fcd5..cf2ea018b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -184,13 +184,13 @@ public class RecipientUtil { @WorkerThread private static boolean isMessageRequestAccepted(@NonNull Context context, long threadId, @NonNull Recipient threadRecipient) { - return threadRecipient.isLocalNumber() || - threadRecipient.isProfileSharing() || - threadRecipient.isSystemContact() || - threadRecipient.isForceSmsSelection() || - !threadRecipient.isRegistered() || - hasSentMessageInThread(context, threadId) || - noSecureMessagesInThread(context, threadId) || + return threadRecipient.isLocalNumber() || + threadRecipient.isProfileSharing() || + threadRecipient.isSystemContact() || + threadRecipient.isForceSmsSelection() || + !threadRecipient.isRegistered() || + hasSentMessageInThread(context, threadId) || + noSecureMessagesAndNoCallsInThread(context, threadId) || isPreMessageRequestThread(context, threadId); } @@ -200,8 +200,9 @@ public class RecipientUtil { } @WorkerThread - private static boolean noSecureMessagesInThread(@NonNull Context context, long threadId) { - return DatabaseFactory.getMmsSmsDatabase(context).getSecureConversationCount(threadId) == 0; + private static boolean noSecureMessagesAndNoCallsInThread(@NonNull Context context, long threadId) { + return DatabaseFactory.getMmsSmsDatabase(context).getSecureConversationCount(threadId) == 0 && + !DatabaseFactory.getThreadDatabase(context).hasReceivedAnyCallsSince(threadId, 0); } @WorkerThread diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java index 47857a0f63..11f4d65405 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -117,48 +117,49 @@ public class WebRtcCallService extends Service implements CallManager.Observer, public static final String EXTRA_BROADCAST = "broadcast"; public static final String EXTRA_ANSWER_WITH_VIDEO = "enable_video"; - public static final String ACTION_OUTGOING_CALL = "CALL_OUTGOING"; - public static final String ACTION_DENY_CALL = "DENY_CALL"; - public static final String ACTION_LOCAL_HANGUP = "LOCAL_HANGUP"; - public static final String ACTION_SET_MUTE_AUDIO = "SET_MUTE_AUDIO"; - public static final String ACTION_FLIP_CAMERA = "FLIP_CAMERA"; - public static final String ACTION_BLUETOOTH_CHANGE = "BLUETOOTH_CHANGE"; - public static final String ACTION_WIRED_HEADSET_CHANGE = "WIRED_HEADSET_CHANGE"; - public static final String ACTION_SCREEN_OFF = "SCREEN_OFF"; - public static final String ACTION_IS_IN_CALL_QUERY = "IS_IN_CALL"; - public static final String ACTION_SET_AUDIO_SPEAKER = "SET_AUDIO_SPEAKER"; - public static final String ACTION_SET_AUDIO_BLUETOOTH = "SET_AUDIO_BLUETOOTH"; - public static final String ACTION_CALL_CONNECTED = "CALL_CONNECTED"; - public static final String ACTION_START_OUTGOING_CALL = "START_OUTGOING_CALL"; - public static final String ACTION_START_INCOMING_CALL = "START_INCOMING_CALL"; - public static final String ACTION_LOCAL_RINGING = "LOCAL_RINGING"; - public static final String ACTION_REMOTE_RINGING = "REMOTE_RINGING"; - public static final String ACTION_ACCEPT_CALL = "ACCEPT_CALL"; - public static final String ACTION_SEND_OFFER = "SEND_OFFER"; - public static final String ACTION_SEND_ANSWER = "SEND_ANSWER"; - public static final String ACTION_SEND_ICE_CANDIDATES = "SEND_ICE_CANDIDATES"; - public static final String ACTION_SEND_HANGUP = "SEND_HANGUP"; - public static final String ACTION_SEND_BUSY = "SEND_BUSY"; - public static final String ACTION_RECEIVE_OFFER = "RECEIVE_OFFER"; - public static final String ACTION_RECEIVE_ANSWER = "RECEIVE_ANSWER"; - public static final String ACTION_RECEIVE_ICE_CANDIDATES = "RECEIVE_ICE_CANDIDATES"; - public static final String ACTION_RECEIVE_HANGUP = "RECEIVE_HANGUP"; - public static final String ACTION_RECEIVE_BUSY = "RECEIVE_BUSY"; - public static final String ACTION_REMOTE_VIDEO_ENABLE = "REMOTE_VIDEO_ENABLE"; - public static final String ACTION_SET_ENABLE_VIDEO = "SET_ENABLE_VIDEO"; - public static final String ACTION_ENDED_REMOTE_HANGUP = "ENDED_REMOTE_HANGUP"; - public static final String ACTION_ENDED_REMOTE_HANGUP_ACCEPTED = "ENDED_REMOTE_HANGUP_ACCEPTED"; - public static final String ACTION_ENDED_REMOTE_HANGUP_DECLINED = "ENDED_REMOTE_HANGUP_DECLINED"; - public static final String ACTION_ENDED_REMOTE_HANGUP_BUSY = "ENDED_REMOTE_HANGUP_BUSY"; - public static final String ACTION_ENDED_REMOTE_BUSY = "ENDED_REMOTE_BUSY"; - public static final String ACTION_ENDED_REMOTE_GLARE = "ENDED_REMOTE_GLARE"; - public static final String ACTION_ENDED_TIMEOUT = "ENDED_TIMEOUT"; - public static final String ACTION_ENDED_INTERNAL_FAILURE = "ENDED_INTERNAL_FAILURE"; - public static final String ACTION_ENDED_SIGNALING_FAILURE = "ENDED_SIGNALING_FAILURE"; - public static final String ACTION_ENDED_CONNECTION_FAILURE = "ENDED_CONNECTION_FAILURE"; - public static final String ACTION_ENDED_RX_OFFER_EXPIRED = "ENDED_RX_OFFER_EXPIRED"; - public static final String ACTION_ENDED_RX_OFFER_WHILE_ACTIVE = "ENDED_RX_OFFER_WHILE_ACTIVE"; - public static final String ACTION_CALL_CONCLUDED = "CALL_CONCLUDED"; + public static final String ACTION_OUTGOING_CALL = "CALL_OUTGOING"; + public static final String ACTION_DENY_CALL = "DENY_CALL"; + public static final String ACTION_LOCAL_HANGUP = "LOCAL_HANGUP"; + public static final String ACTION_SET_MUTE_AUDIO = "SET_MUTE_AUDIO"; + public static final String ACTION_FLIP_CAMERA = "FLIP_CAMERA"; + public static final String ACTION_BLUETOOTH_CHANGE = "BLUETOOTH_CHANGE"; + public static final String ACTION_WIRED_HEADSET_CHANGE = "WIRED_HEADSET_CHANGE"; + public static final String ACTION_SCREEN_OFF = "SCREEN_OFF"; + public static final String ACTION_IS_IN_CALL_QUERY = "IS_IN_CALL"; + public static final String ACTION_SET_AUDIO_SPEAKER = "SET_AUDIO_SPEAKER"; + public static final String ACTION_SET_AUDIO_BLUETOOTH = "SET_AUDIO_BLUETOOTH"; + public static final String ACTION_CALL_CONNECTED = "CALL_CONNECTED"; + public static final String ACTION_START_OUTGOING_CALL = "START_OUTGOING_CALL"; + public static final String ACTION_START_INCOMING_CALL = "START_INCOMING_CALL"; + public static final String ACTION_LOCAL_RINGING = "LOCAL_RINGING"; + public static final String ACTION_REMOTE_RINGING = "REMOTE_RINGING"; + public static final String ACTION_ACCEPT_CALL = "ACCEPT_CALL"; + public static final String ACTION_SEND_OFFER = "SEND_OFFER"; + public static final String ACTION_SEND_ANSWER = "SEND_ANSWER"; + public static final String ACTION_SEND_ICE_CANDIDATES = "SEND_ICE_CANDIDATES"; + public static final String ACTION_SEND_HANGUP = "SEND_HANGUP"; + public static final String ACTION_SEND_BUSY = "SEND_BUSY"; + public static final String ACTION_RECEIVE_OFFER = "RECEIVE_OFFER"; + public static final String ACTION_RECEIVE_ANSWER = "RECEIVE_ANSWER"; + public static final String ACTION_RECEIVE_ICE_CANDIDATES = "RECEIVE_ICE_CANDIDATES"; + public static final String ACTION_RECEIVE_HANGUP = "RECEIVE_HANGUP"; + public static final String ACTION_RECEIVE_BUSY = "RECEIVE_BUSY"; + public static final String ACTION_REMOTE_VIDEO_ENABLE = "REMOTE_VIDEO_ENABLE"; + public static final String ACTION_SET_ENABLE_VIDEO = "SET_ENABLE_VIDEO"; + public static final String ACTION_ENDED_REMOTE_HANGUP = "ENDED_REMOTE_HANGUP"; + public static final String ACTION_ENDED_REMOTE_HANGUP_ACCEPTED = "ENDED_REMOTE_HANGUP_ACCEPTED"; + public static final String ACTION_ENDED_REMOTE_HANGUP_DECLINED = "ENDED_REMOTE_HANGUP_DECLINED"; + public static final String ACTION_ENDED_REMOTE_HANGUP_BUSY = "ENDED_REMOTE_HANGUP_BUSY"; + public static final String ACTION_ENDED_REMOTE_HANGUP_NEED_PERMISSION = "ENDED_REMOTE_HANGUP_NEED_PERMISSION"; + public static final String ACTION_ENDED_REMOTE_BUSY = "ENDED_REMOTE_BUSY"; + public static final String ACTION_ENDED_REMOTE_GLARE = "ENDED_REMOTE_GLARE"; + public static final String ACTION_ENDED_TIMEOUT = "ENDED_TIMEOUT"; + public static final String ACTION_ENDED_INTERNAL_FAILURE = "ENDED_INTERNAL_FAILURE"; + public static final String ACTION_ENDED_SIGNALING_FAILURE = "ENDED_SIGNALING_FAILURE"; + public static final String ACTION_ENDED_CONNECTION_FAILURE = "ENDED_CONNECTION_FAILURE"; + public static final String ACTION_ENDED_RX_OFFER_EXPIRED = "ENDED_RX_OFFER_EXPIRED"; + public static final String ACTION_ENDED_RX_OFFER_WHILE_ACTIVE = "ENDED_RX_OFFER_WHILE_ACTIVE"; + public static final String ACTION_CALL_CONCLUDED = "CALL_CONCLUDED"; private CameraState localCameraState = CameraState.UNKNOWN; private boolean microphoneEnabled = true; @@ -213,48 +214,49 @@ public class WebRtcCallService extends Service implements CallManager.Observer, if (intent == null || intent.getAction() == null) return START_NOT_STICKY; serviceExecutor.execute(() -> { - if (intent.getAction().equals(ACTION_RECEIVE_OFFER)) handleReceivedOffer(intent); - else if (intent.getAction().equals(ACTION_RECEIVE_BUSY)) handleReceivedBusy(intent); - else if (intent.getAction().equals(ACTION_OUTGOING_CALL) && isIdle()) handleOutgoingCall(intent); - else if (intent.getAction().equals(ACTION_DENY_CALL)) handleDenyCall(intent); - else if (intent.getAction().equals(ACTION_LOCAL_HANGUP)) handleLocalHangup(intent); - else if (intent.getAction().equals(ACTION_SET_MUTE_AUDIO)) handleSetMuteAudio(intent); - else if (intent.getAction().equals(ACTION_FLIP_CAMERA)) handleSetCameraFlip(intent); - else if (intent.getAction().equals(ACTION_BLUETOOTH_CHANGE)) handleBluetoothChange(intent); - else if (intent.getAction().equals(ACTION_WIRED_HEADSET_CHANGE)) handleWiredHeadsetChange(intent); - else if (intent.getAction().equals(ACTION_SCREEN_OFF)) handleScreenOffChange(intent); - else if (intent.getAction().equals(ACTION_CALL_CONNECTED)) handleCallConnected(intent); - else if (intent.getAction().equals(ACTION_IS_IN_CALL_QUERY)) handleIsInCallQuery(intent); - else if (intent.getAction().equals(ACTION_SET_AUDIO_SPEAKER)) handleSetSpeakerAudio(intent); - else if (intent.getAction().equals(ACTION_SET_AUDIO_BLUETOOTH)) handleSetBluetoothAudio(intent); - else if (intent.getAction().equals(ACTION_START_OUTGOING_CALL)) handleStartOutgoingCall(intent); - else if (intent.getAction().equals(ACTION_START_INCOMING_CALL)) handleStartIncomingCall(intent); - else if (intent.getAction().equals(ACTION_ACCEPT_CALL)) handleAcceptCall(intent); - else if (intent.getAction().equals(ACTION_LOCAL_RINGING)) handleLocalRinging(intent); - else if (intent.getAction().equals(ACTION_REMOTE_RINGING)) handleRemoteRinging(intent); - else if (intent.getAction().equals(ACTION_SEND_OFFER)) handleSendOffer(intent); - else if (intent.getAction().equals(ACTION_SEND_ANSWER)) handleSendAnswer(intent); - else if (intent.getAction().equals(ACTION_SEND_ICE_CANDIDATES)) handleSendIceCandidates(intent); - else if (intent.getAction().equals(ACTION_SEND_HANGUP)) handleSendHangup(intent); - else if (intent.getAction().equals(ACTION_SEND_BUSY)) handleSendBusy(intent); - else if (intent.getAction().equals(ACTION_RECEIVE_ANSWER)) handleReceivedAnswer(intent); - else if (intent.getAction().equals(ACTION_RECEIVE_ICE_CANDIDATES)) handleReceivedIceCandidates(intent); - else if (intent.getAction().equals(ACTION_RECEIVE_HANGUP)) handleReceivedHangup(intent); - else if (intent.getAction().equals(ACTION_REMOTE_VIDEO_ENABLE)) handleRemoteVideoEnable(intent); - else if (intent.getAction().equals(ACTION_SET_ENABLE_VIDEO)) handleSetEnableVideo(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP)) handleEndedRemoteHangup(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_ACCEPTED)) handleEndedRemoteHangupAccepted(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_BUSY)) handleEndedRemoteHangupBusy(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_DECLINED)) handleEndedRemoteHangupDeclined(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_BUSY)) handleEndedRemoteBusy(intent); - else if (intent.getAction().equals(ACTION_ENDED_REMOTE_GLARE)) handleEndedRemoteGlare(intent); - else if (intent.getAction().equals(ACTION_ENDED_TIMEOUT)) handleEndedTimeout(intent); - else if (intent.getAction().equals(ACTION_ENDED_INTERNAL_FAILURE)) handleEndedInternalFailure(intent); - else if (intent.getAction().equals(ACTION_ENDED_SIGNALING_FAILURE)) handleEndedSignalingFailure(intent); - else if (intent.getAction().equals(ACTION_ENDED_CONNECTION_FAILURE)) handleEndedConnectionFailure(intent); - else if (intent.getAction().equals(ACTION_ENDED_RX_OFFER_EXPIRED)) handleEndedReceivedOfferExpired(intent); - else if (intent.getAction().equals(ACTION_ENDED_RX_OFFER_WHILE_ACTIVE)) handleEndedReceivedOfferWhileActive(intent); - else if (intent.getAction().equals(ACTION_CALL_CONCLUDED)) handleCallConcluded(intent); + if (intent.getAction().equals(ACTION_RECEIVE_OFFER)) handleReceivedOffer(intent); + else if (intent.getAction().equals(ACTION_RECEIVE_BUSY)) handleReceivedBusy(intent); + else if (intent.getAction().equals(ACTION_OUTGOING_CALL) && isIdle()) handleOutgoingCall(intent); + else if (intent.getAction().equals(ACTION_DENY_CALL)) handleDenyCall(intent); + else if (intent.getAction().equals(ACTION_LOCAL_HANGUP)) handleLocalHangup(intent); + else if (intent.getAction().equals(ACTION_SET_MUTE_AUDIO)) handleSetMuteAudio(intent); + else if (intent.getAction().equals(ACTION_FLIP_CAMERA)) handleSetCameraFlip(intent); + else if (intent.getAction().equals(ACTION_BLUETOOTH_CHANGE)) handleBluetoothChange(intent); + else if (intent.getAction().equals(ACTION_WIRED_HEADSET_CHANGE)) handleWiredHeadsetChange(intent); + else if (intent.getAction().equals(ACTION_SCREEN_OFF)) handleScreenOffChange(intent); + else if (intent.getAction().equals(ACTION_CALL_CONNECTED)) handleCallConnected(intent); + else if (intent.getAction().equals(ACTION_IS_IN_CALL_QUERY)) handleIsInCallQuery(intent); + else if (intent.getAction().equals(ACTION_SET_AUDIO_SPEAKER)) handleSetSpeakerAudio(intent); + else if (intent.getAction().equals(ACTION_SET_AUDIO_BLUETOOTH)) handleSetBluetoothAudio(intent); + else if (intent.getAction().equals(ACTION_START_OUTGOING_CALL)) handleStartOutgoingCall(intent); + else if (intent.getAction().equals(ACTION_START_INCOMING_CALL)) handleStartIncomingCall(intent); + else if (intent.getAction().equals(ACTION_ACCEPT_CALL)) handleAcceptCall(intent); + else if (intent.getAction().equals(ACTION_LOCAL_RINGING)) handleLocalRinging(intent); + else if (intent.getAction().equals(ACTION_REMOTE_RINGING)) handleRemoteRinging(intent); + else if (intent.getAction().equals(ACTION_SEND_OFFER)) handleSendOffer(intent); + else if (intent.getAction().equals(ACTION_SEND_ANSWER)) handleSendAnswer(intent); + else if (intent.getAction().equals(ACTION_SEND_ICE_CANDIDATES)) handleSendIceCandidates(intent); + else if (intent.getAction().equals(ACTION_SEND_HANGUP)) handleSendHangup(intent); + else if (intent.getAction().equals(ACTION_SEND_BUSY)) handleSendBusy(intent); + else if (intent.getAction().equals(ACTION_RECEIVE_ANSWER)) handleReceivedAnswer(intent); + else if (intent.getAction().equals(ACTION_RECEIVE_ICE_CANDIDATES)) handleReceivedIceCandidates(intent); + else if (intent.getAction().equals(ACTION_RECEIVE_HANGUP)) handleReceivedHangup(intent); + else if (intent.getAction().equals(ACTION_REMOTE_VIDEO_ENABLE)) handleRemoteVideoEnable(intent); + else if (intent.getAction().equals(ACTION_SET_ENABLE_VIDEO)) handleSetEnableVideo(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP)) handleEndedRemoteHangup(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_ACCEPTED)) handleEndedRemoteHangupAccepted(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_BUSY)) handleEndedRemoteHangupBusy(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_DECLINED)) handleEndedRemoteHangupDeclined(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_BUSY)) handleEndedRemoteBusy(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_HANGUP_NEED_PERMISSION)) handleEndedRemoteNeedPermission(intent); + else if (intent.getAction().equals(ACTION_ENDED_REMOTE_GLARE)) handleEndedRemoteGlare(intent); + else if (intent.getAction().equals(ACTION_ENDED_TIMEOUT)) handleEndedTimeout(intent); + else if (intent.getAction().equals(ACTION_ENDED_INTERNAL_FAILURE)) handleEndedInternalFailure(intent); + else if (intent.getAction().equals(ACTION_ENDED_SIGNALING_FAILURE)) handleEndedSignalingFailure(intent); + else if (intent.getAction().equals(ACTION_ENDED_CONNECTION_FAILURE)) handleEndedConnectionFailure(intent); + else if (intent.getAction().equals(ACTION_ENDED_RX_OFFER_EXPIRED)) handleEndedReceivedOfferExpired(intent); + else if (intent.getAction().equals(ACTION_ENDED_RX_OFFER_WHILE_ACTIVE)) handleEndedReceivedOfferWhileActive(intent); + else if (intent.getAction().equals(ACTION_CALL_CONCLUDED)) handleCallConcluded(intent); }); @@ -403,9 +405,10 @@ public class WebRtcCallService extends Service implements CallManager.Observer, return; } - if (offerType == OfferMessage.Type.NEED_PERMISSION || FeatureFlags.profileForCalling() && !remotePeer.getRecipient().resolve().isProfileSharing()) { + if (FeatureFlags.profileForCalling() && (remotePeer.getRecipient() == null || !RecipientUtil.isMessageRequestAccepted(getApplicationContext(), remotePeer.getRecipient()))) { Log.i(TAG, "handleReceivedOffer(): Caller is untrusted."); intent.putExtra(EXTRA_BROADCAST, true); + intent.putExtra(EXTRA_HANGUP_TYPE, HangupMessage.Type.NEED_PERMISSION.getCode()); handleSendHangup(intent); insertMissedCall(remotePeer, true); return; @@ -706,11 +709,6 @@ public class WebRtcCallService extends Service implements CallManager.Observer, Log.i(TAG, "handleSendOffer: id: " + callId.format(remoteDevice)); - if (FeatureFlags.profileForCalling() && remotePeer.getRecipient().resolve().getProfileKey() == null) { - offer = ""; - offerType = OfferMessage.Type.NEED_PERMISSION; - } - OfferMessage offerMessage = new OfferMessage(callId.longValue(), offer, offerType); Integer destinationDeviceId = broadcast ? null : remoteDevice; SignalServiceCallMessage callMessage = SignalServiceCallMessage.forOffer(offerMessage, true, destinationDeviceId); @@ -1137,6 +1135,16 @@ public class WebRtcCallService extends Service implements CallManager.Observer, }, WebRtcCallActivity.BUSY_SIGNAL_DELAY_FINISH); } + private void handleEndedRemoteNeedPermission(Intent intent) { + RemotePeer remotePeer = getRemotePeer(intent); + + Log.i(TAG, "handleEndedRemoteNeedPermission(): call_id: " + remotePeer.getCallId()); + + if (remotePeer.callIdEquals(activePeer)) { + sendMessage(WebRtcViewModel.State.CALL_NEEDS_PERMISSION, remotePeer, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled, isRemoteVideoOffer); + } + } + private void handleEndedRemoteGlare(Intent intent) { RemotePeer remotePeer = getRemotePeer(intent); @@ -1386,6 +1394,8 @@ public class WebRtcCallService extends Service implements CallManager.Observer, return CallManager.HangupType.NORMAL; case DECLINED: return CallManager.HangupType.DECLINED; + case NEED_PERMISSION: + return CallManager.HangupType.NEED_PERMISSION; default: throw new IllegalArgumentException("Unexpected hangup type: " + hangupType); } @@ -1401,6 +1411,8 @@ public class WebRtcCallService extends Service implements CallManager.Observer, return HangupMessage.Type.NORMAL; case DECLINED: return HangupMessage.Type.DECLINED; + case NEED_PERMISSION: + return HangupMessage.Type.NEED_PERMISSION; default: throw new IllegalArgumentException("Unexpected hangup type: " + hangupType); } @@ -1723,6 +1735,9 @@ public class WebRtcCallService extends Service implements CallManager.Observer, case ENDED_REMOTE_HANGUP: intent.setAction(ACTION_ENDED_REMOTE_HANGUP); break; + case ENDED_REMOTE_HANGUP_NEED_PERMISSION: + intent.setAction(ACTION_ENDED_REMOTE_HANGUP_NEED_PERMISSION); + break; case ENDED_REMOTE_HANGUP_ACCEPTED: intent.setAction(ACTION_ENDED_REMOTE_HANGUP_ACCEPTED); break; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java index e435ed863d..507194f4cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java @@ -25,7 +25,6 @@ import org.thoughtcrime.securesms.WebRtcCallActivity; import org.thoughtcrime.securesms.conversation.ConversationActivity; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.messagerequests.CalleeMustAcceptMessageRequestDialogFragment; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.ringrtc.RemotePeer; @@ -197,16 +196,11 @@ public class CommunicationActions { MessageSender.onMessageSent(); - if (FeatureFlags.profileForCalling() && recipient.resolve().getProfileKey() == null) { - CalleeMustAcceptMessageRequestDialogFragment.create(recipient.getId()) - .show(activity.getSupportFragmentManager(), null); - } else { - Intent activityIntent = new Intent(activity, WebRtcCallActivity.class); + Intent activityIntent = new Intent(activity, WebRtcCallActivity.class); - activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - activity.startActivity(activityIntent); - } + activity.startActivity(activityIntent); }) .execute(); } @@ -228,17 +222,12 @@ public class CommunicationActions { MessageSender.onMessageSent(); - if (FeatureFlags.profileForCalling() && recipient.resolve().getProfileKey() == null) { - CalleeMustAcceptMessageRequestDialogFragment.create(recipient.getId()) - .show(activity.getSupportFragmentManager(), null); - } else { - Intent activityIntent = new Intent(activity, WebRtcCallActivity.class); + Intent activityIntent = new Intent(activity, WebRtcCallActivity.class); - activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(WebRtcCallActivity.EXTRA_ENABLE_VIDEO_IF_AVAILABLE, true); + activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(WebRtcCallActivity.EXTRA_ENABLE_VIDEO_IF_AVAILABLE, true); - activity.startActivity(activityIntent); - } + activity.startActivity(activityIntent); }) .execute(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index c942140923..7cf6f84222 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -55,7 +55,7 @@ public final class FeatureFlags { private static final String PINS_MEGAPHONE_KILL_SWITCH = "android.pinsMegaphoneKillSwitch"; private static final String ATTACHMENTS_V3 = "android.attachmentsV3"; private static final String REMOTE_DELETE = "android.remoteDelete"; - private static final String PROFILE_FOR_CALLING = "android.profileForCalling"; + private static final String PROFILE_FOR_CALLING = "android.profileForCalling.2"; private static final String CALLING_PIP = "android.callingPip"; private static final String VERSIONED_PROFILES_1 = "android.versionedProfiles"; private static final String VERSIONED_PROFILES_2 = "android.versionedProfiles.2"; diff --git a/app/witness-verifications.gradle b/app/witness-verifications.gradle index 65cf2487cc..9070517b14 100644 --- a/app/witness-verifications.gradle +++ b/app/witness-verifications.gradle @@ -432,8 +432,8 @@ dependencyVerification { ['org.signal:argon2:13.1', '0f686ccff0d4842bfcc74d92e8dc780a5f159b9376e37a1189fabbcdac458bef'], - ['org.signal:ringrtc-android:2.2.0', - '10da52bd63cb6c0ba45927928b0da3fd59621e3e698ef17f2dbbb1d3b293e80e'], + ['org.signal:ringrtc-android:2.3.1', + '2860e38b3e01c25ff23abdb848bd3fd772ffddb4387ea7838b71e2400da1648d'], ['org.signal:signal-metadata-java:0.1.2', '6aaeb6a33bf3161a3e6ac9db7678277f7a4cf5a2c96b84342e4007ee49bab1bd'], diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/HangupMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/HangupMessage.java index 0c21da801d..5fa2cecdf3 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/HangupMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/HangupMessage.java @@ -37,7 +37,8 @@ public class HangupMessage { NORMAL("normal", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_NORMAL), ACCEPTED("accepted", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_ACCEPTED), DECLINED("declined", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_DECLINED), - BUSY("busy", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_BUSY); + BUSY("busy", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_BUSY), + NEED_PERMISSION("need_permission", SignalServiceProtos.CallMessage.Hangup.Type.HANGUP_NEED_PERMISSION); private final String code; private final SignalServiceProtos.CallMessage.Hangup.Type protoType; diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/OfferMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/OfferMessage.java index 0d5e102125..c562afbdbe 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/OfferMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/calls/OfferMessage.java @@ -29,8 +29,7 @@ public class OfferMessage { public enum Type { AUDIO_CALL("audio_call", SignalServiceProtos.CallMessage.Offer.Type.OFFER_AUDIO_CALL), - VIDEO_CALL("video_call", SignalServiceProtos.CallMessage.Offer.Type.OFFER_VIDEO_CALL), - NEED_PERMISSION("need_permission", SignalServiceProtos.CallMessage.Offer.Type.OFFER_NEED_PERMISSION); + VIDEO_CALL("video_call", SignalServiceProtos.CallMessage.Offer.Type.OFFER_VIDEO_CALL); private final String code; private final SignalServiceProtos.CallMessage.Offer.Type protoType; diff --git a/libsignal/service/src/main/proto/SignalService.proto b/libsignal/service/src/main/proto/SignalService.proto index 1d351a8ae3..98623989cc 100644 --- a/libsignal/service/src/main/proto/SignalService.proto +++ b/libsignal/service/src/main/proto/SignalService.proto @@ -46,7 +46,7 @@ message CallMessage { enum Type { OFFER_AUDIO_CALL = 0; OFFER_VIDEO_CALL = 1; - OFFER_NEED_PERMISSION = 2; + // 2 is reserved, removed OFFER_NEED_PERMISSION } optional uint64 id = 1; @@ -72,10 +72,11 @@ message CallMessage { message Hangup { enum Type { - HANGUP_NORMAL = 0; - HANGUP_ACCEPTED = 1; - HANGUP_DECLINED = 2; - HANGUP_BUSY = 3; + HANGUP_NORMAL = 0; + HANGUP_ACCEPTED = 1; + HANGUP_DECLINED = 2; + HANGUP_BUSY = 3; + HANGUP_NEED_PERMISSION = 4; } optional uint64 id = 1;