Search in sources :

Example 1 with NotificationProfile

use of org.thoughtcrime.securesms.notifications.profiles.NotificationProfile in project Signal-Android by WhisperSystems.

the class WebRtcActionProcessor method handleReceivedOffer.

// endregion Outgoing call
// region Incoming call
@NonNull
protected WebRtcServiceState handleReceivedOffer(@NonNull WebRtcServiceState currentState, @NonNull CallMetadata callMetadata, @NonNull OfferMetadata offerMetadata, @NonNull ReceivedOfferMetadata receivedOfferMetadata) {
    Log.i(tag, "handleReceivedOffer(): id: " + callMetadata.getCallId().format(callMetadata.getRemoteDevice()) + " offer_type:" + offerMetadata.getOfferType());
    if (TelephonyUtil.isAnyPstnLineBusy(context)) {
        Log.i(tag, "PSTN line is busy.");
        currentState = currentState.getActionProcessor().handleSendBusy(currentState, callMetadata, true);
        webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
        return currentState;
    }
    if (!RecipientUtil.isCallRequestAccepted(context.getApplicationContext(), callMetadata.getRemotePeer().getRecipient())) {
        Log.w(tag, "Caller is untrusted.");
        currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NEED_PERMISSION), true);
        webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
        return currentState;
    }
    if (offerMetadata.getOpaque() == null) {
        Log.w(tag, "Opaque data is required.");
        currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NORMAL), true);
        webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
        return currentState;
    }
    NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(SignalDatabase.notificationProfiles().getProfiles());
    if (activeProfile != null && !(activeProfile.isRecipientAllowed(callMetadata.getRemotePeer().getId()) || activeProfile.getAllowAllCalls())) {
        Log.w(tag, "Caller is excluded by notification profile.");
        currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NORMAL), true);
        webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
        return currentState;
    }
    Log.i(tag, "add remotePeer callId: " + callMetadata.getRemotePeer().getCallId() + " key: " + callMetadata.getRemotePeer().hashCode());
    callMetadata.getRemotePeer().setCallStartTimestamp(receivedOfferMetadata.getServerReceivedTimestamp());
    currentState = currentState.builder().changeCallSetupState(callMetadata.getCallId()).isRemoteVideoOffer(offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL).commit().changeCallInfoState().putRemotePeer(callMetadata.getRemotePeer()).build();
    long messageAgeSec = Math.max(receivedOfferMetadata.getServerDeliveredTimestamp() - receivedOfferMetadata.getServerReceivedTimestamp(), 0) / 1000;
    Log.i(tag, "messageAgeSec: " + messageAgeSec + ", serverReceivedTimestamp: " + receivedOfferMetadata.getServerReceivedTimestamp() + ", serverDeliveredTimestamp: " + receivedOfferMetadata.getServerDeliveredTimestamp());
    try {
        byte[] remoteIdentityKey = WebRtcUtil.getPublicKeyBytes(receivedOfferMetadata.getRemoteIdentityKey());
        byte[] localIdentityKey = WebRtcUtil.getPublicKeyBytes(SignalStore.account().getAciIdentityKey().getPublicKey().serialize());
        webRtcInteractor.getCallManager().receivedOffer(callMetadata.getCallId(), callMetadata.getRemotePeer(), callMetadata.getRemoteDevice(), offerMetadata.getOpaque(), messageAgeSec, WebRtcUtil.getCallMediaTypeFromOfferType(offerMetadata.getOfferType()), SignalStore.account().getDeviceId(), SignalStore.account().isPrimaryDevice(), remoteIdentityKey, localIdentityKey);
    } catch (CallException | InvalidKeyException e) {
        return callFailure(currentState, "Unable to process received offer: ", e);
    }
    return currentState;
}
Also used : CallException(org.signal.ringrtc.CallException) NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) NonNull(androidx.annotation.NonNull)

Example 2 with NotificationProfile

use of org.thoughtcrime.securesms.notifications.profiles.NotificationProfile in project Signal-Android by WhisperSystems.

the class ConversationListFragment method updateNotificationProfileStatus.

