Improve Call Notification UX when things don't go as planned.

fork-5.53.8
Cody Henthorne 2021-03-31 13:45:28 -04:00 zatwierdzone przez Alex Hart
rodzic b053fbc4a7
commit d8dead82b6
15 zmienionych plików z 442 dodań i 27 usunięć

Wyświetl plik

@ -67,6 +67,7 @@ public interface BindableConversationItem extends Unbindable {
void onSafetyNumberLearnMoreClicked(@NonNull Recipient recipient);
void onJoinGroupCallClicked();
void onInviteFriendsToGroupClicked(@NonNull GroupId.V2 groupId);
void onEnableCallNotificationsClicked();
/** @return true if handled, false if you want to let the normal url handling continue */
boolean onUrlClicked(@NonNull String url);

Wyświetl plik

@ -88,6 +88,7 @@ import org.thoughtcrime.securesms.contactshare.SharedContactDetailsActivity;
import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener;
import org.thoughtcrime.securesms.conversation.ConversationAdapter.StickyHeaderViewHolder;
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessageDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
@ -1558,6 +1559,23 @@ public class ConversationFragment extends LoggingFragment {
public void onInviteFriendsToGroupClicked(@NonNull GroupId.V2 groupId) {
GroupLinkInviteFriendsBottomSheetDialogFragment.show(requireActivity().getSupportFragmentManager(), groupId);
}
@Override
public void onEnableCallNotificationsClicked() {
EnableCallNotificationSettingsDialog.fixAutomatically(requireContext());
if (EnableCallNotificationSettingsDialog.shouldShow(requireContext())) {
EnableCallNotificationSettingsDialog.show(getChildFragmentManager());
} else {
refreshList();
}
}
}
public void refreshList() {
ConversationAdapter listAdapter = getListAdapter();
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
}
@Override

Wyświetl plik

@ -23,6 +23,7 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.BindableConversationItem;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.VerifyIdentityActivity;
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil;
import org.thoughtcrime.securesms.database.model.LiveUpdateMessage;
@ -302,6 +303,14 @@ public final class ConversationUpdateItem extends FrameLayout
eventListener.onInviteFriendsToGroupClicked(conversationRecipient.requireGroupId().requireV2());
}
});
} else if ((conversationMessage.getMessageRecord().isMissedAudioCall() || conversationMessage.getMessageRecord().isMissedVideoCall()) && EnableCallNotificationSettingsDialog.shouldShow(getContext())) {
actionButton.setVisibility(VISIBLE);
actionButton.setText(R.string.ConversationUpdateItem_enable_call_notifications);
actionButton.setOnClickListener(v -> {
if (eventListener != null) {
eventListener.onEnableCallNotificationsClicked();
}
});
} else {
actionButton.setVisibility(GONE);
actionButton.setOnClickListener(null);

Wyświetl plik

@ -0,0 +1,233 @@
package org.thoughtcrime.securesms.conversation.ui.error;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.conversation.ConversationFragment;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.util.DeviceProperties;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
* Provide basic steps to fix potential call notification issues based on what we can detect on the system
* and app settings.
*/
@TargetApi(26)
public final class EnableCallNotificationSettingsDialog extends DialogFragment {
private static final String TAG = Log.tag(EnableCallNotificationSettingsDialog.class);
private static final String FRAGMENT_TAG = "MissedCallCheckSettingsDialog";
private static final int NOTIFICATIONS_DISABLED = 1 << 1;
private static final int CALL_NOTIFICATIONS_DISABLED = 1 << 2;
private static final int CALL_CHANNEL_INVALID = 1 << 4;
private static final int BACKGROUND_RESTRICTED = 1 << 8;
private View view;
public static boolean shouldShow(@NonNull Context context) {
return getCallNotificationSettingsBitmask(context) != 0;
}
public static void fixAutomatically(@NonNull Context context) {
if (areCallNotificationsDisabled(context)) {
TextSecurePreferences.setCallNotificationsEnabled(context, true);
Toast.makeText(context, R.string.EnableCallNotificationSettingsDialog__call_notifications_enabled, Toast.LENGTH_SHORT).show();
}
}
public static void show(@NonNull FragmentManager fragmentManager) {
if (fragmentManager.findFragmentByTag(FRAGMENT_TAG) != null) {
Log.i(TAG, "Dialog already being shown");
return;
}
new EnableCallNotificationSettingsDialog().show(fragmentManager, FRAGMENT_TAG);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(requireContext(), R.style.Signal_ThemeOverlay_Dialog_Rounded);
Runnable action = null;
switch (getCallNotificationSettingsBitmask(requireContext())) {
case NOTIFICATIONS_DISABLED:
dialogBuilder.setTitle(R.string.EnableCallNotificationSettingsDialog__enable_call_notifications)
.setMessage(R.string.EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_turn_on_show_notifications)
.setPositiveButton(R.string.EnableCallNotificationSettingsDialog__settings, null);
action = this::showNotificationSettings;
break;
case CALL_CHANNEL_INVALID:
dialogBuilder.setTitle(R.string.EnableCallNotificationSettingsDialog__enable_call_notifications)
.setMessage(R.string.EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_turn_on_notifications)
.setPositiveButton(R.string.EnableCallNotificationSettingsDialog__settings, null);
action = this::showNotificationChannelSettings;
break;
case BACKGROUND_RESTRICTED:
dialogBuilder.setTitle(R.string.EnableCallNotificationSettingsDialog__enable_background_activity)
.setMessage(R.string.EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_enable_background_activity_in_battery_settings)
.setPositiveButton(R.string.EnableCallNotificationSettingsDialog__settings, null);
action = this::showAppSettings;
break;
default:
dialogBuilder.setTitle(R.string.EnableCallNotificationSettingsDialog__enable_call_notifications)
.setView(createView())
.setPositiveButton(android.R.string.ok, null);
break;
}
dialogBuilder.setNegativeButton(android.R.string.cancel, null);
AlertDialog dialog = dialogBuilder.create();
if (action != null) {
final Runnable localAction = action;
dialog.setOnShowListener(d -> dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> localAction.run()));
}
return dialog;
}
@Override
public void onResume() {
super.onResume();
if (getCallNotificationSettingsBitmask(requireContext()) == 0) {
dismissAllowingStateLoss();
} else if (view != null) {
bind(view);
}
}
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
super.onDismiss(dialog);
if (getParentFragment() instanceof ConversationFragment) {
((ConversationFragment) getParentFragment()).refreshList();
}
}
@SuppressLint("InflateParams")
private @NonNull View createView() {
view = LayoutInflater.from(getContext()).inflate(R.layout.enable_call_notification_settings_dialog_fragment, null, false);
bind(view);
return view;
}
private void bind(@NonNull View view) {
TextView allConfigured = view.findViewById(R.id.enable_call_notification_settings_dialog_system_all_configured);
AppCompatImageView systemSettingIndicator = view.findViewById(R.id.enable_call_notification_settings_dialog_system_setting_indicator);
TextView systemSettingText = view.findViewById(R.id.enable_call_notification_settings_dialog_system_setting_text);
AppCompatImageView channelSettingIndicator = view.findViewById(R.id.enable_call_notification_settings_dialog_channel_setting_indicator);
TextView channelSettingText = view.findViewById(R.id.enable_call_notification_settings_dialog_channel_setting_text);
AppCompatImageView backgroundRestrictedIndicator = view.findViewById(R.id.enable_call_notification_settings_dialog_background_restricted_indicator);
TextView backgroundRestrictedText = view.findViewById(R.id.enable_call_notification_settings_dialog_background_restricted_text);
if (areNotificationsDisabled(requireContext())) {
systemSettingIndicator.setVisibility(View.VISIBLE);
systemSettingText.setVisibility(View.VISIBLE);
systemSettingText.setOnClickListener(v -> showNotificationSettings());
} else {
systemSettingIndicator.setVisibility(View.GONE);
systemSettingText.setVisibility(View.GONE);
systemSettingText.setOnClickListener(null);
}
if (isCallChannelInvalid(requireContext())) {
channelSettingIndicator.setVisibility(View.VISIBLE);
channelSettingText.setVisibility(View.VISIBLE);
channelSettingText.setOnClickListener(v -> showNotificationChannelSettings());
} else {
channelSettingIndicator.setVisibility(View.GONE);
channelSettingText.setVisibility(View.GONE);
channelSettingText.setOnClickListener(null);
}
if (isBackgroundRestricted(requireContext())) {
backgroundRestrictedIndicator.setVisibility(View.VISIBLE);
backgroundRestrictedText.setVisibility(View.VISIBLE);
backgroundRestrictedText.setOnClickListener(v -> showAppSettings());
} else {
backgroundRestrictedIndicator.setVisibility(View.GONE);
backgroundRestrictedText.setVisibility(View.GONE);
backgroundRestrictedText.setOnClickListener(null);
}
allConfigured.setVisibility(shouldShow(requireContext()) ? View.GONE : View.VISIBLE);
}
private void showNotificationSettings() {
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().getPackageName());
startActivity(intent);
}
private void showNotificationChannelSettings() {
NotificationChannels.openChannelSettings(requireContext(), NotificationChannels.CALLS);
}
private void showAppSettings() {
Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", requireContext().getPackageName(), null));
startActivity(intent);
}
private static boolean areNotificationsDisabled(@NonNull Context context) {
return !NotificationChannels.areNotificationsEnabled(context);
}
private static boolean areCallNotificationsDisabled(Context context) {
return !TextSecurePreferences.isCallNotificationsEnabled(context);
}
private static boolean isCallChannelInvalid(Context context) {
return !NotificationChannels.isCallsChannelValid(context);
}
private static boolean isBackgroundRestricted(Context context) {
return Build.VERSION.SDK_INT >= 28 && DeviceProperties.isBackgroundRestricted(context);
}
private static int getCallNotificationSettingsBitmask(@NonNull Context context) {
int bitmask = 0;
if (areNotificationsDisabled(context)) {
bitmask |= NOTIFICATIONS_DISABLED;
}
if (areCallNotificationsDisabled(context)) {
bitmask |= CALL_NOTIFICATIONS_DISABLED;
}
if (isCallChannelInvalid(context)) {
bitmask |= CALL_CHANNEL_INVALID;
}
if (isBackgroundRestricted(context)) {
bitmask |= BACKGROUND_RESTRICTED;
}
return bitmask;
}
}

