Skip to content

Commit

Permalink
Disappearing messages for calls
Browse files Browse the repository at this point in the history
  • Loading branch information
valldrac committed Oct 18, 2020
1 parent fe806cb commit b2955d6
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void presentTimer(@NonNull final MessageRecord messageRecord) {
messageRecord.getExpiresIn());
this.timerView.startAnimation();

if (messageRecord.getExpireStarted() + messageRecord.getExpiresIn() <= System.currentTimeMillis()) {
if (timerView.isExpired()) {
ApplicationContext.getInstance(getContext()).getExpiringMessageManager().checkSchedule();
}
} else if (!messageRecord.isOutgoing() && !messageRecord.isMediaPending()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ public void setPercentComplete(float percentage) {
setImageResource(frames[frame]);
}

public boolean isExpired() {
return startedAt + expiresIn <= System.currentTimeMillis();
}

public void startAnimation() {
synchronized (this) {
visible = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.thoughtcrime.securesms.conversation;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.AsyncTask;
import android.text.SpannableString;
import android.util.AttributeSet;
import android.view.View;
Expand All @@ -19,9 +21,12 @@
import androidx.lifecycle.Observer;
import androidx.lifecycle.Transformations;

import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BindableConversationItem;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.VerifyIdentityActivity;
import org.thoughtcrime.securesms.components.ExpirationTimerView;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
import org.thoughtcrime.securesms.database.model.LiveUpdateMessage;
import org.thoughtcrime.securesms.database.model.MessageRecord;
Expand Down Expand Up @@ -54,6 +59,7 @@ public final class ConversationUpdateItem extends LinearLayout
private TextView title;
private TextView body;
private TextView date;
private ExpirationTimerView timer;
private LiveRecipient sender;
private ConversationMessage conversationMessage;
private MessageRecord messageRecord;
Expand All @@ -79,6 +85,7 @@ public void onFinishInflate() {
this.title = findViewById(R.id.conversation_update_title);
this.body = findViewById(R.id.conversation_update_body);
this.date = findViewById(R.id.conversation_update_date);
this.timer = findViewById(R.id.conversation_update_expiration_timer);

this.setOnClickListener(new InternalClickListener(null));
}
Expand Down Expand Up @@ -192,6 +199,7 @@ else if (messageRecord.isIdentityVerified() ||
else setSelected(false);
}

@SuppressLint("StaticFieldLeak")
private void setCallRecord(MessageRecord messageRecord) {
if (messageRecord.isIncomingCall()) icon.setImageResource(R.drawable.ic_call_received_grey600_24dp);
else if (messageRecord.isOutgoingCall()) icon.setImageResource(R.drawable.ic_call_made_grey600_24dp);
Expand All @@ -201,6 +209,36 @@ private void setCallRecord(MessageRecord messageRecord) {

title.setVisibility(GONE);
date.setVisibility(View.VISIBLE);

if (messageRecord.getExpiresIn() > 0 && !messageRecord.isPending()) {
timer.setVisibility(View.VISIBLE);
timer.setPercentComplete(0);

if (messageRecord.getExpireStarted() > 0) {
timer.setExpirationTime(messageRecord.getExpireStarted(),
messageRecord.getExpiresIn());
timer.startAnimation();

if (timer.isExpired()) {
ApplicationContext.getInstance(getContext()).getExpiringMessageManager().checkSchedule();
}
} else if (!messageRecord.isOutgoing() && !messageRecord.isMediaPending()) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
long id = messageRecord.getId();
long expiresIn = messageRecord.getExpiresIn();

DatabaseFactory.getSmsDatabase(getContext()).markExpireStarted(id);

ApplicationContext.getInstance(getContext()).getExpiringMessageManager().scheduleDeletion(id, false, expiresIn);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
} else {
timer.setVisibility(View.GONE);
}
}

private void setTimerRecord(final MessageRecord messageRecord) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ public MessageDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
public abstract void addFailures(long messageId, List<NetworkFailure> failure);
public abstract void removeFailure(long messageId, NetworkFailure failure);

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> insertReceivedCall(@NonNull RecipientId address, long expiresIn);
public abstract @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address, long expiresIn);
public abstract @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long expiresIn, long timestamp);

public abstract Optional<InsertResult> insertMessageInbox(IncomingTextMessage message, long type);
public abstract Optional<InsertResult> insertMessageInbox(IncomingTextMessage message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,17 +379,17 @@ public Pair<Long, Long> updateBundleMessageBody(long messageId, String body) {
}

@Override
public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull RecipientId address) {
public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull RecipientId address, long expiresIn) {
throw new UnsupportedOperationException();
}

@Override
public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address) {
public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address, long expiresIn) {
throw new UnsupportedOperationException();
}

@Override
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long timestamp) {
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull RecipientId address, long expiresIn, long timestamp) {
throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,8 @@ private List<MarkedMessageInfo> setMessagesRead(String where, String[] arguments
cursor = database.query(TABLE_NAME, new String[] {ID, RECIPIENT_ID, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID}, where, arguments, null, null, null);

while (cursor != null && cursor.moveToNext()) {
if (Types.isSecureType(cursor.getLong(cursor.getColumnIndex(TYPE)))) {
long type = cursor.getLong(3);
if (Types.isSecureType(type) || Types.isCallLog(type)) {
long threadId = cursor.getLong(cursor.getColumnIndex(THREAD_ID));
RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndex(RECIPIENT_ID)));
long dateSent = cursor.getLong(cursor.getColumnIndex(DATE_SENT));
Expand Down Expand Up @@ -644,21 +645,21 @@ public boolean hasReceivedAnyCallsSince(long threadId, long timestamp) {
}

@Override
public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull RecipientId address) {
return insertCallLog(address, Types.INCOMING_CALL_TYPE, false, System.currentTimeMillis());
public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull RecipientId address, long expiresIn) {
return insertCallLog(address, Types.INCOMING_CALL_TYPE, expiresIn, false, System.currentTimeMillis());
}

@Override
public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address) {
return insertCallLog(address, Types.OUTGOING_CALL_TYPE, false, System.currentTimeMillis());
public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull RecipientId address, long expiresIn) {
return insertCallLog(address, Types.OUTGOING_CALL_TYPE, expiresIn, false, System.currentTimeMillis());
}

@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 expiresIn, long timestamp) {
return insertCallLog(address, Types.MISSED_CALL_TYPE, expiresIn, true, timestamp);
}