private void updateNotificationProfileStatus(@NonNull List<NotificationProfile> notificationProfiles) {
    NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(notificationProfiles);
    if (activeProfile != null) {
        if (activeProfile.getId() != SignalStore.notificationProfileValues().getLastProfilePopup()) {
            requireView().postDelayed(() -> {
                SignalStore.notificationProfileValues().setLastProfilePopup(activeProfile.getId());
                SignalStore.notificationProfileValues().setLastProfilePopupTime(System.currentTimeMillis());
                if (previousTopToastPopup != null && previousTopToastPopup.isShowing()) {
                    previousTopToastPopup.dismiss();
                }
                ViewGroup view = ((ViewGroup) requireView());
                Fragment fragment = getParentFragmentManager().findFragmentByTag(BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
                if (fragment != null && fragment.isAdded() && fragment.getView() != null) {
                    view = ((ViewGroup) fragment.requireView());
                }
                try {
                    previousTopToastPopup = TopToastPopup.show(view, R.drawable.ic_moon_16, getString(R.string.ConversationListFragment__s_on, activeProfile.getName()));
                } catch (Exception e) {
                    Log.w(TAG, "Unable to show toast popup", e);
                }
            }, 500L);
        }
        notificationProfileStatus.setVisibility(View.VISIBLE);
    } else {
        notificationProfileStatus.setVisibility(View.GONE);
    }
    if (!SignalStore.notificationProfileValues().getHasSeenTooltip() && Util.hasItems(notificationProfiles)) {
        View target = findOverflowMenuButton(getToolbar(requireView()));
        if (target != null) {
            TooltipPopup.forTarget(target).setText(R.string.ConversationListFragment__turn_your_notification_profile_on_or_off_here).setBackgroundTint(ContextCompat.getColor(requireContext(), R.color.signal_button_primary)).setTextColor(ContextCompat.getColor(requireContext(), R.color.signal_button_primary_text)).setOnDismissListener(() -> SignalStore.notificationProfileValues().setHasSeenTooltip(true)).show(POSITION_BELOW);
        } else {
            Log.w(TAG, "Unable to find overflow menu to show Notification Profile tooltip");
        }
    }
}
Also used : NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) ViewGroup(android.view.ViewGroup) RecaptchaProofBottomSheetFragment(org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment) Fragment(androidx.fragment.app.Fragment) DialogFragment(androidx.fragment.app.DialogFragment) CantProcessSubscriptionPaymentBottomSheetDialogFragment(org.thoughtcrime.securesms.badges.self.expired.CantProcessSubscriptionPaymentBottomSheetDialogFragment) MainFragment(org.thoughtcrime.securesms.MainFragment) NotificationProfileSelectionFragment(org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment) ConversationFragment(org.thoughtcrime.securesms.conversation.ConversationFragment) ExpiredBadgeBottomSheetDialogFragment(org.thoughtcrime.securesms.badges.self.expired.ExpiredBadgeBottomSheetDialogFragment) ImageView(android.widget.ImageView) ActionMenuView(androidx.appcompat.widget.ActionMenuView) ReminderView(org.thoughtcrime.securesms.components.reminder.ReminderView) UnreadPaymentsView(org.thoughtcrime.securesms.components.UnreadPaymentsView) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) VoiceNotePlayerView(org.thoughtcrime.securesms.components.voice.VoiceNotePlayerView) TextView(android.widget.TextView) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView)

Example 3 with NotificationProfile

use of org.thoughtcrime.securesms.notifications.profiles.NotificationProfile in project Signal-Android by signalapp.

the class ConversationListFragment method updateNotificationProfileStatus.

