mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
remove dead code
This commit is contained in:
@@ -16,16 +16,11 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||
import com.google.i18n.phonenumbers.Phonenumber;
|
||||
import com.google.i18n.phonenumbers.ShortNumberInfo;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -78,29 +73,6 @@ public class Address implements Parcelable, Comparable<Address> {
|
||||
return new Address(getExternalAddressFormatter(context).format(external));
|
||||
}
|
||||
|
||||
public static @NonNull List<Address> fromSerializedList(@NonNull String serialized, char delimiter) {
|
||||
String[] escapedAddresses = DelimiterUtil.split(serialized, delimiter);
|
||||
List<Address> addresses = new LinkedList<>();
|
||||
|
||||
for (String escapedAddress : escapedAddresses) {
|
||||
addresses.add(Address.fromSerialized(DelimiterUtil.unescape(escapedAddress, delimiter)));
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public static @NonNull String toSerializedList(@NonNull List<Address> addresses, char delimiter) {
|
||||
Collections.sort(addresses);
|
||||
|
||||
List<String> escapedAddresses = new LinkedList<>();
|
||||
|
||||
for (Address address : addresses) {
|
||||
escapedAddresses.add(DelimiterUtil.escape(address.serialize(), delimiter));
|
||||
}
|
||||
|
||||
return Util.join(escapedAddresses, delimiter + "");
|
||||
}
|
||||
|
||||
private static @NonNull ExternalAddressFormatter getExternalAddressFormatter(Context context) {
|
||||
String localNumber = Prefs.getLocalNumber(context);
|
||||
|
||||
@@ -138,11 +110,6 @@ public class Address implements Parcelable, Comparable<Address> {
|
||||
|
||||
public boolean isDcContact() { return address.startsWith(DC_CONTACT_PREFIX); };
|
||||
|
||||
public @NonNull String toGroupString() {
|
||||
if (!isGroup()) throw new AssertionError("Not group: " + address);
|
||||
return address;
|
||||
}
|
||||
|
||||
public @NonNull String toPhoneString() {
|
||||
if (!isPhone()) throw new AssertionError("Not e164: " + address);
|
||||
return address;
|
||||
|
||||
@@ -16,19 +16,13 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
@@ -39,26 +33,15 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.crypto.AttachmentSecret;
|
||||
import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil.ThumbnailData;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.video.EncryptedMediaDataSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class AttachmentDatabase extends Database {
|
||||
|
||||
@@ -77,7 +60,6 @@ public class AttachmentDatabase extends Database {
|
||||
public static final String SIZE = "data_size";
|
||||
static final String FILE_NAME = "file_name";
|
||||
public static final String THUMBNAIL = "thumbnail";
|
||||
static final String THUMBNAIL_ASPECT_RATIO = "aspect_ratio";
|
||||
public static final String UNIQUE_ID = "unique_id";
|
||||
static final String DIGEST = "digest";
|
||||
static final String VOICE_NOTE = "voice_note";
|
||||
@@ -88,41 +70,12 @@ public class AttachmentDatabase extends Database {
|
||||
static final String WIDTH = "width";
|
||||
static final String HEIGHT = "height";
|
||||
|
||||
public static final String DIRECTORY = "parts";
|
||||
|
||||
public static final int TRANSFER_PROGRESS_DONE = 0;
|
||||
public static final int TRANSFER_PROGRESS_STARTED = 1;
|
||||
public static final int TRANSFER_PROGRESS_PENDING = 2;
|
||||
public static final int TRANSFER_PROGRESS_FAILED = 3;
|
||||
|
||||
private static final String PART_ID_WHERE = ROW_ID + " = ? AND " + UNIQUE_ID + " = ?";
|
||||
|
||||
private static final String[] PROJECTION = new String[] {ROW_ID,
|
||||
MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION,
|
||||
CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE,
|
||||
SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
|
||||
UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE,
|
||||
QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT};
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
|
||||
CONTENT_TYPE + " TEXT, " + NAME + " TEXT, " + "chset" + " INTEGER, " +
|
||||
CONTENT_DISPOSITION + " TEXT, " + "fn" + " TEXT, " + "cid" + " TEXT, " +
|
||||
CONTENT_LOCATION + " TEXT, " + "ctt_s" + " INTEGER, " +
|
||||
"ctt_t" + " TEXT, " + "encrypted" + " INTEGER, " +
|
||||
TRANSFER_STATE + " INTEGER, "+ DATA + " TEXT, " + SIZE + " INTEGER, " +
|
||||
FILE_NAME + " TEXT, " + THUMBNAIL + " TEXT, " + THUMBNAIL_ASPECT_RATIO + " REAL, " +
|
||||
UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " +
|
||||
VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB, " +
|
||||
QUOTE + " INTEGER DEFAULT 0, " + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
|
||||
"CREATE INDEX IF NOT EXISTS pending_push_index ON " + TABLE_NAME + " (" + TRANSFER_STATE + ");",
|
||||
};
|
||||
|
||||
private final ExecutorService thumbnailExecutor = Util.newSingleThreadedLifoExecutor();
|
||||
|
||||
private final AttachmentSecret attachmentSecret;
|
||||
|
||||
public AttachmentDatabase(Context context, SQLCipherOpenHelper databaseHelper, AttachmentSecret attachmentSecret) {
|
||||
@@ -139,52 +92,6 @@ public class AttachmentDatabase extends Database {
|
||||
else return dataStream;
|
||||
}
|
||||
|
||||
public @NonNull InputStream getThumbnailStream(@NonNull AttachmentId attachmentId)
|
||||
throws IOException
|
||||
{
|
||||
Log.w(TAG, "getThumbnailStream(" + attachmentId + ")");
|
||||
InputStream dataStream = getDataStream(attachmentId, THUMBNAIL, 0);
|
||||
|
||||
if (dataStream != null) {
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream generatedStream = thumbnailExecutor.submit(new ThumbnailFetchCallable(attachmentId)).get();
|
||||
|
||||
if (generatedStream == null) throw new FileNotFoundException("No thumbnail stream available: " + attachmentId);
|
||||
else return generatedStream;
|
||||
} catch (InterruptedException ie) {
|
||||
throw new AssertionError("interrupted");
|
||||
} catch (ExecutionException ee) {
|
||||
Log.w(TAG, ee);
|
||||
throw new IOException(ee);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable DatabaseAttachment getAttachment(@NonNull AttachmentId attachmentId)
|
||||
{
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, PROJECTION, PART_ID_WHERE, attachmentId.toStrings(), null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
List<DatabaseAttachment> list = getAttachment(cursor);
|
||||
|
||||
if (list != null && list.size() > 0) {
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@VisibleForTesting
|
||||
protected @Nullable InputStream getDataStream(AttachmentId attachmentId, String dataType, long offset)
|
||||
@@ -250,31 +157,6 @@ public class AttachmentDatabase extends Database {
|
||||
|
||||
}
|
||||
|
||||
private @NonNull DataInfo setAttachmentData(@NonNull InputStream in)
|
||||
throws MmsException
|
||||
{
|
||||
try {
|
||||
File partsDirectory = context.getDir(DIRECTORY, Context.MODE_PRIVATE);
|
||||
File dataFile = File.createTempFile("part", ".mms", partsDirectory);
|
||||
return setAttachmentData(dataFile, in);
|
||||
} catch (IOException e) {
|
||||
throw new MmsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull DataInfo setAttachmentData(@NonNull File destination, @NonNull InputStream in)
|
||||
throws MmsException
|
||||
{
|
||||
try {
|
||||
Pair<byte[], OutputStream> out = ModernEncryptingPartOutputStream.createFor(attachmentSecret, destination, false);
|
||||
long length = Util.copy(in, out.second);
|
||||
|
||||
return new DataInfo(destination, length, out.first);
|
||||
} catch (IOException e) {
|
||||
throw new MmsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<DatabaseAttachment> getAttachment(@NonNull Cursor cursor) {
|
||||
try {
|
||||
if (cursor.getColumnIndex(AttachmentDatabase.ATTACHMENT_JSON_ALIAS) != -1) {
|
||||
@@ -335,110 +217,12 @@ public class AttachmentDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@VisibleForTesting
|
||||
protected void updateAttachmentThumbnail(AttachmentId attachmentId, InputStream in, float aspectRatio)
|
||||
throws MmsException
|
||||
{
|
||||
Log.w(TAG, "updating part thumbnail for #" + attachmentId);
|
||||
|
||||
DataInfo thumbnailFile = setAttachmentData(in);
|
||||
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
ContentValues values = new ContentValues(2);
|
||||
|
||||
values.put(THUMBNAIL, thumbnailFile.file.getAbsolutePath());
|
||||
values.put(THUMBNAIL_ASPECT_RATIO, aspectRatio);
|
||||
values.put(THUMBNAIL_RANDOM, thumbnailFile.random);
|
||||
|
||||
database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings());
|
||||
|
||||
Cursor cursor = database.query(TABLE_NAME, new String[] {MMS_ID}, PART_ID_WHERE, attachmentId.toStrings(), null, null, null);
|
||||
|
||||
try {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
// notifyConversationListeners(
|
||||
// DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID))));
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
class ThumbnailFetchCallable implements Callable<InputStream> {
|
||||
|
||||
private final AttachmentId attachmentId;
|
||||
|
||||
ThumbnailFetchCallable(AttachmentId attachmentId) {
|
||||
this.attachmentId = attachmentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable InputStream call() throws Exception {
|
||||
Log.w(TAG, "Executing thumbnail job...");
|
||||
final InputStream stream = getDataStream(attachmentId, THUMBNAIL, 0);
|
||||
|
||||
if (stream != null) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
DatabaseAttachment attachment = getAttachment(attachmentId);
|
||||
|
||||
if (attachment == null || !attachment.hasData()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ThumbnailData data = null;
|
||||
|
||||
if (MediaUtil.isVideoType(attachment.getContentType())) {
|
||||
data = generateVideoThumbnail(attachmentId);
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
updateAttachmentThumbnail(attachmentId, data.toDataStream(), data.getAspectRatio());
|
||||
|
||||
return getDataStream(attachmentId, THUMBNAIL, 0);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private ThumbnailData generateVideoThumbnail(AttachmentId attachmentId) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
Log.w(TAG, "Video thumbnails not supported...");
|
||||
return null;
|
||||
}
|
||||
|
||||
DataInfo dataInfo = getAttachmentDataFileInfo(attachmentId, DATA);
|
||||
|
||||
if (dataInfo == null) {
|
||||
Log.w(TAG, "No data file found for video thumbnail...");
|
||||
return null;
|
||||
}
|
||||
|
||||
EncryptedMediaDataSource dataSource = new EncryptedMediaDataSource(attachmentSecret, dataInfo.file, dataInfo.random, dataInfo.length);
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
retriever.setDataSource(dataSource);
|
||||
|
||||
Bitmap bitmap = retriever.getFrameAtTime(1000);
|
||||
|
||||
Log.w(TAG, "Generated video thumbnail...");
|
||||
return new ThumbnailData(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataInfo {
|
||||
private final File file;
|
||||
private final long length;
|
||||
private final byte[] random;
|
||||
|
||||
private DataInfo(File file, long length, byte[] random) {
|
||||
this.file = file;
|
||||
this.length = length;
|
||||
this.random = random;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
@@ -31,15 +29,6 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
this.modelBuilder = modelBuilder;
|
||||
}
|
||||
|
||||
public static <T> CursorList<T> emptyList() {
|
||||
//noinspection ConstantConditions,unchecked
|
||||
return (CursorList<T>) new CursorList(emptyCursor(), null);
|
||||
}
|
||||
|
||||
private static Cursor emptyCursor() {
|
||||
return new MatrixCursor(new String[] { "a" }, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return cursor.getCount();
|
||||
@@ -186,14 +175,6 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerContentObserver(@NonNull ContentObserver observer) {
|
||||
cursor.registerContentObserver(observer);
|
||||
}
|
||||
|
||||
public void unregisterContentObserver(@NonNull ContentObserver observer) {
|
||||
cursor.unregisterContentObserver(observer);
|
||||
}
|
||||
|
||||
public interface ModelBuilder<T> {
|
||||
T build(@NonNull Cursor cursor);
|
||||
}
|
||||
|
||||
@@ -67,14 +67,6 @@ public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHold
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public void setHeaderView(@Nullable View header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public void setFooterView(@Nullable View footer) {
|
||||
this.footer = footer;
|
||||
}
|
||||
|
||||
public boolean hasHeaderView() {
|
||||
return header != null;
|
||||
}
|
||||
|
||||
@@ -17,22 +17,14 @@
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class Database {
|
||||
|
||||
protected static final String ID_WHERE = "_id = ?";
|
||||
private static final String CONVERSATION_URI = "content://textsecure/thread/";
|
||||
private static final String CONVERSATION_LIST_URI = "content://textsecure/conversation-list";
|
||||
private static final String ATTACHMENT_URI = "content://textsecure/attachment/";
|
||||
|
||||
protected SQLCipherOpenHelper databaseHelper;
|
||||
protected final Context context;
|
||||
|
||||
@@ -41,22 +33,10 @@ public abstract class Database {
|
||||
this.databaseHelper = databaseHelper;
|
||||
}
|
||||
|
||||
protected void notifyConversationListeners(long threadId) {
|
||||
context.getContentResolver().notifyChange(Uri.parse(CONVERSATION_URI + threadId), null);
|
||||
}
|
||||
|
||||
protected void notifyConversationListListeners() {
|
||||
context.getContentResolver().notifyChange(Uri.parse(CONVERSATION_LIST_URI), null);
|
||||
}
|
||||
|
||||
protected void setNotifyConverationListeners(Cursor cursor, long threadId) {
|
||||
cursor.setNotificationUri(context.getContentResolver(), Uri.parse(CONVERSATION_URI + threadId));
|
||||
}
|
||||
|
||||
protected void setNotifyConverationListListeners(Cursor cursor) {
|
||||
cursor.setNotificationUri(context.getContentResolver(), Uri.parse(CONVERSATION_LIST_URI));
|
||||
}
|
||||
|
||||
public void reset(SQLCipherOpenHelper databaseHelper) {
|
||||
this.databaseHelper = databaseHelper;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
|
||||
@@ -14,29 +12,10 @@ import java.util.List;
|
||||
|
||||
public class MediaDatabase extends Database {
|
||||
|
||||
private static final String BASE_MEDIA_QUERY = null;
|
||||
|
||||
private static final String GALLERY_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, AttachmentDatabase.CONTENT_TYPE + " LIKE 'image/%' OR " + AttachmentDatabase.CONTENT_TYPE + " LIKE 'video/%'");
|
||||
private static final String DOCUMENT_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'image/%' AND " + AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'video/%' AND " + AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'audio/%'");
|
||||
|
||||
MediaDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
public Cursor getGalleryMediaForThread(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = database.rawQuery(GALLERY_MEDIA_QUERY, new String[]{threadId+""});
|
||||
setNotifyConverationListeners(cursor, threadId);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public Cursor getDocumentMediaForThread(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = database.rawQuery(DOCUMENT_MEDIA_QUERY, new String[]{threadId+""});
|
||||
setNotifyConverationListeners(cursor, threadId);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public static class MediaRecord {
|
||||
|
||||
private final DatabaseAttachment attachment;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
|
||||
public abstract class MessagingDatabase extends Database implements MmsSmsColumns {
|
||||
|
||||
private static final String TAG = MessagingDatabase.class.getSimpleName();
|
||||
|
||||
public MessagingDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,30 +4,14 @@ package org.thoughtcrime.securesms.database;
|
||||
public interface MmsSmsColumns {
|
||||
|
||||
public static final String ID = "_id";
|
||||
public static final String NORMALIZED_DATE_SENT = "date_sent";
|
||||
public static final String NORMALIZED_DATE_RECEIVED = "date_received";
|
||||
public static final String THREAD_ID = "thread_id";
|
||||
public static final String READ = "read";
|
||||
public static final String BODY = "body";
|
||||
public static final String ADDRESS = "address";
|
||||
public static final String ADDRESS_DEVICE_ID = "address_device_id";
|
||||
public static final String DELIVERY_RECEIPT_COUNT = "delivery_receipt_count";
|
||||
public static final String READ_RECEIPT_COUNT = "read_receipt_count";
|
||||
public static final String MISMATCHED_IDENTITIES = "mismatched_identities";
|
||||
public static final String UNIQUE_ROW_ID = "unique_row_id";
|
||||
public static final String SUBSCRIPTION_ID = "subscription_id";
|
||||
public static final String EXPIRES_IN = "expires_in";
|
||||
public static final String EXPIRE_STARTED = "expire_started";
|
||||
public static final String NOTIFIED = "notified";
|
||||
|
||||
public static class Types {
|
||||
// Base Types
|
||||
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 JOINED_TYPE = 4;
|
||||
|
||||
protected static final long BASE_OUTBOX_TYPE = 21;
|
||||
protected static final long BASE_SENDING_TYPE = 22;
|
||||
@@ -42,36 +26,17 @@ public interface MmsSmsColumns {
|
||||
BASE_PENDING_INSECURE_SMS_FALLBACK,
|
||||
OUTGOING_CALL_TYPE};
|
||||
|
||||
// Message attributes
|
||||
protected static final long MESSAGE_FORCE_SMS_BIT = 0x40;
|
||||
|
||||
// Key Exchange Information
|
||||
protected static final long KEY_EXCHANGE_BIT = 0x8000;
|
||||
protected static final long KEY_EXCHANGE_IDENTITY_VERIFIED_BIT = 0x4000;
|
||||
protected static final long KEY_EXCHANGE_IDENTITY_DEFAULT_BIT = 0x2000;
|
||||
protected static final long KEY_EXCHANGE_CORRUPTED_BIT = 0x1000;
|
||||
protected static final long KEY_EXCHANGE_INVALID_VERSION_BIT = 0x800;
|
||||
protected static final long KEY_EXCHANGE_BUNDLE_BIT = 0x400;
|
||||
protected static final long KEY_EXCHANGE_IDENTITY_UPDATE_BIT = 0x200;
|
||||
protected static final long KEY_EXCHANGE_CONTENT_FORMAT = 0x100;
|
||||
|
||||
// Secure Message Information
|
||||
protected static final long SECURE_MESSAGE_BIT = 0x800000;
|
||||
protected static final long END_SESSION_BIT = 0x400000;
|
||||
protected static final long PUSH_MESSAGE_BIT = 0x200000;
|
||||
|
||||
// Group Message Information
|
||||
protected static final long GROUP_UPDATE_BIT = 0x10000;
|
||||
protected static final long GROUP_QUIT_BIT = 0x20000;
|
||||
protected static final long EXPIRATION_TIMER_UPDATE_BIT = 0x40000;
|
||||
|
||||
// Encrypted Storage Information XXX
|
||||
// public static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000; Deprecated
|
||||
// protected static final long ENCRYPTION_ASYMMETRIC_BIT = 0x40000000; Deprecated
|
||||
protected static final long ENCRYPTION_REMOTE_BIT = 0x20000000;
|
||||
protected static final long ENCRYPTION_REMOTE_FAILED_BIT = 0x10000000;
|
||||
protected static final long ENCRYPTION_REMOTE_NO_SESSION_BIT = 0x08000000;
|
||||
protected static final long ENCRYPTION_REMOTE_DUPLICATE_BIT = 0x04000000;
|
||||
protected static final long ENCRYPTION_REMOTE_LEGACY_BIT = 0x02000000;
|
||||
|
||||
public static boolean isFailedMessageType(long type) {
|
||||
@@ -87,10 +52,6 @@ public interface MmsSmsColumns {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isForcedSms(long type) {
|
||||
return (type & MESSAGE_FORCE_SMS_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isPendingMessageType(long type) {
|
||||
return
|
||||
(type & BASE_TYPE_MASK) == BASE_OUTBOX_TYPE ||
|
||||
@@ -101,26 +62,10 @@ public interface MmsSmsColumns {
|
||||
return (type & BASE_TYPE_MASK) == BASE_PENDING_SECURE_SMS_FALLBACK;
|
||||
}
|
||||
|
||||
public static boolean isJoinedType(long type) {
|
||||
return (type & BASE_TYPE_MASK) == JOINED_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isSecureType(long type) {
|
||||
return (type & SECURE_MESSAGE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isPushType(long type) {
|
||||
return (type & PUSH_MESSAGE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isEndSessionType(long type) {
|
||||
return (type & END_SESSION_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isKeyExchangeType(long type) {
|
||||
return (type & KEY_EXCHANGE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isIdentityVerified(long type) {
|
||||
return (type & KEY_EXCHANGE_IDENTITY_VERIFIED_BIT) != 0;
|
||||
}
|
||||
@@ -129,66 +74,6 @@ public interface MmsSmsColumns {
|
||||
return (type & KEY_EXCHANGE_IDENTITY_DEFAULT_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isCorruptedKeyExchange(long type) {
|
||||
return (type & KEY_EXCHANGE_CORRUPTED_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isInvalidVersionKeyExchange(long type) {
|
||||
return (type & KEY_EXCHANGE_INVALID_VERSION_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isBundleKeyExchange(long type) {
|
||||
return (type & KEY_EXCHANGE_BUNDLE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isContentBundleKeyExchange(long type) {
|
||||
return (type & KEY_EXCHANGE_CONTENT_FORMAT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isIdentityUpdate(long type) {
|
||||
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 isExpirationTimerUpdate(long type) {
|
||||
return (type & EXPIRATION_TIMER_UPDATE_BIT) != 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
return (type & GROUP_UPDATE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isGroupQuit(long type) {
|
||||
return (type & GROUP_QUIT_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isFailedDecryptType(long type) {
|
||||
return (type & ENCRYPTION_REMOTE_FAILED_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isDuplicateMessageType(long type) {
|
||||
return (type & ENCRYPTION_REMOTE_DUPLICATE_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isNoRemoteSessionType(long type) {
|
||||
return (type & ENCRYPTION_REMOTE_NO_SESSION_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isLegacyType(long type) {
|
||||
return (type & ENCRYPTION_REMOTE_LEGACY_BIT) != 0 ||
|
||||
(type & ENCRYPTION_REMOTE_BIT) != 0;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
|
||||
public class NetworkFailure {
|
||||
|
||||
@JsonProperty(value = "a")
|
||||
private String address;
|
||||
|
||||
public NetworkFailure(Address address) {
|
||||
this.address = address.serialize();
|
||||
}
|
||||
|
||||
public NetworkFailure() {}
|
||||
|
||||
@JsonIgnore
|
||||
public Address getAddress() {
|
||||
return Address.fromSerialized(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof NetworkFailure)) return false;
|
||||
|
||||
NetworkFailure that = (NetworkFailure)other;
|
||||
return this.address.equals(that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkFailureList implements Document<NetworkFailure> {
|
||||
|
||||
@JsonProperty(value = "l")
|
||||
private List<NetworkFailure> failures;
|
||||
|
||||
public NetworkFailureList() {
|
||||
this.failures = new LinkedList<>();
|
||||
}
|
||||
|
||||
public NetworkFailureList(List<NetworkFailure> failures) {
|
||||
this.failures = failures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if (failures == null) return 0;
|
||||
else return failures.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public List<NetworkFailure> getList() {
|
||||
return failures;
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,10 @@ import org.thoughtcrime.securesms.util.AbstractCursorLoader;
|
||||
public class ThreadMediaLoader extends AbstractCursorLoader {
|
||||
|
||||
private final Address address;
|
||||
private final boolean gallery;
|
||||
|
||||
public ThreadMediaLoader(@NonNull Context context, @NonNull Address address, boolean gallery) {
|
||||
super(context);
|
||||
this.address = address;
|
||||
this.gallery = gallery;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,9 +41,6 @@ public abstract class DisplayRecord {
|
||||
private final long dateReceived;
|
||||
private final long threadId;
|
||||
private final String body;
|
||||
private final int deliveryStatus;
|
||||
private final int deliveryReceiptCount;
|
||||
private final int readReceiptCount;
|
||||
|
||||
DisplayRecord(Context context, String body, Recipient recipient, long dateSent,
|
||||
long dateReceived, long threadId, int deliveryStatus, int deliveryReceiptCount,
|
||||
@@ -56,9 +53,6 @@ public abstract class DisplayRecord {
|
||||
this.dateReceived = dateReceived;
|
||||
this.type = type;
|
||||
this.body = body;
|
||||
this.deliveryReceiptCount = deliveryReceiptCount;
|
||||
this.readReceiptCount = readReceiptCount;
|
||||
this.deliveryStatus = deliveryStatus;
|
||||
}
|
||||
|
||||
public @NonNull String getBody() {
|
||||
@@ -102,10 +96,6 @@ public abstract class DisplayRecord {
|
||||
return threadId;
|
||||
}
|
||||
|
||||
public boolean isKeyExchange() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEndSession() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2012 Moxie Marlinspike
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.SpannableString;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the message record model for MMS messages that contain
|
||||
* media (ie: they've been downloaded).
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
|
||||
public class MediaMmsMessageRecord extends MmsMessageRecord {
|
||||
private final static String TAG = MediaMmsMessageRecord.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private final int partCount;
|
||||
|
||||
public MediaMmsMessageRecord(Context context, long id, Recipient conversationRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived, int deliveryReceiptCount,
|
||||
long threadId, String body,
|
||||
@NonNull SlideDeck slideDeck,
|
||||
int partCount, long mailbox,
|
||||
List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> failures, int subscriptionId,
|
||||
long expiresIn, long expireStarted, int readReceiptCount,
|
||||
@Nullable Quote quote, @Nullable List<Contact> contacts)
|
||||
{
|
||||
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent,
|
||||
dateReceived, threadId, 0, deliveryReceiptCount, mailbox, mismatches, failures,
|
||||
subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount, quote, contacts);
|
||||
|
||||
this.context = context.getApplicationContext();
|
||||
this.partCount = partCount;
|
||||
}
|
||||
|
||||
public int getPartCount() {
|
||||
return partCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMmsNotification() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpannableString getDisplayBody() {
|
||||
if (isLegacyMessage()) {
|
||||
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
|
||||
}
|
||||
|
||||
return super.getDisplayBody();
|
||||
}
|
||||
}
|
||||
@@ -17,20 +17,13 @@
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.ExpirationUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The base class for message record models that are displayed in
|
||||
* conversations, as opposed to models that are displayed in a thread list.
|
||||
@@ -44,10 +37,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
private static final int MAX_DISPLAY_LENGTH = 2000;
|
||||
|
||||
private final Recipient individualRecipient;
|
||||
private final int recipientDeviceId;
|
||||
private final long id;
|
||||
private final List<IdentityKeyMismatch> mismatches;
|
||||
private final List<NetworkFailure> networkFailures;
|
||||
private final int subscriptionId;
|
||||
private final long expiresIn;
|
||||
private final long expireStarted;
|
||||
@@ -56,8 +46,6 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived, long threadId,
|
||||
int deliveryStatus, int deliveryReceiptCount, long type,
|
||||
List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> networkFailures,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount)
|
||||
{
|
||||
@@ -65,25 +53,17 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
threadId, deliveryStatus, deliveryReceiptCount, type, readReceiptCount);
|
||||
this.id = id;
|
||||
this.individualRecipient = individualRecipient;
|
||||
this.recipientDeviceId = recipientDeviceId;
|
||||
this.mismatches = mismatches;
|
||||
this.networkFailures = networkFailures;
|
||||
this.subscriptionId = subscriptionId;
|
||||
this.expiresIn = expiresIn;
|
||||
this.expireStarted = expireStarted;
|
||||
}
|
||||
|
||||
public abstract boolean isMms();
|
||||
public abstract boolean isMmsNotification();
|
||||
|
||||
public boolean isSecure() {
|
||||
return MmsSmsColumns.Types.isSecureType(type);
|
||||
}
|
||||
|
||||
public boolean isLegacyMessage() {
|
||||
return MmsSmsColumns.Types.isLegacyType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpannableString getDisplayBody() {
|
||||
if (isGroupUpdate() && isOutgoing()) {
|
||||
@@ -147,51 +127,23 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBundleKeyExchange() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isIdentityUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCorruptedKeyExchange() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isInvalidVersionKeyExchange() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return isGroupAction() || isJoined() || isExpirationTimerUpdate() || isCallLog() ||
|
||||
isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault();
|
||||
}
|
||||
|
||||
public boolean isMediaPending() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Recipient getIndividualRecipient() {
|
||||
return individualRecipient;
|
||||
}
|
||||
|
||||
public int getRecipientDeviceId() {
|
||||
return recipientDeviceId;
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
protected SpannableString emphasisAdded(String sequence) {
|
||||
SpannableString spannable = new SpannableString(sequence);
|
||||
spannable.setSpan(new RelativeSizeSpan(0.9f), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
spannable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
return spannable;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return other != null &&
|
||||
other instanceof MessageRecord &&
|
||||
@@ -203,15 +155,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return (int)getId();
|
||||
}
|
||||
|
||||
public int getSubscriptionId() {
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
public long getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public long getExpireStarted() {
|
||||
return expireStarted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MmsMessageRecord extends MessageRecord {
|
||||
|
||||
private final @NonNull SlideDeck slideDeck;
|
||||
private final @Nullable Quote quote;
|
||||
private final @NonNull List<Contact> contacts = new LinkedList<>();
|
||||
|
||||
MmsMessageRecord(Context context, long id, String body, Recipient conversationRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId, long dateSent,
|
||||
long dateReceived, long threadId, int deliveryStatus, int deliveryReceiptCount,
|
||||
long type, List<IdentityKeyMismatch> mismatches,
|
||||
List<NetworkFailure> networkFailures, int subscriptionId, long expiresIn,
|
||||
long expireStarted, @NonNull SlideDeck slideDeck, int readReceiptCount,
|
||||
@Nullable Quote quote, @NonNull List<Contact> contacts)
|
||||
{
|
||||
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount);
|
||||
|
||||
this.slideDeck = slideDeck;
|
||||
this.quote = quote;
|
||||
|
||||
this.contacts.addAll(contacts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMms() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public SlideDeck getSlideDeck() {
|
||||
return slideDeck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMediaPending() {
|
||||
for (Slide slide : getSlideDeck().getSlides()) {
|
||||
if (slide.isInProgress() || slide.isPendingDownload()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsMediaSlide() {
|
||||
return slideDeck.containsMediaSlide();
|
||||
}
|
||||
|
||||
public @Nullable Quote getQuote() {
|
||||
return quote;
|
||||
}
|
||||
|
||||
public @NonNull List<Contact> getSharedContacts() {
|
||||
return contacts;
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Moxie Marlinspike
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.SpannableString;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Represents the message record model for MMS messages that are
|
||||
* notifications (ie: they're pointers to undownloaded media).
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
|
||||
public class NotificationMmsMessageRecord extends MmsMessageRecord {
|
||||
|
||||
private final byte[] contentLocation;
|
||||
private final long messageSize;
|
||||
private final long expiry;
|
||||
private final int status;
|
||||
private final byte[] transactionId;
|
||||
|
||||
public NotificationMmsMessageRecord(Context context, long id, Recipient conversationRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
long dateSent, long dateReceived, int deliveryReceiptCount,
|
||||
long threadId, byte[] contentLocation, long messageSize,
|
||||
long expiry, int status, byte[] transactionId, long mailbox,
|
||||
int subscriptionId, SlideDeck slideDeck, int readReceiptCount)
|
||||
{
|
||||
super(context, id, "", conversationRecipient, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, 0, deliveryReceiptCount, mailbox,
|
||||
new LinkedList<IdentityKeyMismatch>(), new LinkedList<NetworkFailure>(), subscriptionId,
|
||||
0, 0, slideDeck, readReceiptCount, null, Collections.emptyList());
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
this.expiry = expiry;
|
||||
this.status = status;
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public byte[] getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public byte[] getContentLocation() {
|
||||
return contentLocation;
|
||||
}
|
||||
|
||||
public long getMessageSize() {
|
||||
return (messageSize + 1023) / 1024;
|
||||
}
|
||||
|
||||
public long getExpiration() {
|
||||
return expiry * 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOutgoing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPending() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMmsNotification() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMediaPending() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpannableString getDisplayBody() {
|
||||
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
|
||||
public class Quote {
|
||||
|
||||
private final long id;
|
||||
private final Address author;
|
||||
private final String text;
|
||||
private final SlideDeck attachment;
|
||||
|
||||
public Quote(long id, @NonNull Address author, @Nullable String text, @NonNull SlideDeck attachment) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public @NonNull Address getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public @Nullable String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public @NonNull SlideDeck getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Moxie Marlinspike
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.SpannableString;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The message record model which represents standard SMS messages.
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
|
||||
public class SmsMessageRecord extends MessageRecord {
|
||||
|
||||
public SmsMessageRecord(Context context, long id,
|
||||
String body, Recipient recipient,
|
||||
Recipient individualRecipient,
|
||||
int recipientDeviceId,
|
||||
long dateSent, long dateReceived,
|
||||
int deliveryReceiptCount,
|
||||
long type, long threadId,
|
||||
int status, List<IdentityKeyMismatch> mismatches,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount)
|
||||
{
|
||||
super(context, id, body, recipient, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, threadId, status, deliveryReceiptCount, type,
|
||||
mismatches, new LinkedList<>(), subscriptionId,
|
||||
expiresIn, expireStarted, readReceiptCount);
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpannableString getDisplayBody() {
|
||||
if (isCorruptedKeyExchange()) {
|
||||
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_corrupted_key_exchange_message));
|
||||
} else if (isInvalidVersionKeyExchange()) {
|
||||
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_key_exchange_message_for_invalid_protocol_version));
|
||||
} else if (MmsSmsColumns.Types.isLegacyType(type)) {
|
||||
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
|
||||
} else if (isBundleKeyExchange()) {
|
||||
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_message_with_new_safety_number_tap_to_process));
|
||||
} else if (isKeyExchange() && isOutgoing()) {
|
||||
return new SpannableString("");
|
||||
} else if (isKeyExchange() && !isOutgoing()) {
|
||||
return emphasisAdded(context.getString(R.string.ConversationItem_received_key_exchange_message_tap_to_process));
|
||||
} else if (isEndSession() && isOutgoing()) {
|
||||
return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset));
|
||||
} else if (isEndSession()) {
|
||||
return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset_s, getIndividualRecipient().toShortString()));
|
||||
} else {
|
||||
return super.getDisplayBody();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMms() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMmsNotification() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user