private @NonNull Pair<Long, Long> insertCallLog(@NonNull RecipientId recipientId, long type, boolean unread, long timestamp) {
private @NonNull Pair<Long, Long> insertCallLog(@NonNull RecipientId recipientId, long type, long expiresIn, boolean unread, long timestamp) {
Recipient recipient = Recipient.resolved(recipientId);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);

Expand All @@ -670,6 +671,7 @@ public boolean hasReceivedAnyCallsSince(long threadId, long timestamp) {
values.put(READ, unread ? 0 : 1);
values.put(TYPE, type);
values.put(THREAD_ID, threadId);
values.put(EXPIRES_IN, expiresIn);

SQLiteDatabase db = databaseHelper.getWritableDatabase();
long messageId = db.insert(TABLE_NAME, null, values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,10 @@ public int getExpireMessages() {
return expireMessages;
}

public long getExpireMessagesInMillis() {
return getExpireMessages() * 1000L;
}

public boolean hasSeenFirstInviteReminder() {
return insightsBannerTier.seen(InsightsBannerTier.TIER_ONE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessageDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
Expand Down Expand Up @@ -421,7 +422,7 @@ private void handleReceivedOffer(Intent intent) {
Log.i(TAG, "PSTN line is busy.");
intent.putExtra(EXTRA_BROADCAST, true);
handleSendBusy(intent);
insertMissedCall(remotePeer, true, serverReceivedTimestamp);
insertMissedCall(remotePeer.getRecipient(), true, serverReceivedTimestamp);
return;
}

Expand All @@ -430,7 +431,7 @@ private void handleReceivedOffer(Intent intent) {
intent.putExtra(EXTRA_BROADCAST, true);
intent.putExtra(EXTRA_HANGUP_TYPE, HangupMessage.Type.NEED_PERMISSION.getCode());
handleSendHangup(intent);
insertMissedCall(remotePeer, true, serverReceivedTimestamp);
insertMissedCall(remotePeer.getRecipient(), true, serverReceivedTimestamp);
return;
}

Expand Down Expand Up @@ -553,11 +554,37 @@ private void handleIsInCallQuery(Intent intent) {
}
}

private void insertMissedCall(@NonNull RemotePeer remotePeer, boolean signal, long timestamp) {
Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(remotePeer.getId(), timestamp);
private void insertMissedCall(@NonNull Recipient recipient, boolean signal, long timestamp) {
long expiresIn = recipient.getExpireMessagesInMillis();
Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getId(), expiresIn, timestamp);
ApplicationDependencies.getMessageNotifier().updateNotification(this, messageAndThreadId.second(), signal);
}

private void insertDeniedCall(@NonNull Recipient recipient) {
long expiresIn = recipient.getExpireMessagesInMillis();
DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getId(), expiresIn, System.currentTimeMillis());
}

private void insertOutgoingCall(@NonNull Recipient recipient) {
long expiresIn = recipient.getExpireMessagesInMillis();
MessageDatabase database = DatabaseFactory.getSmsDatabase(this);
Pair<Long, Long> messageAndThreadId = database.insertOutgoingCall(recipient.getId(), expiresIn);
if (expiresIn > 0) {
database.markExpireStarted(messageAndThreadId.first());
ApplicationContext.getInstance(this).getExpiringMessageManager().scheduleDeletion(messageAndThreadId.first(), false, expiresIn);
}
}

private void insertReceivedCall(@NonNull Recipient recipient) {
long expiresIn = recipient.getExpireMessagesInMillis();
MessageDatabase database = DatabaseFactory.getSmsDatabase(this);
Pair<Long, Long> messageAndThreadId = database.insertReceivedCall(recipient.getId(), expiresIn);
if (expiresIn > 0) {
database.markExpireStarted(messageAndThreadId.first());
ApplicationContext.getInstance(this).getExpiringMessageManager().scheduleDeletion(messageAndThreadId.first(), false, expiresIn);
}
}

private void handleDenyCall(Intent intent) {
if (activePeer == null) {
Log.i(TAG, "handleDenyCall(): Ignoring for inactive call.");
Expand All @@ -573,7 +600,7 @@ private void handleDenyCall(Intent intent) {

try {
callManager.hangup();
DatabaseFactory.getSmsDatabase(this).insertMissedCall(activePeer.getId(), System.currentTimeMillis());
insertDeniedCall(activePeer.getRecipient());
terminate(activePeer);
} catch (CallException e) {
callFailure("hangup() failed: ", e);
Expand Down Expand Up @@ -710,7 +737,7 @@ private void handleStartOutgoingCall(Intent intent) {

setCallInProgressNotification(TYPE_OUTGOING_RINGING, activePeer);

DatabaseFactory.getSmsDatabase(this).insertOutgoingCall(activePeer.getId());
insertOutgoingCall(activePeer.getRecipient());

retrieveTurnServers().addListener(new SuccessOnlyListener<List<PeerConnection.IceServer>>(this.activePeer.getState(), this.activePeer.getCallId()) {
@Override
Expand Down Expand Up @@ -802,7 +829,7 @@ private void handleAcceptCall(Intent intent) {

Log.i(TAG, "handleAcceptCall(): call_id: " + activePeer.getCallId());

DatabaseFactory.getSmsDatabase(this).insertReceivedCall(activePeer.getId());
insertReceivedCall(activePeer.getRecipient());

acceptWithVideo = intent.getBooleanExtra(EXTRA_ANSWER_WITH_VIDEO, false);

Expand Down Expand Up @@ -1167,7 +1194,7 @@ private void handleReceivedOfferExpired(Intent intent) {

Log.i(TAG, "handleReceivedOfferExpired(): call_id: " + remotePeer.getCallId());

insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
insertMissedCall(remotePeer.getRecipient(), true, remotePeer.getCallStartTimestamp());

terminate(remotePeer);
}
Expand Down Expand Up @@ -1196,7 +1223,7 @@ private void handleReceivedOfferWhileActive(Intent intent) {
stopForeground(true);
}

insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
insertMissedCall(remotePeer.getRecipient(), true, remotePeer.getCallStartTimestamp());

terminate(remotePeer);
}
Expand All @@ -1217,7 +1244,7 @@ private void handleEndedRemoteHangup(Intent intent) {

boolean incomingBeforeAccept = remotePeer.getState() == CallState.ANSWERING || remotePeer.getState() == CallState.LOCAL_RINGING;
if (incomingBeforeAccept) {
insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
insertMissedCall(remotePeer.getRecipient(), true, remotePeer.getCallStartTimestamp());
}

terminate(remotePeer);
Expand Down Expand Up @@ -1304,7 +1331,7 @@ private void handleEndedRemoteGlare(Intent intent) {

boolean incomingBeforeAccept = remotePeer.getState() == CallState.ANSWERING || remotePeer.getState() == CallState.LOCAL_RINGING;
if (incomingBeforeAccept) {
insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
insertMissedCall(remotePeer.getRecipient(), true, remotePeer.getCallStartTimestamp());
}

terminate(remotePeer);
Expand All @@ -1320,7 +1347,7 @@ private void handleEndedFailure(Intent intent) {
}

if (remotePeer.getState() == CallState.ANSWERING || remotePeer.getState() == CallState.LOCAL_RINGING) {
insertMissedCall(remotePeer, true, remotePeer.getCallStartTimestamp());
insertMissedCall(remotePeer.getRecipient(), true, remotePeer.getCallStartTimestamp());
}

terminate(remotePeer);
Expand Down
38 changes: 27 additions & 11 deletions app/src/main/res/layout/conversation_item_update.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,35 @@
android:textColor="?attr/conversation_item_update_text_color"
tools:text="Gwen Stacy set the disappearing message timer to 1 hour" />

<TextView
android:id="@+id/conversation_update_date"
style="@style/Signal.Text.Caption"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="6dp"
android:autoLink="none"
android:gravity="center"
android:linksClickable="false"
android:minWidth="15sp"
android:textColor="?conversation_item_update_text_color"
tools:text="30 min ago" />
android:layout_marginBottom="0dp">

<TextView
android:id="@+id/conversation_update_date"
style="@style/Signal.Text.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="none"
android:layout_marginTop="6dp"
android:linksClickable="false"
android:minWidth="15sp"
android:textColor="?conversation_item_update_text_color"
tools:text="30 min ago" />

<org.thoughtcrime.securesms.components.ExpirationTimerView
android:id="@+id/conversation_update_expiration_timer"
android:layout_marginTop="3dp"
android:layout_marginStart="4dp"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_gravity="center_vertical"
app:tint="?conversation_item_update_text_color"
android:visibility="gone"
tools:visibility="visible" />

</LinearLayout>

</LinearLayout>

Expand Down

0 comments on commit b2955d6

Please sign in to comment.