private void updateNotificationProfileStatus(@NonNull List<NotificationProfile> notificationProfiles) {
    NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(notificationProfiles);
    if (activeProfile != null) {
        if (activeProfile.getId() != SignalStore.notificationProfileValues().getLastProfilePopup()) {
            requireView().postDelayed(() -> {
                SignalStore.notificationProfileValues().setLastProfilePopup(activeProfile.getId());
                SignalStore.notificationProfileValues().setLastProfilePopupTime(System.currentTimeMillis());
                if (previousTopToastPopup != null && previousTopToastPopup.isShowing()) {
                    previousTopToastPopup.dismiss();
                }
                ViewGroup view = ((ViewGroup) requireView());
                Fragment fragment = getParentFragmentManager().findFragmentByTag(BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
                if (fragment != null && fragment.isAdded() && fragment.getView() != null) {
                    view = ((ViewGroup) fragment.requireView());
                }
                try {
                    previousTopToastPopup = TopToastPopup.show(view, R.drawable.ic_moon_16, getString(R.string.ConversationListFragment__s_on, activeProfile.getName()));
                } catch (Exception e) {
                    Log.w(TAG, "Unable to show toast popup", e);
                }
            }, 500L);
        }
        notificationProfileStatus.setVisibility(View.VISIBLE);
    } else {
        notificationProfileStatus.setVisibility(View.GONE);
    }
    if (!SignalStore.notificationProfileValues().getHasSeenTooltip() && Util.hasItems(notificationProfiles)) {
        View target = findOverflowMenuButton(getToolbar(requireView()));
        if (target != null) {
            TooltipPopup.forTarget(target).setText(R.string.ConversationListFragment__turn_your_notification_profile_on_or_off_here).setBackgroundTint(ContextCompat.getColor(requireContext(), R.color.signal_button_primary)).setTextColor(ContextCompat.getColor(requireContext(), R.color.signal_button_primary_text)).setOnDismissListener(() -> SignalStore.notificationProfileValues().setHasSeenTooltip(true)).show(POSITION_BELOW);
        } else {
            Log.w(TAG, "Unable to find overflow menu to show Notification Profile tooltip");
        }
    }
}
Also used : NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) ViewGroup(android.view.ViewGroup) RecaptchaProofBottomSheetFragment(org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment) Fragment(androidx.fragment.app.Fragment) DialogFragment(androidx.fragment.app.DialogFragment) CantProcessSubscriptionPaymentBottomSheetDialogFragment(org.thoughtcrime.securesms.badges.self.expired.CantProcessSubscriptionPaymentBottomSheetDialogFragment) MainFragment(org.thoughtcrime.securesms.MainFragment) NotificationProfileSelectionFragment(org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment) ConversationFragment(org.thoughtcrime.securesms.conversation.ConversationFragment) ExpiredBadgeBottomSheetDialogFragment(org.thoughtcrime.securesms.badges.self.expired.ExpiredBadgeBottomSheetDialogFragment) ImageView(android.widget.ImageView) ActionMenuView(androidx.appcompat.widget.ActionMenuView) ReminderView(org.thoughtcrime.securesms.components.reminder.ReminderView) UnreadPaymentsView(org.thoughtcrime.securesms.components.UnreadPaymentsView) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) VoiceNotePlayerView(org.thoughtcrime.securesms.components.voice.VoiceNotePlayerView) TextView(android.widget.TextView) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView)

Example 4 with NotificationProfile

use of org.thoughtcrime.securesms.notifications.profiles.NotificationProfile in project Signal-Android by WhisperSystems.

the class IdleActionProcessor method handleGroupCallRingUpdate.

@Override
@NonNull
protected WebRtcServiceState handleGroupCallRingUpdate(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeerGroup, @NonNull GroupId.V2 groupId, long ringId, @NonNull UUID uuid, @NonNull CallManager.RingUpdate ringUpdate) {
    Log.i(TAG, "handleGroupCallRingUpdate(): recipient: " + remotePeerGroup.getId() + " ring: " + ringId + " update: " + ringUpdate);
    if (ringUpdate != CallManager.RingUpdate.REQUESTED) {
        SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
        return currentState;
    } else if (SignalDatabase.groupCallRings().isCancelled(ringId)) {
        try {
            Log.i(TAG, "Incoming ring request for already cancelled ring: " + ringId);
            webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, null);
        } catch (CallException e) {
            Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
        }
        return currentState;
    }
    NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(SignalDatabase.notificationProfiles().getProfiles());
    if (activeProfile != null && !(activeProfile.isRecipientAllowed(remotePeerGroup.getId()) || activeProfile.getAllowAllCalls())) {
        try {
            Log.i(TAG, "Incoming ring request for profile restricted recipient");
            SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
            webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.DeclinedByUser);
        } catch (CallException e) {
            Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
        }
        return currentState;
    }
    webRtcInteractor.peekGroupCallForRingingCheck(new GroupCallRingCheckInfo(remotePeerGroup.getId(), groupId, ringId, uuid, ringUpdate));
    return currentState;
}
Also used : CallException(org.signal.ringrtc.CallException) NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) NonNull(androidx.annotation.NonNull)

