Log calls to conversations
// FREEBIE
BIN
res/drawable-hdpi/ic_call_made_grey600_24dp.png
Normal file
After Width: | Height: | Size: 284 B |
BIN
res/drawable-hdpi/ic_call_missed_grey600_24dp.png
Normal file
After Width: | Height: | Size: 311 B |
BIN
res/drawable-hdpi/ic_call_received_grey600_24dp.png
Normal file
After Width: | Height: | Size: 309 B |
BIN
res/drawable-mdpi/ic_call_made_grey600_24dp.png
Normal file
After Width: | Height: | Size: 227 B |
BIN
res/drawable-mdpi/ic_call_missed_grey600_24dp.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
res/drawable-mdpi/ic_call_received_grey600_24dp.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
res/drawable-xhdpi/ic_call_made_grey600_24dp.png
Normal file
After Width: | Height: | Size: 308 B |
BIN
res/drawable-xhdpi/ic_call_missed_grey600_24dp.png
Normal file
After Width: | Height: | Size: 359 B |
BIN
res/drawable-xhdpi/ic_call_received_grey600_24dp.png
Normal file
After Width: | Height: | Size: 322 B |
BIN
res/drawable-xxhdpi/ic_call_made_grey600_24dp.png
Normal file
After Width: | Height: | Size: 386 B |
BIN
res/drawable-xxhdpi/ic_call_missed_grey600_24dp.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
res/drawable-xxhdpi/ic_call_received_grey600_24dp.png
Normal file
After Width: | Height: | Size: 384 B |
|
@ -1,21 +1,25 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<org.thoughtcrime.securesms.ConversationUpdateItem
|
<org.thoughtcrime.securesms.ConversationUpdateItem
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/conversation_update_item"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/conversation_update_item"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:gravity="center"
|
android:layout_height="wrap_content"
|
||||||
android:padding="20dp">
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
<LinearLayout android:orientation="horizontal"
|
<ImageView android:id="@+id/conversation_update_icon"
|
||||||
|
android:layout_marginRight="7dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:src="@drawable/ic_call_received_grey600_24dp" />
|
||||||
|
|
||||||
|
<LinearLayout android:orientation="vertical"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<ImageView android:id="@+id/conversation_update_icon"
|
|
||||||
android:layout_marginRight="7dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/conversation_update_body"
|
<TextView android:id="@+id/conversation_update_body"
|
||||||
android:autoLink="all"
|
android:autoLink="all"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -23,8 +27,25 @@
|
||||||
android:linksClickable="true"
|
android:linksClickable="true"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
android:textColor="?attr/conversation_group_member_name"/>
|
android:textColor="?attr/conversation_group_member_name"
|
||||||
|
tools:text="Sasha called you"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/conversation_update_date"
|
||||||
|
android:autoLink="none"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="15sp"
|
||||||
|
android:linksClickable="false"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textColor="?conversation_item_sent_text_secondary_color"
|
||||||
|
android:textSize="@dimen/conversation_item_date_text_size"
|
||||||
|
android:paddingTop="1dip"
|
||||||
|
android:paddingBottom="2dp"
|
||||||
|
tools:text="30 min ago" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</org.thoughtcrime.securesms.ConversationUpdateItem>
|
</org.thoughtcrime.securesms.ConversationUpdateItem>
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.thoughtcrime.redphone.signaling.SignalingSocket;
|
||||||
import org.thoughtcrime.redphone.ui.NotificationBarManager;
|
import org.thoughtcrime.redphone.ui.NotificationBarManager;
|
||||||
import org.thoughtcrime.redphone.util.Base64;
|
import org.thoughtcrime.redphone.util.Base64;
|
||||||
import org.thoughtcrime.redphone.util.UncaughtExceptionHandlerManager;
|
import org.thoughtcrime.redphone.util.UncaughtExceptionHandlerManager;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
@ -92,15 +93,12 @@ public class RedPhoneService extends Service implements CallStateListener, CallS
|
||||||
|
|
||||||
private int state;
|
private int state;
|
||||||
private byte[] zid;
|
private byte[] zid;
|
||||||
// private String localNumber;
|
|
||||||
private String remoteNumber;
|
private String remoteNumber;
|
||||||
// private String password;
|
|
||||||
private CallManager currentCallManager;
|
private CallManager currentCallManager;
|
||||||
private LockManager lockManager;
|
private LockManager lockManager;
|
||||||
private UncaughtExceptionHandlerManager uncaughtExceptionHandlerManager;
|
private UncaughtExceptionHandlerManager uncaughtExceptionHandlerManager;
|
||||||
|
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
// private CallLogger.CallRecord currentCallRecord;
|
|
||||||
private IncomingPstnCallListener pstnCallListener;
|
private IncomingPstnCallListener pstnCallListener;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,17 +161,9 @@ public class RedPhoneService extends Service implements CallStateListener, CallS
|
||||||
registerReceiver(pstnCallListener, new IntentFilter("android.intent.action.PHONE_STATE"));
|
registerReceiver(pstnCallListener, new IntentFilter("android.intent.action.PHONE_STATE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void initializeApplicationContext() {
|
|
||||||
// ApplicationContext context = ApplicationContext.getInstance();
|
|
||||||
// context.setContext(this);
|
|
||||||
// context.setCallStateListener(this);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void initializeResources() {
|
private void initializeResources() {
|
||||||
this.state = RedPhone.STATE_IDLE;
|
this.state = RedPhone.STATE_IDLE;
|
||||||
this.zid = getZID();
|
this.zid = getZID();
|
||||||
// this.localNumber = TextSecurePreferences.getLocalNumber(this);
|
|
||||||
// this.password = TextSecurePreferences.getPushServerPassword(this);
|
|
||||||
this.lockManager = new LockManager(this);
|
this.lockManager = new LockManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +206,8 @@ public class RedPhoneService extends Service implements CallStateListener, CallS
|
||||||
this.currentCallManager.start();
|
this.currentCallManager.start();
|
||||||
|
|
||||||
NotificationBarManager.setCallInProgress(this);
|
NotificationBarManager.setCallInProgress(this);
|
||||||
//
|
DatabaseFactory.getSmsDatabase(this).insertOutgoingCall(remoteNumber);
|
||||||
// currentCallRecord = CallLogger.logOutgoingCall(this, remoteNumber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleBusyCall(Intent intent) {
|
private void handleBusyCall(Intent intent) {
|
||||||
|
@ -246,14 +236,14 @@ public class RedPhoneService extends Service implements CallStateListener, CallS
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMissedCall(String remoteNumber) {
|
private void handleMissedCall(String remoteNumber) {
|
||||||
// CallLogger.logMissedCall(this, remoteNumber, System.currentTimeMillis());
|
DatabaseFactory.getSmsDatabase(this).insertMissedCall(remoteNumber);
|
||||||
NotificationBarManager.notifyMissedCall(this, remoteNumber);
|
NotificationBarManager.notifyMissedCall(this, remoteNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAnswerCall(Intent intent) {
|
private void handleAnswerCall(Intent intent) {
|
||||||
state = RedPhone.STATE_ANSWERING;
|
state = RedPhone.STATE_ANSWERING;
|
||||||
incomingRinger.stop();
|
incomingRinger.stop();
|
||||||
// currentCallRecord = CallLogger.logIncomingCall(this, remoteNumber);
|
DatabaseFactory.getSmsDatabase(this).insertReceivedCall(remoteNumber);
|
||||||
if (currentCallManager != null) {
|
if (currentCallManager != null) {
|
||||||
((ResponderCallManager)this.currentCallManager).answer(true);
|
((ResponderCallManager)this.currentCallManager).answer(true);
|
||||||
}
|
}
|
||||||
|
@ -262,7 +252,7 @@ public class RedPhoneService extends Service implements CallStateListener, CallS
|
||||||
private void handleDenyCall(Intent intent) {
|
private void handleDenyCall(Intent intent) {
|
||||||
state = RedPhone.STATE_IDLE;
|
state = RedPhone.STATE_IDLE;
|
||||||
incomingRinger.stop();
|
incomingRinger.stop();
|
||||||
// CallLogger.logMissedCall(this, remoteNumber, System.currentTimeMillis());
|
DatabaseFactory.getSmsDatabase(this).insertMissedCall(remoteNumber);
|
||||||
if(currentCallManager != null) {
|
if(currentCallManager != null) {
|
||||||
((ResponderCallManager)this.currentCallManager).answer(false);
|
((ResponderCallManager)this.currentCallManager).answer(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,15 @@ import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
import org.thoughtcrime.redphone.RedPhone;
|
import org.thoughtcrime.redphone.RedPhone;
|
||||||
|
import org.thoughtcrime.securesms.ConversationActivity;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the state of the RedPhone items in the Android notification bar.
|
* Manages the state of the RedPhone items in the Android notification bar.
|
||||||
|
@ -35,7 +41,8 @@ import org.thoughtcrime.securesms.R;
|
||||||
|
|
||||||
public class NotificationBarManager {
|
public class NotificationBarManager {
|
||||||
|
|
||||||
private static final int RED_PHONE_NOTIFICATION = 313388;
|
private static final int RED_PHONE_NOTIFICATION = 313388;
|
||||||
|
private static final int MISSED_CALL_NOTIFICATION = 313389;
|
||||||
|
|
||||||
public static void setCallEnded(Context context) {
|
public static void setCallEnded(Context context) {
|
||||||
NotificationManager notificationManager = (NotificationManager)context
|
NotificationManager notificationManager = (NotificationManager)context
|
||||||
|
@ -61,26 +68,27 @@ public class NotificationBarManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void notifyMissedCall(Context context, String remoteNumber) {
|
public static void notifyMissedCall(Context context, String remoteNumber) {
|
||||||
// Intent intent = new Intent(DialerActivity.CALL_LOG_ACTION, null,
|
Intent intent = new Intent(context, ConversationActivity.class);
|
||||||
// context, DialerActivity.class);
|
Recipients notifyRecipients = RecipientFactory.getRecipientsFromString(context, remoteNumber, false);
|
||||||
// PendingIntent launchIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
intent.putExtra("recipients", notifyRecipients.getIds());
|
||||||
// PersonInfo remoteInfo = PersonInfo.getInstance(context, remoteNumber);
|
intent.putExtra("thread_id", DatabaseFactory.getThreadDatabase(context).getThreadIdFor(notifyRecipients));
|
||||||
|
intent.setData((Uri.parse("custom://" + System.currentTimeMillis())));
|
||||||
|
|
||||||
// NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
// builder.setSmallIcon(R.drawable.stat_notify_missed_call);
|
|
||||||
// builder.setWhen(System.currentTimeMillis());
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||||
// builder.setTicker(context
|
builder.setSmallIcon(R.drawable.ic_call_missed_grey600_24dp);
|
||||||
// .getString(R.string.NotificationBarManager_missed_redphone_call_from_s,
|
builder.setWhen(System.currentTimeMillis());
|
||||||
// remoteInfo.getName()));
|
builder.setTicker(String.format("Missed call from %s", notifyRecipients.toShortString()));
|
||||||
// builder.setContentTitle(context.getString(R.string.NotificationBarManager_missed_redphone_call));
|
builder.setContentTitle("Missed Signal call");
|
||||||
// builder.setContentText(remoteInfo.getName());
|
builder.setContentText(String.format("Missed call from %s", notifyRecipients.toShortString()));
|
||||||
// builder.setContentIntent(launchIntent);
|
builder.setContentIntent(pendingIntent);
|
||||||
// builder.setDefaults(Notification.DEFAULT_VIBRATE);
|
builder.setDefaults(Notification.DEFAULT_VIBRATE);
|
||||||
// builder.setAutoCancel(true);
|
builder.setAutoCancel(true);
|
||||||
//
|
|
||||||
// NotificationManager manager = (NotificationManager)context
|
NotificationManager manager = (NotificationManager)context
|
||||||
// .getSystemService(Context.NOTIFICATION_SERVICE);
|
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
//
|
|
||||||
// manager.notify(DialerActivity.MISSED_CALL, builder.build());
|
manager.notify(MISSED_CALL_NOTIFICATION, builder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,9 +164,9 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||||
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
||||||
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
||||||
|
|
||||||
if (messageRecord.isGroupAction()) return MESSAGE_TYPE_UPDATE;
|
if (messageRecord.isGroupAction() || messageRecord.isCallLog()) return MESSAGE_TYPE_UPDATE;
|
||||||
else if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING;
|
else if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING;
|
||||||
else return MESSAGE_TYPE_INCOMING;
|
else return MESSAGE_TYPE_INCOMING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
|
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
import org.thoughtcrime.securesms.util.DateUtils;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
|
@ -26,8 +27,10 @@ public class ConversationUpdateItem extends LinearLayout
|
||||||
|
|
||||||
private ImageView icon;
|
private ImageView icon;
|
||||||
private TextView body;
|
private TextView body;
|
||||||
|
private TextView date;
|
||||||
private Recipient sender;
|
private Recipient sender;
|
||||||
private MessageRecord messageRecord;
|
private MessageRecord messageRecord;
|
||||||
|
private Locale locale;
|
||||||
|
|
||||||
public ConversationUpdateItem(Context context) {
|
public ConversationUpdateItem(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -43,6 +46,7 @@ public class ConversationUpdateItem extends LinearLayout
|
||||||
|
|
||||||
this.icon = (ImageView)findViewById(R.id.conversation_update_icon);
|
this.icon = (ImageView)findViewById(R.id.conversation_update_icon);
|
||||||
this.body = (TextView)findViewById(R.id.conversation_update_body);
|
this.body = (TextView)findViewById(R.id.conversation_update_body);
|
||||||
|
this.date = (TextView)findViewById(R.id.conversation_update_date);
|
||||||
|
|
||||||
setOnClickListener(this);
|
setOnClickListener(this);
|
||||||
}
|
}
|
||||||
|
@ -54,28 +58,45 @@ public class ConversationUpdateItem extends LinearLayout
|
||||||
@NonNull Set<MessageRecord> batchSelected,
|
@NonNull Set<MessageRecord> batchSelected,
|
||||||
boolean groupThread, boolean pushDestination)
|
boolean groupThread, boolean pushDestination)
|
||||||
{
|
{
|
||||||
bind(messageRecord);
|
bind(messageRecord, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind(@NonNull MessageRecord messageRecord) {
|
private void bind(@NonNull MessageRecord messageRecord, @NonNull Locale locale) {
|
||||||
this.messageRecord = messageRecord;
|
this.messageRecord = messageRecord;
|
||||||
this.sender = messageRecord.getIndividualRecipient();
|
this.sender = messageRecord.getIndividualRecipient();
|
||||||
|
this.locale = locale;
|
||||||
|
|
||||||
this.sender.addListener(this);
|
this.sender.addListener(this);
|
||||||
|
|
||||||
if (messageRecord.isGroupAction()) {
|
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
|
||||||
icon.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_group_grey600_24dp));
|
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
|
||||||
|
else throw new AssertionError("Neither group no log.");
|
||||||
|
}
|
||||||
|
|
||||||
if (messageRecord.isGroupQuit() && messageRecord.isOutgoing()) {
|
private void setCallRecord(MessageRecord messageRecord) {
|
||||||
body.setText(R.string.MessageRecord_left_group);
|
if (messageRecord.isIncomingCall()) icon.setImageResource(R.drawable.ic_call_received_grey600_24dp);
|
||||||
} else if (messageRecord.isGroupQuit()) {
|
else if (messageRecord.isOutgoingCall()) icon.setImageResource(R.drawable.ic_call_made_grey600_24dp);
|
||||||
body.setText(getContext().getString(R.string.ConversationItem_group_action_left, sender.toShortString()));
|
else icon.setImageResource(R.drawable.ic_call_missed_grey600_24dp);
|
||||||
} else {
|
|
||||||
GroupUtil.GroupDescription description = GroupUtil.getDescription(getContext(), messageRecord.getBody().getBody());
|
body.setText(messageRecord.getDisplayBody());
|
||||||
description.addListener(this);
|
date.setText(DateUtils.getExtendedRelativeTimeSpanString(getContext(), locale, messageRecord.getDateReceived()));
|
||||||
body.setText(description.toString());
|
date.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setGroupRecord(MessageRecord messageRecord) {
|
||||||
|
icon.setImageResource(R.drawable.ic_group_grey600_24dp);
|
||||||
|
|
||||||
|
if (messageRecord.isGroupQuit() && messageRecord.isOutgoing()) {
|
||||||
|
body.setText(R.string.MessageRecord_left_group);
|
||||||
|
} else if (messageRecord.isGroupQuit()) {
|
||||||
|
body.setText(getContext().getString(R.string.ConversationItem_group_action_left, sender.toShortString()));
|
||||||
|
} else {
|
||||||
|
GroupUtil.GroupDescription description = GroupUtil.getDescription(getContext(), messageRecord.getBody().getBody());
|
||||||
|
description.addListener(this);
|
||||||
|
body.setText(description.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
date.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,7 +109,7 @@ public class ConversationUpdateItem extends LinearLayout
|
||||||
Util.runOnMain(new Runnable() {
|
Util.runOnMain(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
bind(messageRecord);
|
bind(messageRecord, locale);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ public interface MmsSmsColumns {
|
||||||
// Base Types
|
// Base Types
|
||||||
protected static final long BASE_TYPE_MASK = 0x1F;
|
protected static final long BASE_TYPE_MASK = 0x1F;
|
||||||
|
|
||||||
|
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 BASE_INBOX_TYPE = 20;
|
protected static final long BASE_INBOX_TYPE = 20;
|
||||||
protected static final long BASE_OUTBOX_TYPE = 21;
|
protected static final long BASE_OUTBOX_TYPE = 21;
|
||||||
protected static final long BASE_SENDING_TYPE = 22;
|
protected static final long BASE_SENDING_TYPE = 22;
|
||||||
|
@ -150,6 +154,22 @@ public interface MmsSmsColumns {
|
||||||
return (type & KEY_EXCHANGE_IDENTITY_UPDATE_BIT) != 0;
|
return (type & KEY_EXCHANGE_IDENTITY_UPDATE_BIT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isCallLog(long type) {
|
||||||
|
return type == INCOMING_CALL_TYPE || type == OUTGOING_CALL_TYPE || type == MISSED_CALL_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIncomingCall(long type) {
|
||||||
|
return type == INCOMING_CALL_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOutgoingCall(long type) {
|
||||||
|
return type == OUTGOING_CALL_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMissedCall(long type) {
|
||||||
|
return type == MISSED_CALL_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isGroupUpdate(long type) {
|
public static boolean isGroupUpdate(long type) {
|
||||||
return (type & GROUP_UPDATE_BIT) != 0;
|
return (type & GROUP_UPDATE_BIT) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.database.sqlite.SQLiteStatement;
|
import android.database.sqlite.SQLiteStatement;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.telephony.PhoneNumberUtils;
|
import android.telephony.PhoneNumberUtils;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -343,6 +344,45 @@ public class SmsDatabase extends MessagingDatabase {
|
||||||
return new Pair<>(newMessageId, record.getThreadId());
|
return new Pair<>(newMessageId, record.getThreadId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NonNull Pair<Long, Long> insertReceivedCall(@NonNull String number) {
|
||||||
|
return insertCallLog(number, Types.INCOMING_CALL_TYPE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull Pair<Long, Long> insertOutgoingCall(@NonNull String number) {
|
||||||
|
return insertCallLog(number, Types.OUTGOING_CALL_TYPE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull Pair<Long, Long> insertMissedCall(@NonNull String number) {
|
||||||
|
return insertCallLog(number, Types.MISSED_CALL_TYPE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NonNull Pair<Long, Long> insertCallLog(@NonNull String number, long type, boolean unread) {
|
||||||
|
Recipients recipients = RecipientFactory.getRecipientsFromString(context, number, true);
|
||||||
|
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||||
|
|
||||||
|
ContentValues values = new ContentValues(6);
|
||||||
|
values.put(ADDRESS, number);
|
||||||
|
values.put(ADDRESS_DEVICE_ID, 1);
|
||||||
|
values.put(DATE_RECEIVED, System.currentTimeMillis());
|
||||||
|
values.put(DATE_SENT, System.currentTimeMillis());
|
||||||
|
values.put(READ, unread ? 0 : 1);
|
||||||
|
values.put(TYPE, type);
|
||||||
|
values.put(THREAD_ID, threadId);
|
||||||
|
|
||||||
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
|
long messageId = db.insert(TABLE_NAME, null, values);
|
||||||
|
|
||||||
|
DatabaseFactory.getThreadDatabase(context).update(threadId);
|
||||||
|
notifyConversationListeners(threadId);
|
||||||
|
jobManager.add(new TrimThreadJob(context, threadId));
|
||||||
|
|
||||||
|
if (unread) {
|
||||||
|
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Pair<>(messageId, threadId);
|
||||||
|
}
|
||||||
|
|
||||||
protected Pair<Long, Long> insertMessageInbox(IncomingTextMessage message, long type) {
|
protected Pair<Long, Long> insertMessageInbox(IncomingTextMessage message, long type) {
|
||||||
if (message.isPreKeyBundle()) {
|
if (message.isPreKeyBundle()) {
|
||||||
type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
|
type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
|
||||||
|
|
|
@ -95,6 +95,22 @@ public abstract class DisplayRecord {
|
||||||
return isGroupUpdate() || isGroupQuit();
|
return isGroupUpdate() || isGroupQuit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCallLog() {
|
||||||
|
return SmsDatabase.Types.isCallLog(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIncomingCall() {
|
||||||
|
return SmsDatabase.Types.isIncomingCall(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOutgoingCall() {
|
||||||
|
return SmsDatabase.Types.isOutgoingCall(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMissedCall() {
|
||||||
|
return SmsDatabase.Types.isMissedCall(type);
|
||||||
|
}
|
||||||
|
|
||||||
public static class Body {
|
public static class Body {
|
||||||
private final String body;
|
private final String body;
|
||||||
private final boolean plaintext;
|
private final boolean plaintext;
|
||||||
|
|
|
@ -115,6 +115,12 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||||
return emphasisAdded(context.getString(R.string.MessageRecord_left_group));
|
return emphasisAdded(context.getString(R.string.MessageRecord_left_group));
|
||||||
} else if (isGroupQuit()) {
|
} else if (isGroupQuit()) {
|
||||||
return emphasisAdded(context.getString(R.string.ConversationItem_group_action_left, getIndividualRecipient().toShortString()));
|
return emphasisAdded(context.getString(R.string.ConversationItem_group_action_left, getIndividualRecipient().toShortString()));
|
||||||
|
} else if (isIncomingCall()) {
|
||||||
|
return emphasisAdded(String.format("%s called you", getIndividualRecipient().toShortString()));
|
||||||
|
} else if (isOutgoingCall()) {
|
||||||
|
return emphasisAdded(String.format("Called %s", getIndividualRecipient().toShortString()));
|
||||||
|
} else if (isMissedCall()) {
|
||||||
|
return emphasisAdded(String.format("Missed call from %s", getIndividualRecipient().toShortString()));
|
||||||
} else if (getBody().getBody().length() > MAX_DISPLAY_LENGTH) {
|
} else if (getBody().getBody().length() > MAX_DISPLAY_LENGTH) {
|
||||||
return new SpannableString(getBody().getBody().substring(0, MAX_DISPLAY_LENGTH));
|
return new SpannableString(getBody().getBody().substring(0, MAX_DISPLAY_LENGTH));
|
||||||
}
|
}
|
||||||
|
|