Skip to content

Instantly share code, notes, and snippets.

@valldrac
Created March 4, 2020 11:55
Show Gist options
  • Save valldrac/ceb4343adfecf3114c9cc8eb07929cb5 to your computer and use it in GitHub Desktop.
Save valldrac/ceb4343adfecf3114c9cc8eb07929cb5 to your computer and use it in GitHub Desktop.
Disappearing call logs patch for Signal v4.44.7
diff --git a/res/layout/conversation_item_update.xml b/res/layout/conversation_item_update.xml
index 9a2368a43..2753e84c4 100644
--- a/res/layout/conversation_item_update.xml
+++ b/res/layout/conversation_item_update.xml
@@ -44,7 +44,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="7dp"
+ android:layout_marginBottom="6dp"
android:gravity="center"
android:orientation="vertical">
@@ -59,13 +59,21 @@
android:textColor="?attr/conversation_item_update_text_color"
tools:text="Gwen Stacy set the disappearing message timer to 1 hour" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="7dp"
+ android:gravity="center"
+ android:orientation="horizontal">
+
<TextView
android:id="@+id/conversation_update_date"
style="@style/Signal.Text.Caption"
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"
@@ -74,6 +82,15 @@
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_gravity="center_vertical|end"
+ android:layout_marginStart="6dp"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:visibility="gone"
+ tools:visibility="visible"/>
+
</LinearLayout>
</org.thoughtcrime.securesms.conversation.ConversationUpdateItem>
diff --git a/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java b/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java
index 528e758b1..e473387b3 100644
--- a/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java
+++ b/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java
@@ -134,7 +134,7 @@ public class ConversationItemFooter extends LinearLayout {
messageRecord.getExpiresIn());
this.timerView.startAnimation();
- if (messageRecord.getExpireStarted() + messageRecord.getExpiresIn() <= System.currentTimeMillis()) {
+ if (this.timerView.isExpired()) {
ApplicationContext.getInstance(getContext()).getExpiringMessageManager().checkSchedule();
}
} else if (!messageRecord.isOutgoing() && !messageRecord.isMediaPending()) {
diff --git a/src/org/thoughtcrime/securesms/components/ExpirationTimerView.java b/src/org/thoughtcrime/securesms/components/ExpirationTimerView.java
index 1de60b823..485ce1822 100644
--- a/src/org/thoughtcrime/securesms/components/ExpirationTimerView.java
+++ b/src/org/thoughtcrime/securesms/components/ExpirationTimerView.java
@@ -59,6 +59,10 @@ public class ExpirationTimerView extends androidx.appcompat.widget.AppCompatImag
setImageResource(frames[frame]);
}
+ public boolean isExpired() {
+ return startedAt + expiresIn <= System.currentTimeMillis();
+ }
+
public void startAnimation() {
synchronized (this) {
visible = true;
diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java b/src/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java
index 8dbeca26b..c1e37dbe8 100644
--- a/src/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java
+++ b/src/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java
@@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.conversation;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
@@ -7,16 +8,21 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+
+import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+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.crypto.IdentityKeyParcelable;
+import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -24,6 +30,7 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
+import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
@@ -43,13 +50,14 @@ public class ConversationUpdateItem extends LinearLayout
private Set<MessageRecord> batchSelected;
- private ImageView icon;
- private TextView title;
- private TextView body;
- private TextView date;
- private Recipient sender;
- private MessageRecord messageRecord;
- private Locale locale;
+ private ImageView icon;
+ private TextView title;
+ private TextView body;
+ private TextView date;
+ private ExpirationTimerView timer;
+ private Recipient sender;
+ private MessageRecord messageRecord;
+ private Locale locale;
public ConversationUpdateItem(Context context) {
super(context);
@@ -67,6 +75,7 @@ public class ConversationUpdateItem extends LinearLayout
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));
}
@@ -118,6 +127,7 @@ public class ConversationUpdateItem extends LinearLayout
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);
@@ -129,6 +139,37 @@ public class ConversationUpdateItem extends LinearLayout
title.setVisibility(GONE);
body.setVisibility(VISIBLE);
date.setVisibility(View.VISIBLE);
+
+ if (messageRecord.getExpiresIn() > 0 && !messageRecord.isPending()) {
+ timer.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#757575"), PorterDuff.Mode.MULTIPLY));
+ 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()) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ ExpiringMessageManager expirationManager = ApplicationContext.getInstance(getContext()).getExpiringMessageManager();
+ long id = messageRecord.getId();
+
+ DatabaseFactory.getSmsDatabase(getContext()).markExpireStarted(id);
+
+ expirationManager.scheduleDeletion(id, false, messageRecord.getExpiresIn());
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ } else {
+ timer.setVisibility(View.GONE);
+ }
}
private void setTimerRecord(final MessageRecord messageRecord) {
diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
index 81527845b..c613001b4 100644
--- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
@@ -408,7 +408,8 @@ public class SmsDatabase extends MessagingDatabase {
cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED}, where, arguments, null, null, null);
while (cursor != null && cursor.moveToNext()) {
- if (Types.isSecureType(cursor.getLong(3))) {
+ long type = cursor.getLong(3);
+ if (Types.isSecureType(type) || Types.isCallLog(type)) {
SyncMessageId syncMessageId = new SyncMessageId(Address.fromSerialized(cursor.getString(1)), cursor.getLong(2));
ExpirationInfo expirationInfo = new ExpirationInfo(cursor.getLong(0), cursor.getLong(4), cursor.getLong(5), false);
@@ -485,19 +486,19 @@ public class SmsDatabase extends MessagingDatabase {
}
}
- public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull Address address) {
- return insertCallLog(address, Types.INCOMING_CALL_TYPE, false);
+ public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull Address address, long expiresIn) {
+ return insertCallLog(address, Types.INCOMING_CALL_TYPE, expiresIn, false);
}
- public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull Address address) {
- return insertCallLog(address, Types.OUTGOING_CALL_TYPE, false);
+ public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull Address address, long expiresIn) {
+ return insertCallLog(address, Types.OUTGOING_CALL_TYPE, expiresIn, false);
}
- public @NonNull Pair<Long, Long> insertMissedCall(@NonNull Address address) {
- return insertCallLog(address, Types.MISSED_CALL_TYPE, true);
+ public @NonNull Pair<Long, Long> insertMissedCall(@NonNull Address address, long expiresIn) {
+ return insertCallLog(address, Types.MISSED_CALL_TYPE, expiresIn, true);
}
- private @NonNull Pair<Long, Long> insertCallLog(@NonNull Address address, long type, boolean unread) {
+ private @NonNull Pair<Long, Long> insertCallLog(@NonNull Address address, long type, long expiresIn, boolean unread) {
Recipient recipient = Recipient.from(context, address, true);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
@@ -509,6 +510,7 @@ public class SmsDatabase extends MessagingDatabase {
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);
diff --git a/src/org/thoughtcrime/securesms/recipients/Recipient.java b/src/org/thoughtcrime/securesms/recipients/Recipient.java
index ec144f630..c8c3cea08 100644
--- a/src/org/thoughtcrime/securesms/recipients/Recipient.java
+++ b/src/org/thoughtcrime/securesms/recipients/Recipient.java
@@ -571,6 +571,10 @@ public class Recipient implements RecipientModifiedListener {
return expireMessages;
}
+ public long getExpireMessagesInMillis() {
+ return getExpireMessages() * 1000L;
+ }
+
public void setExpireMessages(int expireMessages) {
synchronized (this) {
this.expireMessages = expireMessages;
diff --git a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java
index 30140dbc3..24adc9459 100644
--- a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java
+++ b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
+import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.logging.Log;
@@ -436,7 +437,7 @@ public class WebRtcCallService extends Service implements PeerConnection.Observe
bluetoothStateManager.setWantsConnection(true);
setCallInProgressNotification(TYPE_OUTGOING_RINGING, recipient);
- DatabaseFactory.getSmsDatabase(this).insertOutgoingCall(recipient.getAddress());
+ insertOutgoingCall(recipient);
timeoutExecutor.schedule(new TimeoutRunnable(this.callId), 2, TimeUnit.MINUTES);
@@ -715,10 +716,36 @@ public class WebRtcCallService extends Service implements PeerConnection.Observe
}
private void insertMissedCall(@NonNull Recipient recipient, boolean signal) {
- Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getAddress());
+ long expiresIn = recipient.getExpireMessagesInMillis();
+ Pair<Long, Long> messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getAddress(), expiresIn);
MessageNotifier.updateNotification(this, messageAndThreadId.second, signal);
}
+ private void insertDeniedCall(@NonNull Recipient recipient) {
+ long expiresIn = recipient.getExpireMessagesInMillis();
+ DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getAddress(), expiresIn);
+ }
+
+ private void insertOutgoingCall(@NonNull Recipient recipient) {
+ long expiresIn = recipient.getExpireMessagesInMillis();
+ SmsDatabase database = DatabaseFactory.getSmsDatabase(this);
+ Pair<Long, Long> messageAndThreadId = database.insertOutgoingCall(recipient.getAddress(), 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();
+ SmsDatabase database = DatabaseFactory.getSmsDatabase(this);
+ Pair<Long, Long> messageAndThreadId = database.insertReceivedCall(recipient.getAddress(), expiresIn);
+ if (expiresIn > 0) {
+ database.markExpireStarted(messageAndThreadId.first);
+ ApplicationContext.getInstance(this).getExpiringMessageManager().scheduleDeletion(messageAndThreadId.first, false, expiresIn);
+ }
+ }
+
private void handleAnswerCall(Intent intent) {
if (callState != CallState.STATE_LOCAL_RINGING) {
Log.w(TAG, "Can only answer from ringing!");
@@ -729,7 +756,7 @@ public class WebRtcCallService extends Service implements PeerConnection.Observe
throw new AssertionError("assert");
}
- DatabaseFactory.getSmsDatabase(this).insertReceivedCall(recipient.getAddress());
+ insertReceivedCall(recipient);
this.peerConnection.setAudioEnabled(true);
this.peerConnection.setVideoEnabled(false);
@@ -753,7 +780,7 @@ public class WebRtcCallService extends Service implements PeerConnection.Observe
this.dataChannel.send(new DataChannel.Buffer(ByteBuffer.wrap(Data.newBuilder().setHangup(Hangup.newBuilder().setId(this.callId)).build().toByteArray()), false));
sendMessage(this.recipient, SignalServiceCallMessage.forHangup(new HangupMessage(this.callId)));
- DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getAddress());
+ insertDeniedCall(recipient);
this.terminate();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment