Add support for MISSED_VIDEO_CALL type.

This commit is contained in:
Alex Hart 2020-11-04 10:42:45 -04:00 committed by Alan Evans
parent f796447815
commit 31e137cf6d
14 changed files with 57 additions and 41 deletions

View file

@ -450,8 +450,10 @@ public final class ConversationListItem extends RelativeLayout
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called));
} else if (SmsDatabase.Types.isIncomingCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called_you));
} else if (SmsDatabase.Types.isMissedCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_missed_call));
} else if (SmsDatabase.Types.isMissedAudioCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_missed_audio_call));
} else if (SmsDatabase.Types.isMissedVideoCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_missed_video_call));
} else if (SmsDatabase.Types.isJoinedType(thread.getType())) {
return emphasisAdded(recipientToStringAsync(thread.getRecipient().getId(), r -> new SpannableString(context.getString(R.string.ThreadRecord_s_is_on_signal, r.getDisplayName(context)))));
} else if (SmsDatabase.Types.isExpirationTimerUpdate(thread.getType())) {

View file

@ -108,7 +108,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract void markUnidentified(long messageId, boolean unidentified);
public abstract void markAsSending(long messageId);
public abstract void markAsRemoteDelete(long messageId);
public abstract void markAsMissedCall(long id);
public abstract void markAsMissedCall(long id, boolean isVideoOffer);
public abstract void markAsNotified(long id);
public abstract void markSmsStatus(long id, int status);
public abstract void markDownloadState(long messageId, long state);
@ -126,7 +126,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract @NonNull Pair<Long, Long> insertReceivedCall(@NonNull RecipientId address);
public abstract @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address);
public abstract @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp);
public abstract @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp, boolean isVideoOffer);
public abstract Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long type);
public abstract Optional<InsertResult> insertMessageInbox(IncomingTextMessage message);

View file

@ -365,7 +365,7 @@ public class MmsDatabase extends MessageDatabase {
}
@Override
public void markAsMissedCall(long id) {
public void markAsMissedCall(long id, boolean isVideoOffer) {
throw new UnsupportedOperationException();
}
@ -390,7 +390,7 @@ public class MmsDatabase extends MessageDatabase {
}
@Override
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp) {
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp, boolean isVideoOffer) {
throw new UnsupportedOperationException();
}

View file

@ -34,11 +34,12 @@ public interface MmsSmsColumns {
protected static final long INCOMING_CALL_TYPE = 1;
protected static final long OUTGOING_CALL_TYPE = 2;
protected static final long MISSED_CALL_TYPE = 3;
protected static final long MISSED_AUDIO_CALL_TYPE = 3;
protected static final long JOINED_TYPE = 4;
protected static final long UNSUPPORTED_MESSAGE_TYPE = 5;
protected static final long INVALID_MESSAGE_TYPE = 6;
protected static final long PROFILE_CHANGE_TYPE = 7;
protected static final long MISSED_VIDEO_CALL_TYPE = 8;
protected static final long BASE_INBOX_TYPE = 20;
protected static final long BASE_OUTBOX_TYPE = 21;
@ -204,7 +205,7 @@ public interface MmsSmsColumns {
}
public static boolean isCallLog(long type) {
return type == INCOMING_CALL_TYPE || type == OUTGOING_CALL_TYPE || type == MISSED_CALL_TYPE;
return type == INCOMING_CALL_TYPE || type == OUTGOING_CALL_TYPE || type == MISSED_AUDIO_CALL_TYPE || type == MISSED_VIDEO_CALL_TYPE;
}
public static boolean isExpirationTimerUpdate(long type) {
@ -219,8 +220,12 @@ public interface MmsSmsColumns {
return type == OUTGOING_CALL_TYPE;
}
public static boolean isMissedCall(long type) {
return type == MISSED_CALL_TYPE;
public static boolean isMissedAudioCall(long type) {
return type == MISSED_AUDIO_CALL_TYPE;
}
public static boolean isMissedVideoCall(long type) {
return type == MISSED_VIDEO_CALL_TYPE;
}
public static boolean isGroupUpdate(long type) {

View file

@ -364,8 +364,8 @@ public class SmsDatabase extends MessageDatabase {
}
@Override
public void markAsMissedCall(long id) {
updateTypeBitmask(id, Types.TOTAL_MASK, Types.MISSED_CALL_TYPE);
public void markAsMissedCall(long id, boolean isVideoOffer) {
updateTypeBitmask(id, Types.TOTAL_MASK, isVideoOffer ? Types.MISSED_VIDEO_CALL_TYPE : Types.MISSED_AUDIO_CALL_TYPE);
}
@Override
@ -633,12 +633,13 @@ public class SmsDatabase extends MessageDatabase {
@Override
public boolean hasReceivedAnyCallsSince(long threadId, long timestamp) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String[] projection = new String[]{SmsDatabase.TYPE};
String selection = THREAD_ID + " = ? AND " + DATE_RECEIVED + " > ? AND (" + TYPE + " = ? OR " + TYPE + " = ?)";
String[] selectionArgs = new String[]{String.valueOf(threadId),
String.valueOf(timestamp),
String.valueOf(Types.INCOMING_CALL_TYPE),
String.valueOf(Types.MISSED_CALL_TYPE)};
String[] projection = SqlUtil.buildArgs(SmsDatabase.TYPE);
String selection = THREAD_ID + " = ? AND " + DATE_RECEIVED + " > ? AND (" + TYPE + " = ? OR " + TYPE + " = ? OR " + TYPE + " =?)";
String[] selectionArgs = SqlUtil.buildArgs(threadId,
timestamp,
Types.INCOMING_CALL_TYPE,
Types.MISSED_AUDIO_CALL_TYPE,
Types.MISSED_VIDEO_CALL_TYPE);
try (Cursor cursor = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, null)) {
return cursor != null && cursor.moveToFirst();
@ -656,8 +657,8 @@ public class SmsDatabase extends MessageDatabase {
}
@Override
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp) {
return insertCallLog(address, Types.MISSED_CALL_TYPE, true, timestamp);
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp, boolean isVideoCall) {
return insertCallLog(address, isVideoCall ? Types.MISSED_VIDEO_CALL_TYPE : Types.MISSED_AUDIO_CALL_TYPE, true, timestamp);
}
private @NonNull Pair<Long, Long> insertCallLog(@NonNull RecipientId recipientId, long type, boolean unread, long timestamp) {

View file

@ -148,8 +148,12 @@ public abstract class DisplayRecord {
return SmsDatabase.Types.isOutgoingCall(type);
}
public boolean isMissedCall() {
return SmsDatabase.Types.isMissedCall(type);
public final boolean isMissedAudioCall() {
return SmsDatabase.Types.isMissedAudioCall(type);
}
public final boolean isMissedVideoCall() {
return SmsDatabase.Types.isMissedVideoCall(type);
}
public boolean isVerificationStatusChange() {

View file

@ -144,8 +144,10 @@ public abstract class MessageRecord extends DisplayRecord {
return fromRecipient(getIndividualRecipient(), r -> context.getString(R.string.MessageRecord_s_called_you_date, r.getDisplayName(context), getCallDateString(context)), R.drawable.ic_update_audio_call_incoming_light_16, R.drawable.ic_update_audio_call_incoming_dark_16);
} else if (isOutgoingCall()) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_called_date, getCallDateString(context)), R.drawable.ic_update_audio_call_outgoing_light_16, R.drawable.ic_update_audio_call_outgoing_dark_16);
} else if (isMissedCall()) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_missed_call_date, getCallDateString(context)), R.drawable.ic_update_audio_call_missed_light_16, R.drawable.ic_update_audio_call_missed_dark_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
} else if (isMissedAudioCall()) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_missed_audio_call_date, getCallDateString(context)), R.drawable.ic_update_audio_call_missed_light_16, R.drawable.ic_update_audio_call_missed_dark_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
} else if (isMissedVideoCall()) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_missed_video_call_date, getCallDateString(context)), R.drawable.ic_update_video_call_missed_light_16, R.drawable.ic_update_video_call_missed_dark_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
} else if (isJoined()) {
return staticUpdateDescription(context.getString(R.string.MessageRecord_s_joined_signal, getIndividualRecipient().getDisplayName(context)), R.drawable.ic_update_group_add_light_16, R.drawable.ic_update_group_add_dark_16);
} else if (isExpirationTimerUpdate()) {

View file

@ -506,7 +506,7 @@ public final class PushProcessMessageJob extends BaseJob {
if (smsMessageId.isPresent()) {
MessageDatabase database = DatabaseFactory.getSmsDatabase(context);
database.markAsMissedCall(smsMessageId.get());
database.markAsMissedCall(smsMessageId.get(), message.getType() == OfferMessage.Type.VIDEO_CALL);
} else {
Intent intent = new Intent(context, WebRtcCallService.class);
Recipient recipient = Recipient.externalHighTrustPush(context, content.getSender());
@ -581,7 +581,7 @@ public final class PushProcessMessageJob extends BaseJob {
{
log(TAG, String.valueOf(content), "handleCallHangupMessage");
if (smsMessageId.isPresent()) {
DatabaseFactory.getSmsDatabase(context).markAsMissedCall(smsMessageId.get());
DatabaseFactory.getSmsDatabase(context).markAsMissedCall(smsMessageId.get(), false);
} else {
Intent intent = new Intent(context, WebRtcCallService.class);
RemotePeer remotePeer = new RemotePeer(Recipient.externalHighTrustPush(context, content.getSender()).getId());

View file

@ -328,8 +328,8 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
}
}
public void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp) {
Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(remotePeer.getId(), timestamp);
public void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp, boolean isVideoOffer) {
Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(remotePeer.getId(), timestamp, isVideoOffer);
ApplicationDependencies.getMessageNotifier().updateNotification(this, messageAndThreadId.second(), signal);
}

View file

@ -178,7 +178,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
webRtcInteractor.stopForegroundService();
}
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
return terminate(currentState, remotePeer);
}
@ -206,7 +206,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
}
if (incomingBeforeAccept) {
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
}
} else if (action.equals(ACTION_ENDED_REMOTE_BUSY) && remotePeerIsActive) {
activePeer.receivedBusy();
@ -215,7 +215,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
ringer.start(OutgoingRinger.Type.BUSY);
Util.runOnMainDelayed(ringer::stop, BUSY_TONE_LENGTH);
} else if (action.equals(ACTION_ENDED_REMOTE_GLARE) && incomingBeforeAccept) {
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
}
currentState = currentState.builder()
@ -242,7 +242,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
}
if (remotePeer.getState() == CallState.ANSWERING || remotePeer.getState() == CallState.LOCAL_RINGING) {
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
}
return terminate(currentState, remotePeer);
@ -273,7 +273,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
webRtcInteractor.sendMessage(currentState);
if (activePeer.getState() == CallState.ANSWERING || activePeer.getState() == CallState.LOCAL_RINGING) {
webRtcInteractor.insertMissedCall(activePeer, true, activePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(activePeer, true, activePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
}
return terminate(currentState, activePeer);

View file

@ -136,7 +136,7 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
try {
webRtcInteractor.getCallManager().hangup();
DatabaseFactory.getSmsDatabase(context).insertMissedCall(activePeer.getId(), System.currentTimeMillis());
DatabaseFactory.getSmsDatabase(context).insertMissedCall(activePeer.getId(), System.currentTimeMillis(), currentState.getCallSetupState().isRemoteVideoOffer());
return terminate(currentState, activePeer);
} catch (CallException e) {
return callFailure(currentState, "hangup() failed: ", e);

View file

@ -284,14 +284,14 @@ public abstract class WebRtcActionProcessor {
if (TelephonyUtil.isAnyPstnLineBusy(context)) {
Log.i(tag, "PSTN line is busy.");
currentState = currentState.getActionProcessor().handleSendBusy(currentState, callMetadata, true);
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), true, receivedOfferMetadata.getServerReceivedTimestamp());
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), true, 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(), true, receivedOfferMetadata.getServerReceivedTimestamp());
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), true, receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
return currentState;
}
@ -338,7 +338,7 @@ public abstract class WebRtcActionProcessor {
{
Log.i(tag, "handleReceivedOfferExpired(): call_id: " + remotePeer.getCallId());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
webRtcInteractor.insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState().isRemoteVideoOffer());
return terminate(currentState, remotePeer);
}