Example 5 with NotificationProfile

use of org.thoughtcrime.securesms.notifications.profiles.NotificationProfile in project Signal-Android by signalapp.

the class IdleActionProcessor method handleGroupCallRingUpdate.

@Override
@NonNull
protected WebRtcServiceState handleGroupCallRingUpdate(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeerGroup, @NonNull GroupId.V2 groupId, long ringId, @NonNull UUID uuid, @NonNull CallManager.RingUpdate ringUpdate) {
    Log.i(TAG, "handleGroupCallRingUpdate(): recipient: " + remotePeerGroup.getId() + " ring: " + ringId + " update: " + ringUpdate);
    if (ringUpdate != CallManager.RingUpdate.REQUESTED) {
        SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
        return currentState;
    } else if (SignalDatabase.groupCallRings().isCancelled(ringId)) {
        try {
            Log.i(TAG, "Incoming ring request for already cancelled ring: " + ringId);
            webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, null);
        } catch (CallException e) {
            Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
        }
        return currentState;
    }
    NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(SignalDatabase.notificationProfiles().getProfiles());
    if (activeProfile != null && !(activeProfile.isRecipientAllowed(remotePeerGroup.getId()) || activeProfile.getAllowAllCalls())) {
        try {
            Log.i(TAG, "Incoming ring request for profile restricted recipient");
            SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
            webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.DeclinedByUser);
        } catch (CallException e) {
            Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
        }
        return currentState;
    }
    webRtcInteractor.peekGroupCallForRingingCheck(new GroupCallRingCheckInfo(remotePeerGroup.getId(), groupId, ringId, uuid, ringUpdate));
    return currentState;
}
Also used : CallException(org.signal.ringrtc.CallException) NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) NonNull(androidx.annotation.NonNull)

Aggregations

NotificationProfile (org.thoughtcrime.securesms.notifications.profiles.NotificationProfile)6 NonNull (androidx.annotation.NonNull)4 CallException (org.signal.ringrtc.CallException)4 View (android.view.View)2 ViewGroup (android.view.ViewGroup)2 ImageView (android.widget.ImageView)2 TextView (android.widget.TextView)2 ActionMenuView (androidx.appcompat.widget.ActionMenuView)2 DialogFragment (androidx.fragment.app.DialogFragment)2 Fragment (androidx.fragment.app.Fragment)2 RecyclerView (androidx.recyclerview.widget.RecyclerView)2 MainFragment (org.thoughtcrime.securesms.MainFragment)2 BadgeImageView (org.thoughtcrime.securesms.badges.BadgeImageView)2 CantProcessSubscriptionPaymentBottomSheetDialogFragment (org.thoughtcrime.securesms.badges.self.expired.CantProcessSubscriptionPaymentBottomSheetDialogFragment)2 ExpiredBadgeBottomSheetDialogFragment (org.thoughtcrime.securesms.badges.self.expired.ExpiredBadgeBottomSheetDialogFragment)2 UnreadPaymentsView (org.thoughtcrime.securesms.components.UnreadPaymentsView)2 ReminderView (org.thoughtcrime.securesms.components.reminder.ReminderView)2 NotificationProfileSelectionFragment (org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment)2 VoiceNotePlayerView (org.thoughtcrime.securesms.components.voice.VoiceNotePlayerView)2 ConversationFragment (org.thoughtcrime.securesms.conversation.ConversationFragment)2