Wyświetl plik

@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
@ -13,6 +14,7 @@ import android.os.AsyncTask;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -219,10 +221,15 @@ public class NotificationChannels {
return;
}
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
context.startActivity(intent);
try {
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Channel settings activity not found", e);
Toast.makeText(context, R.string.NotificationChannels__no_activity_available_to_open_notification_channel_settings, Toast.LENGTH_SHORT).show();
}
}
/**
@ -413,6 +420,16 @@ public class NotificationChannels {
return group != null && !group.isBlocked();
}
public static boolean isCallsChannelValid(@NonNull Context context) {
if (!supported()) {
return true;
}
NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
NotificationChannel channel = notificationManager.getNotificationChannel(CALLS);
return channel != null && channel.getImportance() == NotificationManager.IMPORTANCE_HIGH;
}
/**
* Whether or not notifications for the entire app are enabled.

Wyświetl plik

@ -31,10 +31,8 @@ import org.signal.ringrtc.HttpHeader;
import org.signal.ringrtc.Remote;
import org.signal.storageservice.protos.groups.GroupExternalCredential;
import org.signal.zkgroup.VerificationFailedException;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.WebRtcCallActivity;
import org.thoughtcrime.securesms.components.sensors.DeviceOrientationMonitor;
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
@ -57,6 +55,7 @@ import org.thoughtcrime.securesms.service.webrtc.IdleActionProcessor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcInteractor;
import org.thoughtcrime.securesms.service.webrtc.WebRtcUtil;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.util.BubbleUtil;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
@ -90,10 +89,14 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static org.thoughtcrime.securesms.events.WebRtcViewModel.GroupCallState.IDLE;
import static org.thoughtcrime.securesms.events.WebRtcViewModel.State.CALL_INCOMING;
public class WebRtcCallService extends Service implements CallManager.Observer,
BluetoothStateManager.BluetoothStateListener,
CameraEventListener,
GroupCall.Observer
BluetoothStateManager.BluetoothStateListener,
CameraEventListener,
GroupCall.Observer,
AppForegroundObserver.Listener
{
private static final String TAG = Log.tag(WebRtcCallService.class);
@ -276,6 +279,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
new SignalAudioManager(this),
bluetoothStateManager,
this,
this,
this);
return true;
}
@ -479,15 +483,16 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
return listenableFutureTask;
}
public void startCallCardActivityIfPossible() {
public boolean startCallCardActivityIfPossible() {
if (Build.VERSION.SDK_INT >= 29 && !ApplicationDependencies.getAppForegroundObserver().isForegrounded()) {
return;
return false;
}
Intent activityIntent = new Intent();
activityIntent.setClass(this, WebRtcCallActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityIntent);
return true;
}
private static @NonNull OfferMessage.Type getOfferTypeFromCallMediaType(@NonNull CallManager.CallMediaType mediaType) {
@ -516,6 +521,18 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
return null;
}
@Override
public void onForeground() {
WebRtcViewModel.State callState = serviceState.getCallInfoState().getCallState();
if (callState == CALL_INCOMING && serviceState.getCallInfoState().getGroupCallState() == IDLE) {
startCallCardActivityIfPossible();
}
ApplicationDependencies.getAppForegroundObserver().removeListener(this);
}
@Override
public void onBackground() { }
private static class WiredHeadsetStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {

Wyświetl plik

@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallManager;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.ringrtc.CallState;
import org.thoughtcrime.securesms.ringrtc.Camera;
@ -37,6 +38,7 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer();
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.startAudioCommunication(activePeer.getState() == CallState.REMOTE_RINGING);
webRtcInteractor.setWantsBluetoothConnection(true);

Wyświetl plik

@ -12,6 +12,7 @@ import org.signal.ringrtc.CallId;
import org.thoughtcrime.securesms.components.webrtc.OrientationAwareVideoSink;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.notifications.DoNotDisturbUtil;
@ -157,7 +158,11 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
boolean shouldDisturbUserWithCall = DoNotDisturbUtil.shouldDisturbUserWithCall(context.getApplicationContext(), recipient);
if (shouldDisturbUserWithCall) {
webRtcInteractor.startWebRtcCallActivityIfPossible();
boolean started = webRtcInteractor.startWebRtcCallActivityIfPossible();
if (!started) {
Log.i(TAG, "Unable to start call activity due to OS version or not being in the foreground");
ApplicationDependencies.getAppForegroundObserver().addListener(webRtcInteractor.getForegroundListener());
}
}
webRtcInteractor.initializeAudioForCall();

Wyświetl plik

@ -13,6 +13,7 @@ import org.signal.ringrtc.CallId;
import org.signal.ringrtc.GroupCall;
import org.thoughtcrime.securesms.components.sensors.Orientation;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.recipients.RecipientId;
@ -723,6 +724,8 @@ public abstract class WebRtcActionProcessor {
return currentState;
}
ApplicationDependencies.getAppForegroundObserver().removeListener(webRtcInteractor.getForegroundListener());
webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
webRtcInteractor.stopForegroundService();
boolean playDisconnectSound = (activePeer.getState() == CallState.DIALING) ||

Wyświetl plik

@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.ringrtc.CameraEventListener;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.service.WebRtcCallService;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.webrtc.audio.BluetoothStateManager;
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger;
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
@ -29,13 +30,14 @@ import java.util.UUID;
*/
public class WebRtcInteractor {
@NonNull private final WebRtcCallService webRtcCallService;
@NonNull private final CallManager callManager;
@NonNull private final LockManager lockManager;
@NonNull private final SignalAudioManager audioManager;
@NonNull private final BluetoothStateManager bluetoothStateManager;
@NonNull private final CameraEventListener cameraEventListener;
@NonNull private final GroupCall.Observer groupCallObserver;
@NonNull private final WebRtcCallService webRtcCallService;
@NonNull private final CallManager callManager;
@NonNull private final LockManager lockManager;
@NonNull private final SignalAudioManager audioManager;
@NonNull private final BluetoothStateManager bluetoothStateManager;
@NonNull private final CameraEventListener cameraEventListener;
@NonNull private final GroupCall.Observer groupCallObserver;
@NonNull private final AppForegroundObserver.Listener foregroundListener;
public WebRtcInteractor(@NonNull WebRtcCallService webRtcCallService,
@NonNull CallManager callManager,
@ -43,7 +45,8 @@ public class WebRtcInteractor {
@NonNull SignalAudioManager audioManager,
@NonNull BluetoothStateManager bluetoothStateManager,
@NonNull CameraEventListener cameraEventListener,
@NonNull GroupCall.Observer groupCallObserver)
@NonNull GroupCall.Observer groupCallObserver,
@NonNull AppForegroundObserver.Listener foregroundListener)
{
this.webRtcCallService = webRtcCallService;
this.callManager = callManager;
@ -52,6 +55,7 @@ public class WebRtcInteractor {
this.bluetoothStateManager = bluetoothStateManager;
this.cameraEventListener = cameraEventListener;
this.groupCallObserver = groupCallObserver;
this.foregroundListener = foregroundListener;
}
@NonNull CameraEventListener getCameraEventListener() {
@ -70,6 +74,10 @@ public class WebRtcInteractor {
return groupCallObserver;
}
@NonNull AppForegroundObserver.Listener getForegroundListener() {
return foregroundListener;
}
void setWantsBluetoothConnection(boolean enabled) {
bluetoothStateManager.setWantsConnection(enabled);
}
@ -118,8 +126,8 @@ public class WebRtcInteractor {
webRtcCallService.insertMissedCall(remotePeer, signal, timestamp, isVideoOffer);
}
void startWebRtcCallActivityIfPossible() {
webRtcCallService.startCallCardActivityIfPossible();
boolean startWebRtcCallActivityIfPossible() {
return webRtcCallService.startCallCardActivityIfPossible();
}
void registerPowerButtonReceiver() {

Wyświetl plik

@ -987,6 +987,10 @@ public class TextSecurePreferences {
return getBooleanPreference(context, NOTIFICATION_PREF, true);
}
public static void setCallNotificationsEnabled(Context context, boolean enabled) {
setBooleanPreference(context, CALL_NOTIFICATIONS_PREF, enabled);
}
public static boolean isCallNotificationsEnabled(Context context) {
return getBooleanPreference(context, CALL_NOTIFICATIONS_PREF, true);
}

Wyświetl plik

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/signal_icon_tint_primary"
android:fillColor="#000000"
android:pathData="M9.172,18.5l-6.188,-6.187l1.061,-1.061l5.127,5.127l10.783,-10.784l1.061,1.061l-11.844,11.844z"/>
</vector>

Wyświetl plik

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/core_white"
android:fillColor="#ffffff"
android:pathData="M12,2.5A9.5,9.5 0,1 1,2.5 12,9.511 9.511,0 0,1 12,2.5M12,1A11,11 0,1 0,23 12,11 11,0 0,0 12,1ZM12,8.5A1.5,1.5 0,0 0,13.5 7a1.5,1.5 0,1 0,-2.56 1.06A1.435,1.435 0,0 0,12 8.5ZM13,16.5L13,10L9.5,10v1.5h2v5L9,16.5L9,18h6L15,16.5Z" />
</vector>

Wyświetl plik

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.gridlayout.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="?attr/dialogPreferredPadding"
app:alignmentMode="alignBounds"
app:columnCount="2">
<TextView
android:id="@+id/enable_call_notification_settings_dialog_system_all_configured"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/EnableCallNotificationSettingsDialog__everything_looks_good_now"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:visibility="gone"
app:layout_columnSpan="2" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/enable_call_notification_settings_dialog_system_setting_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_gravity="center_vertical"
app:srcCompat="@drawable/ic_info_white_24"
app:tint="@color/signal_alert_primary" />
<TextView
android:id="@+id/enable_call_notification_settings_dialog_system_setting_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:text="@string/EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_turn_on_show_notifications"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Signal.Body2"
app:layout_columnWeight="1"
app:layout_gravity="center_vertical" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/enable_call_notification_settings_dialog_channel_setting_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_gravity="center_vertical"
app:srcCompat="@drawable/ic_info_white_24"
app:tint="@color/signal_alert_primary" />
<TextView
android:id="@+id/enable_call_notification_settings_dialog_channel_setting_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:text="@string/EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_turn_on_notifications"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Signal.Body2"
app:layout_columnWeight="1"
app:layout_gravity="center_vertical" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/enable_call_notification_settings_dialog_background_restricted_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_gravity="center_vertical"
app:srcCompat="@drawable/ic_info_white_24"
app:tint="@color/signal_alert_primary" />
<TextView
android:id="@+id/enable_call_notification_settings_dialog_background_restricted_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:text="@string/EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_enable_background_activity_in_battery_settings"
android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Signal.Body2"
app:layout_columnWeight="1"
app:layout_gravity="center_vertical" />
</androidx.gridlayout.widget.GridLayout>

Wyświetl plik

@ -640,7 +640,7 @@
<item quantity="one">Error revoking invite</item>
<item quantity="other">Error revoking invites</item>
</plurals>
<!-- RequestingMembersFragment -->
<string name="RequestingMembersFragment_pending_member_requests">Pending member requests</string>
<string name="RequestingMembersFragment_no_member_requests_to_show">No member requests to show.</string>
@ -799,7 +799,7 @@
<string name="CustomNotificationsDialogFragment__enabled">Enabled</string>
<string name="CustomNotificationsDialogFragment__disabled">Disabled</string>
<string name="CustomNotificationsDialogFragment__default">Default</string>
<!-- ShareableGroupLinkDialogFragment -->
<string name="ShareableGroupLinkDialogFragment__shareable_group_link">Shareable group link</string>
<string name="ShareableGroupLinkDialogFragment__manage_and_share">Manage &amp; share</string>
@ -1722,7 +1722,7 @@
<string name="NotificationChannel_group_messages">Messages</string>
<string name="NotificationChannel_missing_display_name">Unknown</string>
<string name="NotificationChannel_voice_notes">Voice Notes</string>
<string name="NotificationChannels__no_activity_available_to_open_notification_channel_settings">No activity available to open notification channel settings.</string>
<!-- ProfileEditNameFragment -->
<!-- QuickResponseService -->
@ -1871,6 +1871,7 @@
<string name="ConversationUpdateItem_return_to_call">Return to call</string>
<string name="ConversationUpdateItem_call_is_full">Call is full</string>
<string name="ConversationUpdateItem_invite_friends">Invite friends</string>
<string name="ConversationUpdateItem_enable_call_notifications">Enable Call Notifications</string>
<!-- audio_view -->
<string name="audio_view__play_pause_accessibility_description">Play … Pause</string>
@ -1899,6 +1900,19 @@
<string name="safety_number_change_dialog__view">View</string>
<string name="safety_number_change_dialog__previous_verified">Previous verified</string>
<!-- EnableCallNotificationSettingsDialog__call_notifications_checklist -->
<string name="EnableCallNotificationSettingsDialog__call_notifications_enabled">Call notifications enabled.</string>
<string name="EnableCallNotificationSettingsDialog__enable_call_notifications">Enable call notifications</string>
<string name="EnableCallNotificationSettingsDialog__enable_background_activity">Enable background activity</string>
<string name="EnableCallNotificationSettingsDialog__everything_looks_good_now">Everything looks good now!</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_turn_on_show_notifications">To receive call notifications, tap here and turn on \"Show notifications.\"</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_turn_on_notifications">To receive call notifications, tap here and turn on notifications and make sure Sound and Pop-up are enabled.</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_here_and_enable_background_activity_in_battery_settings">To receive call notifications, tap here and enable background activity in \"Battery\" settings. </string>
<string name="EnableCallNotificationSettingsDialog__settings">Settings</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_turn_on_show_notifications">To receive call notifications, tap Settings and turn on \"Show notifications.\"</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_turn_on_notifications">To receive call notifications, tap Settings and turn on notifications and make sure Sound and Pop-up are enabled.</string>
<string name="EnableCallNotificationSettingsDialog__to_receive_call_notifications_tap_settings_and_enable_background_activity_in_battery_settings">To receive call notifications, tap Settings and enable background activity in \"Battery\" settings.</string>
<!-- country_selection_fragment -->
<string name="country_selection_fragment__loading_countries">Loading countries…</string>
<string name="country_selection_fragment__search">Search</string>