View file

@ -85,8 +85,8 @@ public class WebRtcInteractor {
webRtcCallService.stopForeground(true);
}
void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp) {
webRtcCallService.insertMissedCall(remotePeer, signal, timestamp);
void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp, boolean isVideoOffer) {
webRtcCallService.insertMissedCall(remotePeer, signal, timestamp, isVideoOffer);
}
void startWebRtcCallActivityIfPossible() {

View file

@ -940,7 +940,8 @@
<string name="MessageRecord_you_updated_group">You updated the group.</string>
<string name="MessageRecord_the_group_was_updated">The group was updated.</string>
<string name="MessageRecord_you_called_date">You called · %1$s</string>
<string name="MessageRecord_missed_call_date">Missed call · %1$s</string>
<string name="MessageRecord_missed_audio_call_date">Missed audio call · %1$s</string>
<string name="MessageRecord_missed_video_call_date">Missed video call · %1$s</string>
<string name="MessageRecord_s_updated_group">%s updated the group.</string>
<string name="MessageRecord_s_called_you_date">%1$s called you · %2$s</string>
<string name="MessageRecord_called_s">Called %s</string>
@ -1431,7 +1432,8 @@
<string name="ThreadRecord_draft">Draft:</string>
<string name="ThreadRecord_called">You called</string>
<string name="ThreadRecord_called_you">Called you</string>
<string name="ThreadRecord_missed_call">Missed call</string>
<string name="ThreadRecord_missed_audio_call">Missed audio call</string>
<string name="ThreadRecord_missed_video_call">Missed video call</string>
<string name="ThreadRecord_media_message">Media message</string>
<string name="ThreadRecord_sticker">Sticker</string>
<string name="ThreadRecord_view_once_photo">View-once photo</string>