diff --git a/src/com/b44t/messenger/DcMsg.java b/src/com/b44t/messenger/DcMsg.java index 72da29cb5..2d039b79e 100644 --- a/src/com/b44t/messenger/DcMsg.java +++ b/src/com/b44t/messenger/DcMsg.java @@ -1,9 +1,6 @@ package com.b44t.messenger; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import org.thoughtcrime.securesms.database.model.Quote; import java.io.File; import java.util.Set; @@ -161,12 +158,6 @@ public class DcMsg { public boolean isIdentityVerified() { return false; } public boolean isIdentityDefault() { return false; } - @Nullable - public Quote getQuote() { - // TODO: remove the dependency to org.thoughtcrime.securesms.database.model.Quote - return null; - } - // working with raw c-data private long msgCPtr; // CAVE: the name is referenced in the JNI private native void unrefMsgCPtr (); diff --git a/src/org/thoughtcrime/securesms/MediaOverviewActivity.java b/src/org/thoughtcrime/securesms/MediaOverviewActivity.java index eeda96ddb..f08e13527 100644 --- a/src/org/thoughtcrime/securesms/MediaOverviewActivity.java +++ b/src/org/thoughtcrime/securesms/MediaOverviewActivity.java @@ -421,10 +421,11 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity @Override public void onLoadFinished(Loader loader, Cursor data) { - ((CursorRecyclerViewAdapter)this.recyclerView.getAdapter()).changeCursor(data); + //((CursorRecyclerViewAdapter)this.recyclerView.getAdapter()).changeCursor(data); getActivity().invalidateOptionsMenu(); - this.noMedia.setVisibility(data.getCount() > 0 ? View.GONE : View.VISIBLE); + // TODO: onLoadFinished() should no take a cursor but forward the loaded messages in a way + this.noMedia.setVisibility(/*data.getCount() > 0 ?*/ View.GONE /*: View.VISIBLE*/); } @Override diff --git a/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java b/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java deleted file mode 100644 index 0011af6c9..000000000 --- a/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.thoughtcrime.securesms.attachments; - - -import android.net.Uri; -import android.support.annotation.Nullable; - -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.MmsDatabase; - -public class MmsNotificationAttachment extends Attachment { - - public MmsNotificationAttachment(int status, long size) { - super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false); - } - - @Nullable - @Override - public Uri getDataUri() { - return null; - } - - @Nullable - @Override - public Uri getThumbnailUri() { - return null; - } - - private static int getTransferStateFromStatus(int status) { - if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED || - status == MmsDatabase.Status.DOWNLOAD_NO_CONNECTIVITY) - { - return AttachmentDatabase.TRANSFER_PROGRESS_PENDING; - } else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) { - return AttachmentDatabase.TRANSFER_PROGRESS_STARTED; - } else { - return AttachmentDatabase.TRANSFER_PROGRESS_FAILED; - } - } -} diff --git a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java index b4140f02b..98ca1f1e4 100644 --- a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java +++ b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java @@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientProvider; @@ -236,7 +235,7 @@ public class ApplicationDcContext extends DcContext { @NonNull public ThreadRecord getThreadRecord(DcLot summary, DcChat chat) { // adapted from ThreadDatabase.getCurrent() int chatId = chat.getId(); - int distributionType = chatId == DcChat.DC_CHAT_ID_ARCHIVED_LINK ? ThreadDatabase.DistributionTypes.ARCHIVE : ThreadDatabase.DistributionTypes.CONVERSATION; + int distributionType = chatId == DcChat.DC_CHAT_ID_ARCHIVED_LINK ? ThreadRecord.DistributionTypes.ARCHIVE : ThreadRecord.DistributionTypes.CONVERSATION; String body = summary.getText1(); if (!body.isEmpty()) { diff --git a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java index 5ee0674ba..e8cd32879 100644 --- a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java @@ -16,31 +16,18 @@ */ package org.thoughtcrime.securesms.contacts; -import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; -import android.database.MergeCursor; -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.telephony.PhoneNumberUtils; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.util.Hash; import org.thoughtcrime.securesms.util.Prefs; import java.util.ArrayList; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; -import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; - /** * This class was originally a layer of indirection between * ContactAccessorNewApi and ContactAccesorOldApi, which corresponded @@ -97,245 +84,4 @@ public class ContactAccessor { Prefs.setSystemContactPhotos(context, contactPhotoIdentifiers); return result.toString(); } - - public String getNameFromContact(Context context, Uri uri) { - Cursor cursor = null; - - try { - cursor = context.getContentResolver().query(uri, new String[] {Contacts.DISPLAY_NAME}, - null, null, null); - - if (cursor != null && cursor.moveToFirst()) - return cursor.getString(0); - - } finally { - if (cursor != null) - cursor.close(); - } - - return null; - } - - public ContactData getContactData(Context context, Uri uri) { - return getContactData(context, getNameFromContact(context, uri), Long.parseLong(uri.getLastPathSegment())); - } - - private ContactData getContactData(Context context, String displayName, long id) { - ContactData contactData = new ContactData(id, displayName); - Cursor mailCursor = null; - - try { - mailCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, - Phone.CONTACT_ID + " = ?", - new String[] {contactData.id + ""}, null); - - while (mailCursor != null && mailCursor.moveToNext()) { - int type = mailCursor.getInt(mailCursor.getColumnIndexOrThrow(Phone.TYPE)); - String label = mailCursor.getString(mailCursor.getColumnIndexOrThrow(Phone.LABEL)); - String number = mailCursor.getString(mailCursor.getColumnIndexOrThrow(Phone.NUMBER)); - String typeLabel = Phone.getTypeLabel(context.getResources(), type, label).toString(); - - contactData.mails.add(new NumberData(typeLabel, number)); - } - } finally { - if (mailCursor != null) - mailCursor.close(); - } - - return contactData; - } - - public List getNumbersForThreadSearchFilter(Context context, String constraint) { - LinkedList numberList = new LinkedList<>(); - Cursor cursor = null; - - try { - cursor = context.getContentResolver().query(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, - Uri.encode(constraint)), - null, null, null, null); - - while (cursor != null && cursor.moveToNext()) { - numberList.add(cursor.getString(cursor.getColumnIndexOrThrow(Phone.NUMBER))); - } - - } finally { - if (cursor != null) - cursor.close(); - } - - GroupDatabase.Reader reader = null; - GroupRecord record; - - try { - reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint); - - while ((record = reader.getNext()) != null) { - numberList.add(record.getEncodedId()); - } - } finally { - if (reader != null) - reader.close(); - } - - return numberList; - } - - public CharSequence phoneTypeToString(Context mContext, int type, CharSequence label) { - return Phone.getTypeLabel(mContext.getResources(), type, label); - } - - public static class NumberData implements Parcelable { - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public NumberData createFromParcel(Parcel in) { - return new NumberData(in); - } - - public NumberData[] newArray(int size) { - return new NumberData[size]; - } - }; - - public final String mail; - public final String type; - - public NumberData(String type, String number) { - this.type = type; - this.mail = number; - } - - public NumberData(Parcel in) { - mail = in.readString(); - type = in.readString(); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mail); - dest.writeString(type); - } - } - - public static class ContactData implements Parcelable { - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public ContactData createFromParcel(Parcel in) { - return new ContactData(in); - } - - public ContactData[] newArray(int size) { - return new ContactData[size]; - } - }; - - public final long id; - public final String name; - public final List mails; - - public ContactData(long id, String name) { - this.id = id; - this.name = name; - this.mails = new LinkedList<>(); - } - - public ContactData(Parcel in) { - id = in.readLong(); - name = in.readString(); - mails = new LinkedList<>(); - - in.readTypedList(mails, NumberData.CREATOR); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(id); - dest.writeString(name); - dest.writeTypedList(mails); - } - } - - /*** - * If the code below looks shitty to you, that's because it was taken - * directly from the Android source, where shitty code is all you get. - */ - - public Cursor getCursorForRecipientFilter(CharSequence constraint, - ContentResolver mContentResolver) - { - final String SORT_ORDER = Contacts.TIMES_CONTACTED + " DESC," + - Contacts.DISPLAY_NAME + "," + - Contacts.Data.IS_SUPER_PRIMARY + " DESC," + - Phone.TYPE; - - final String[] PROJECTION_PHONE = { - Phone._ID, // 0 - Phone.CONTACT_ID, // 1 - Phone.TYPE, // 2 - Phone.NUMBER, // 3 - Phone.LABEL, // 4 - Phone.DISPLAY_NAME, // 5 - }; - - String phone = ""; - String cons = null; - - if (constraint != null) { - cons = constraint.toString(); - - if (RecipientsAdapter.usefulAsDigits(cons)) { - phone = PhoneNumberUtils.convertKeypadLettersToDigits(cons); - if (phone.equals(cons) && !PhoneNumberUtils.isWellFormedSmsAddress(phone)) { - phone = ""; - } else { - phone = phone.trim(); - } - } - } - Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(cons)); - String selection = String.format("%s=%s OR %s=%s OR %s=%s", - Phone.TYPE, - Phone.TYPE_MOBILE, - Phone.TYPE, - Phone.TYPE_WORK_MOBILE, - Phone.TYPE, - Phone.TYPE_MMS); - - Cursor phoneCursor = mContentResolver.query(uri, - PROJECTION_PHONE, - null, - null, - SORT_ORDER); - - if (phone.length() > 0) { - ArrayList result = new ArrayList(); - result.add(Integer.valueOf(-1)); // ID - result.add(Long.valueOf(-1)); // CONTACT_ID - result.add(Integer.valueOf(Phone.TYPE_CUSTOM)); // TYPE - result.add(phone); // NUMBER - - /* - * The "\u00A0" keeps Phone.getDisplayLabel() from deciding - * to display the default label ("Home") next to the transformation - * of the letters into numbers. - */ - result.add("\u00A0"); // LABEL - result.add(cons); // NAME - - ArrayList wrap = new ArrayList(); - wrap.add(result); - - ArrayListCursor translated = new ArrayListCursor(PROJECTION_PHONE, wrap); - - return new MergeCursor(new Cursor[] { translated, phoneCursor }); - } else { - return phoneCursor; - } - } - } diff --git a/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java b/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java deleted file mode 100644 index 32337abac..000000000 --- a/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thoughtcrime.securesms.contacts; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.recipients.RecipientsFormatter; - -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.text.Annotation; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.TextUtils; -import android.view.View; -import android.widget.ResourceCursorAdapter; -import android.widget.TextView; - -/** - * This adapter is used to filter contacts on both name and number. - */ -public class RecipientsAdapter extends ResourceCursorAdapter { - - public static final int CONTACT_ID_INDEX = 1; - public static final int TYPE_INDEX = 2; - public static final int NUMBER_INDEX = 3; - public static final int LABEL_INDEX = 4; - public static final int NAME_INDEX = 5; - - private final Context mContext; - private final ContentResolver mContentResolver; - private ContactAccessor mContactAccessor; - - public RecipientsAdapter(Context context) { - super(context, R.layout.recipient_filter_item, null); - mContext = context; - mContentResolver = context.getContentResolver(); - mContactAccessor = ContactAccessor.getInstance(); - } - - @Override - public final CharSequence convertToString(Cursor cursor) { - String name = cursor.getString(RecipientsAdapter.NAME_INDEX); - int type = cursor.getInt(RecipientsAdapter.TYPE_INDEX); - String number = cursor.getString(RecipientsAdapter.NUMBER_INDEX).trim(); - - String label = cursor.getString(RecipientsAdapter.LABEL_INDEX); - CharSequence displayLabel = mContactAccessor.phoneTypeToString(mContext, type, label); - - if (number.length() == 0) { - return number; - } - - if (name == null) { - name = ""; - } else { - // Names with commas are the bane of the recipient editor's existence. - // We've worked around them by using spans, but there are edge cases - // where the spans get deleted. Furthermore, having commas in names - // can be confusing to the user since commas are used as separators - // between recipients. The best solution is to simply remove commas - // from names. - name = name.replace(", ", " ") - .replace(",", " "); // Make sure we leave a space between parts of names. - } - - String nameAndNumber = RecipientsFormatter.formatNameAndNumber(name, number); - - SpannableString out = new SpannableString(nameAndNumber); - int len = out.length(); - - if (!TextUtils.isEmpty(name)) { - out.setSpan(new Annotation("name", name), 0, len, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } else { - out.setSpan(new Annotation("name", number), 0, len, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - - String person_id = cursor.getString(RecipientsAdapter.CONTACT_ID_INDEX); - out.setSpan(new Annotation("person_id", person_id), 0, len, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - out.setSpan(new Annotation("label", displayLabel.toString()), 0, len, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - out.setSpan(new Annotation("number", number), 0, len, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - - return out; - } - - @Override - public final void bindView(View view, Context context, Cursor cursor) { - TextView name = (TextView) view.findViewById(R.id.name); - name.setText(cursor.getString(NAME_INDEX)); - - TextView label = (TextView) view.findViewById(R.id.label); - int type = cursor.getInt(TYPE_INDEX); - label.setText(mContactAccessor.phoneTypeToString(mContext, type, cursor.getString(LABEL_INDEX))); - - TextView number = (TextView) view.findViewById(R.id.number); - number.setText("(" + cursor.getString(NUMBER_INDEX) + ")"); - } - - @Override - public Cursor runQueryOnBackgroundThread(CharSequence constraint) { - return mContactAccessor.getCursorForRecipientFilter( constraint, mContentResolver ); - } - - /** - * Returns true if all the characters are meaningful as digits - * in a phone number -- letters, digits, and a few punctuation marks. - */ - public static boolean usefulAsDigits(CharSequence cons) { - int len = cons.length(); - - for (int i = 0; i < len; i++) { - char c = cons.charAt(i); - - if ((c >= '0') && (c <= '9')) { - continue; - } - if ((c == ' ') || (c == '-') || (c == '(') || (c == ')') || (c == '.') || (c == '+') - || (c == '#') || (c == '*')) { - continue; - } - if ((c >= 'A') && (c <= 'Z')) { - continue; - } - if ((c >= 'a') && (c <= 'z')) { - continue; - } - - return false; - } - - return true; - } -} diff --git a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 0750d812e..6cf25bf31 100644 --- a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -358,7 +358,8 @@ public class AttachmentDatabase extends Database { try { if (cursor != null && cursor.moveToFirst()) { - notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)))); +// notifyConversationListeners( +// DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)))); } } finally { if (cursor != null) cursor.close(); diff --git a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java index f62120741..e5c77eb4e 100644 --- a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -34,14 +34,7 @@ public class DatabaseFactory { private static DatabaseFactory instance; private final SQLCipherOpenHelper databaseHelper; - private final SmsDatabase sms; - private final MmsDatabase mms; private final AttachmentDatabase attachments; - private final MediaDatabase media; - private final ThreadDatabase thread; - private final MmsSmsDatabase mmsSmsDatabase; - private final GroupDatabase groupDatabase; - private final RecipientDatabase recipientDatabase; public static DatabaseFactory getInstance(Context context) { synchronized (lock) { @@ -51,39 +44,10 @@ public class DatabaseFactory { return instance; } } - - public static MmsSmsDatabase getMmsSmsDatabase(Context context) { - return getInstance(context).mmsSmsDatabase; - } - - public static ThreadDatabase getThreadDatabase(Context context) { - return getInstance(context).thread; - } - - public static SmsDatabase getSmsDatabase(Context context) { - return getInstance(context).sms; - } - - public static MmsDatabase getMmsDatabase(Context context) { - return getInstance(context).mms; - } - public static AttachmentDatabase getAttachmentDatabase(Context context) { return getInstance(context).attachments; } - public static MediaDatabase getMediaDatabase(Context context) { - return getInstance(context).media; - } - - public static GroupDatabase getGroupDatabase(Context context) { - return getInstance(context).groupDatabase; - } - - public static RecipientDatabase getRecipientDatabase(Context context) { - return getInstance(context).recipientDatabase; - } - private DatabaseFactory(@NonNull Context context) { SQLiteDatabase.loadLibs(context); @@ -91,16 +55,6 @@ public class DatabaseFactory { AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(); this.databaseHelper = new SQLCipherOpenHelper(context, databaseSecret); - this.sms = new SmsDatabase(context, databaseHelper); - this.mms = new MmsDatabase(context, databaseHelper); this.attachments = new AttachmentDatabase(context, databaseHelper, attachmentSecret); - this.media = new MediaDatabase(context, databaseHelper); - this.thread = new ThreadDatabase(context, databaseHelper); - this.mmsSmsDatabase = new MmsSmsDatabase(context, databaseHelper); - this.groupDatabase = new GroupDatabase(context, databaseHelper); - this.recipientDatabase = new RecipientDatabase(context, databaseHelper); } - - - } diff --git a/src/org/thoughtcrime/securesms/database/GroupDatabase.java b/src/org/thoughtcrime/securesms/database/GroupDatabase.java deleted file mode 100644 index ec94aad7b..000000000 --- a/src/org/thoughtcrime/securesms/database/GroupDatabase.java +++ /dev/null @@ -1,240 +0,0 @@ -package org.thoughtcrime.securesms.database; - - -import android.annotation.SuppressLint; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.support.annotation.Nullable; -import android.text.TextUtils; - -import com.annimon.stream.Stream; - -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.thoughtcrime.securesms.util.guava.Optional; - -import java.io.Closeable; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -public class GroupDatabase extends Database { - - @SuppressWarnings("unused") - private static final String TAG = GroupDatabase.class.getSimpleName(); - - static final String TABLE_NAME = "groups"; - private static final String ID = "_id"; - static final String GROUP_ID = "group_id"; - private static final String TITLE = "title"; - private static final String MEMBERS = "members"; - private static final String AVATAR = "avatar"; - private static final String AVATAR_ID = "avatar_id"; - private static final String AVATAR_KEY = "avatar_key"; - private static final String AVATAR_CONTENT_TYPE = "avatar_content_type"; - private static final String AVATAR_RELAY = "avatar_relay"; - private static final String AVATAR_DIGEST = "avatar_digest"; - private static final String TIMESTAMP = "timestamp"; - private static final String ACTIVE = "active"; - private static final String MMS = "mms"; - - public static final String CREATE_TABLE = - "CREATE TABLE " + TABLE_NAME + - " (" + ID + " INTEGER PRIMARY KEY, " + - GROUP_ID + " TEXT, " + - TITLE + " TEXT, " + - MEMBERS + " TEXT, " + - AVATAR + " BLOB, " + - AVATAR_ID + " INTEGER, " + - AVATAR_KEY + " BLOB, " + - AVATAR_CONTENT_TYPE + " TEXT, " + - AVATAR_RELAY + " TEXT, " + - TIMESTAMP + " INTEGER, " + - ACTIVE + " INTEGER DEFAULT 1, " + - AVATAR_DIGEST + " BLOB, " + - MMS + " INTEGER DEFAULT 0);"; - - public static final String[] CREATE_INDEXS = { - "CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON " + TABLE_NAME + " (" + GROUP_ID + ");", - }; - - private static final String[] GROUP_PROJECTION = { - GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST, - TIMESTAMP, ACTIVE, MMS - }; - - static final List TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList(); - - public GroupDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } - - public Optional getGroup(String groupId) { - try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, GROUP_ID + " = ?", - new String[] {groupId}, - null, null, null)) - { - if (cursor != null && cursor.moveToNext()) { - return getGroup(cursor); - } - - return Optional.absent(); - } - } - - Optional getGroup(Cursor cursor) { - Reader reader = new Reader(cursor); - return Optional.fromNullable(reader.getCurrent()); - } - - public Reader getGroupsFilteredByTitle(String constraint) { - @SuppressLint("Recycle") - Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, TITLE + " LIKE ?", - new String[]{"%" + constraint + "%"}, - null, null, null); - - return new Reader(cursor); - } - - public Reader getGroups() { - @SuppressLint("Recycle") - Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null); - return new Reader(cursor); - } - - public void remove(String groupId, Address source) { - List
currentMembers = getCurrentMembers(groupId); - currentMembers.remove(source); - - ContentValues contents = new ContentValues(); - contents.put(MEMBERS, Address.toSerializedList(currentMembers, ',')); - - databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", - new String[] {groupId}); - } - - private List
getCurrentMembers(String groupId) { - Cursor cursor = null; - - try { - cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {MEMBERS}, - GROUP_ID + " = ?", - new String[] {groupId}, - null, null, null); - - if (cursor != null && cursor.moveToFirst()) { - String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)); - return Address.fromSerializedList(serializedMembers, ','); - } - - return new LinkedList<>(); - } finally { - if (cursor != null) - cursor.close(); - } - } - - public static class Reader implements Closeable { - - private final Cursor cursor; - - public Reader(Cursor cursor) { - this.cursor = cursor; - } - - public @Nullable GroupRecord getNext() { - if (cursor == null || !cursor.moveToNext()) { - return null; - } - - return getCurrent(); - } - - public @Nullable GroupRecord getCurrent() { - if (cursor == null || cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)) == null) { - return null; - } - - return new GroupRecord(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)), - cursor.getString(cursor.getColumnIndexOrThrow(TITLE)), - cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)), - cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR)), - cursor.getLong(cursor.getColumnIndexOrThrow(AVATAR_ID)), - cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR_KEY)), - cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_CONTENT_TYPE)), - cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_RELAY)), - cursor.getInt(cursor.getColumnIndexOrThrow(ACTIVE)) == 1, - cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR_DIGEST)), - cursor.getInt(cursor.getColumnIndexOrThrow(MMS)) == 1); - } - - @Override - public void close() { - if (this.cursor != null) - this.cursor.close(); - } - } - - public static class GroupRecord { - - private final String id; - private final String title; - private final List
members; - private final byte[] avatar; - private final long avatarId; - private final boolean active; - private final boolean mms; - - public GroupRecord(String id, String title, String members, byte[] avatar, - long avatarId, byte[] avatarKey, String avatarContentType, - String relay, boolean active, byte[] avatarDigest, boolean mms) - { - this.id = id; - this.title = title; - this.avatar = avatar; - this.avatarId = avatarId; - this.active = active; - this.mms = mms; - - if (!TextUtils.isEmpty(members)) this.members = Address.fromSerializedList(members, ','); - else this.members = new LinkedList<>(); - } - - public byte[] getId() { - try { - return GroupUtil.getDecodedId(id); - } catch (IOException ioe) { - throw new AssertionError(ioe); - } - } - - public String getEncodedId() { - return id; - } - - public String getTitle() { - return title; - } - - public List
getMembers() { - return members; - } - - public byte[] getAvatar() { - return avatar; - } - - public long getAvatarId() { - return avatarId; - } - - public boolean isActive() { - return active; - } - - public boolean isMms() { - return mms; - } - } -} diff --git a/src/org/thoughtcrime/securesms/database/MediaDatabase.java b/src/org/thoughtcrime/securesms/database/MediaDatabase.java index ec582354f..d6e95d7f3 100644 --- a/src/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -14,36 +14,7 @@ import java.util.List; public class MediaDatabase extends Database { - private static final String BASE_MEDIA_QUERY = "SELECT " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ROW_ID + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_TYPE + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL_ASPECT_RATIO + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFER_STATE + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.SIZE + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FILE_NAME + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DATA + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_LOCATION + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DIGEST + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.QUOTE + ", " - + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " - + MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", " - + MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", " - + MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + ", " - + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ADDRESS + " " - + "FROM " + AttachmentDatabase.TABLE_NAME + " LEFT JOIN " + MmsDatabase.TABLE_NAME - + " ON " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " - + "WHERE " + AttachmentDatabase.MMS_ID + " IN (SELECT " + MmsSmsColumns.ID - + " FROM " + MmsDatabase.TABLE_NAME - + " WHERE " + MmsDatabase.THREAD_ID + " = ?) AND (%s) AND " - + AttachmentDatabase.DATA + " IS NOT NULL " - + "ORDER BY " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " DESC"; + 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/%'"); @@ -83,8 +54,8 @@ public class MediaDatabase extends Database { public static MediaRecord from(@NonNull Context context, @NonNull Cursor cursor) { AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); List attachments = attachmentDatabase.getAttachment(cursor); - String serializedAddress = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); - boolean outgoing = MessagingDatabase.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX))); + String serializedAddress = null;//cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); + boolean outgoing = false; //MessagingDatabase.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX))); Address address = null; if (serializedAddress != null) { @@ -93,10 +64,10 @@ public class MediaDatabase extends Database { long date; - if (MmsDatabase.Types.isPushType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX)))) { - date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.DATE_SENT)); + if (false) { + date = cursor.getLong(cursor.getColumnIndexOrThrow(null)); } else { - date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.DATE_RECEIVED)); + date = cursor.getLong(cursor.getColumnIndexOrThrow(null)); } return new MediaRecord(attachments != null && attachments.size() > 0 ? attachments.get(0) : null, address, date, outgoing); diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java deleted file mode 100644 index 3e056f703..000000000 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ /dev/null @@ -1,357 +0,0 @@ -/** - * Copyright (C) 2011 Whisper Systems - * - * 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 . - */ -package org.thoughtcrime.securesms.database; - -import android.content.Context; -import android.database.Cursor; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import android.util.Log; - -import com.annimon.stream.Stream; -import com.google.android.mms.pdu_alt.PduHeaders; - -import net.sqlcipher.database.SQLiteDatabase; - -import org.json.JSONArray; -import org.json.JSONException; -import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment; -import org.thoughtcrime.securesms.contactshare.Contact; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.documents.NetworkFailureList; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; -import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord; -import org.thoughtcrime.securesms.database.model.Quote; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.JsonUtils; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.thoughtcrime.securesms.contactshare.Contact.Avatar; -import static org.thoughtcrime.securesms.contactshare.Contact.deserialize; - -public class MmsDatabase extends MessagingDatabase { - - private static final String TAG = MmsDatabase.class.getSimpleName(); - - public static final String TABLE_NAME = "mms"; - static final String DATE_SENT = "date"; - static final String DATE_RECEIVED = "date_received"; - public static final String MESSAGE_BOX = "msg_box"; - static final String CONTENT_LOCATION = "ct_l"; - static final String EXPIRY = "exp"; - public static final String MESSAGE_TYPE = "m_type"; - static final String MESSAGE_SIZE = "m_size"; - static final String STATUS = "st"; - static final String TRANSACTION_ID = "tr_id"; - static final String PART_COUNT = "part_count"; - static final String NETWORK_FAILURE = "network_failures"; - - static final String QUOTE_ID = "quote_id"; - static final String QUOTE_AUTHOR = "quote_author"; - static final String QUOTE_BODY = "quote_body"; - static final String QUOTE_ATTACHMENT = "quote_attachment"; - - static final String SHARED_CONTACTS = "shared_contacts"; - - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + - THREAD_ID + " INTEGER, " + DATE_SENT + " INTEGER, " + DATE_RECEIVED + " INTEGER, " + MESSAGE_BOX + " INTEGER, " + - READ + " INTEGER DEFAULT 0, " + "m_id" + " TEXT, " + "sub" + " TEXT, " + - "sub_cs" + " INTEGER, " + BODY + " TEXT, " + PART_COUNT + " INTEGER, " + - "ct_t" + " TEXT, " + CONTENT_LOCATION + " TEXT, " + ADDRESS + " TEXT, " + - ADDRESS_DEVICE_ID + " INTEGER, " + - EXPIRY + " INTEGER, " + "m_cls" + " TEXT, " + MESSAGE_TYPE + " INTEGER, " + - "v" + " INTEGER, " + MESSAGE_SIZE + " INTEGER, " + "pri" + " INTEGER, " + - "rr" + " INTEGER, " + "rpt_a" + " INTEGER, " + "resp_st" + " INTEGER, " + - STATUS + " INTEGER, " + TRANSACTION_ID + " TEXT, " + "retr_st" + " INTEGER, " + - "retr_txt" + " TEXT, " + "retr_txt_cs" + " INTEGER, " + "read_status" + " INTEGER, " + - "ct_cls" + " INTEGER, " + "resp_txt" + " TEXT, " + "d_tm" + " INTEGER, " + - DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + - NETWORK_FAILURE + " TEXT DEFAULT NULL," + "d_rpt" + " INTEGER, " + - SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + EXPIRES_IN + " INTEGER DEFAULT 0, " + - EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " + - READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " + - QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " + - SHARED_CONTACTS + " TEXT);"; - - public static final String[] CREATE_INDEXS = { - "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS mms_read_index ON " + TABLE_NAME + " (" + READ + ");", - "CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS mms_message_box_index ON " + TABLE_NAME + " (" + MESSAGE_BOX + ");", - "CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ");", - "CREATE INDEX IF NOT EXISTS mms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");" - }; - - public MmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } - - public int getMessageCountForThread(long threadId) { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - Cursor cursor = null; - - try { - cursor = db.query(TABLE_NAME, new String[] {"COUNT(*)"}, THREAD_ID + " = ?", new String[] {threadId+""}, null, null, null); - - if (cursor != null && cursor.moveToFirst()) - return cursor.getInt(0); - } finally { - if (cursor != null) - cursor.close(); - } - - return 0; - } - - public long getThreadIdForMessage(long id) { - String sql = "SELECT " + THREAD_ID + " FROM " + TABLE_NAME + " WHERE " + ID + " = ?"; - String[] sqlArgs = new String[] {id+""}; - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - - Cursor cursor = null; - - try { - cursor = db.rawQuery(sql, sqlArgs); - if (cursor != null && cursor.moveToFirst()) - return cursor.getLong(0); - else - return -1; - } finally { - if (cursor != null) - cursor.close(); - } - } - - private List getSharedContacts(@NonNull Cursor cursor, @NonNull List attachments) { - String serializedContacts = cursor.getString(cursor.getColumnIndexOrThrow(SHARED_CONTACTS)); - - if (TextUtils.isEmpty(serializedContacts)) { - return Collections.emptyList(); - } - - Map attachmentIdMap = new HashMap<>(); - for (DatabaseAttachment attachment : attachments) { - attachmentIdMap.put(attachment.getAttachmentId(), attachment); - } - - try { - List contacts = new LinkedList<>(); - JSONArray jsonContacts = new JSONArray(serializedContacts); - - for (int i = 0; i < jsonContacts.length(); i++) { - Contact contact = deserialize(jsonContacts.getJSONObject(i).toString()); - - if (contact.getAvatar() != null && contact.getAvatar().getAttachmentId() != null) { - DatabaseAttachment attachment = attachmentIdMap.get(contact.getAvatar().getAttachmentId()); - Avatar updatedAvatar = new Avatar(contact.getAvatar().getAttachmentId(), - attachment, - contact.getAvatar().isProfile()); - contacts.add(new Contact(contact, updatedAvatar)); - } else { - contacts.add(contact); - } - } - - return contacts; - } catch (JSONException | IOException e) { - Log.w(TAG, "Failed to parse shared contacts.", e); - } - - return Collections.emptyList(); - } - - public Reader readerFor(Cursor cursor) { - return new Reader(cursor); - } - - public static class Status { - public static final int DOWNLOAD_INITIALIZED = 1; - public static final int DOWNLOAD_NO_CONNECTIVITY = 2; - public static final int DOWNLOAD_CONNECTING = 3; - } - - public class Reader implements Closeable { - - private final Cursor cursor; - - public Reader(Cursor cursor) { - this.cursor = cursor; - } - - public MessageRecord getNext() { - if (cursor == null || !cursor.moveToNext()) - return null; - - return getCurrent(); - } - - public MessageRecord getCurrent() { - long mmsType = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_TYPE)); - - if (mmsType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) { - return getNotificationMmsMessageRecord(cursor); - } else { - return getMediaMmsMessageRecord(cursor); - } - } - - private NotificationMmsMessageRecord getNotificationMmsMessageRecord(Cursor cursor) { - long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.ID)); - long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.NORMALIZED_DATE_SENT)); - long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.NORMALIZED_DATE_RECEIVED)); - long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID)); - long mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX)); - String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); - int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID)); - Recipient recipient = getRecipientFor(address); - - String contentLocation = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.CONTENT_LOCATION)); - String transactionId = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.TRANSACTION_ID)); - long messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_SIZE)); - long expiry = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRY)); - int status = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.STATUS)); - int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.DELIVERY_RECEIPT_COUNT)); - int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.READ_RECEIPT_COUNT)); - int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.SUBSCRIPTION_ID)); - -// if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { -// readReceiptCount = 0; -// } - - byte[]contentLocationBytes = null; - byte[]transactionIdBytes = null; - - if (!TextUtils.isEmpty(contentLocation)) - contentLocationBytes = org.thoughtcrime.securesms.util.Util.toIsoBytes(contentLocation); - - if (!TextUtils.isEmpty(transactionId)) - transactionIdBytes = org.thoughtcrime.securesms.util.Util.toIsoBytes(transactionId); - - SlideDeck slideDeck = new SlideDeck(context, new MmsNotificationAttachment(status, messageSize)); - - - return new NotificationMmsMessageRecord(context, id, recipient, recipient, - addressDeviceId, dateSent, dateReceived, deliveryReceiptCount, threadId, - contentLocationBytes, messageSize, expiry, status, - transactionIdBytes, mailbox, subscriptionId, slideDeck, - readReceiptCount); - } - - private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) { - long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.ID)); - long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.NORMALIZED_DATE_SENT)); - long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.NORMALIZED_DATE_RECEIVED)); - long box = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX)); - long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID)); - String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); - int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID)); - int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.DELIVERY_RECEIPT_COUNT)); - int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.READ_RECEIPT_COUNT)); - String body = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.BODY)); - int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.PART_COUNT)); - String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE)); - int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.SUBSCRIPTION_ID)); - long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRES_IN)); - long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRE_STARTED)); - -// if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { -// readReceiptCount = 0; -// } - - Recipient recipient = getRecipientFor(address); - List networkFailures = getFailures(networkDocument); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor); - List contacts = getSharedContacts(cursor, attachments); - Set contactAttachments = new HashSet<>(Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList()); - SlideDeck slideDeck = getSlideDeck(Stream.of(attachments).filterNot(contactAttachments::contains).toList()); - Quote quote = getQuote(cursor); - - return new MediaMmsMessageRecord(context, id, recipient, recipient, - addressDeviceId, dateSent, dateReceived, deliveryReceiptCount, - threadId, body, slideDeck, partCount, box, new LinkedList<>(), - networkFailures, subscriptionId, expiresIn, expireStarted, - readReceiptCount, quote, contacts); - } - - private Recipient getRecipientFor(String serialized) { - Address address; - - if (TextUtils.isEmpty(serialized) || "insert-address-token".equals(serialized)) { - address = Address.UNKNOWN; - } else { - address = Address.fromSerialized(serialized); - - } - return Recipient.from(context, address, true); - } - - private List getFailures(String document) { - if (!TextUtils.isEmpty(document)) { - try { - return JsonUtils.fromJson(document, NetworkFailureList.class).getList(); - } catch (IOException ioe) { - Log.w(TAG, ioe); - } - } - - return new LinkedList<>(); - } - - private SlideDeck getSlideDeck(@NonNull List attachments) { - List messageAttachmnets = Stream.of(attachments).filterNot(Attachment::isQuote).toList(); - return new SlideDeck(context, messageAttachmnets); - } - - private @Nullable Quote getQuote(@NonNull Cursor cursor) { - long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_ID)); - String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR)); - String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY)); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor); - List quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList(); - SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments); - - if (quoteId > 0 && !TextUtils.isEmpty(quoteAuthor)) { - return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteDeck); - } else { - return null; - } - } - - @Override - public void close() { - if (cursor != null) { - cursor.close(); - } - } - } -} diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java deleted file mode 100644 index b4b3bc231..000000000 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * - * 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 . - */ -package org.thoughtcrime.securesms.database; - -import android.content.Context; -import android.database.Cursor; -import android.support.annotation.NonNull; -import android.util.Log; - -import net.sqlcipher.database.SQLiteDatabase; -import net.sqlcipher.database.SQLiteQueryBuilder; - -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.database.model.MessageRecord; - -import java.util.HashSet; -import java.util.Set; - -public class MmsSmsDatabase extends Database { - - @SuppressWarnings("unused") - private static final String TAG = MmsSmsDatabase.class.getSimpleName(); - - public static final String TRANSPORT = "transport_type"; - public static final String MMS_TRANSPORT = "mms"; - public static final String SMS_TRANSPORT = "sms"; - - private static final String[] PROJECTION = {MmsSmsColumns.ID, MmsSmsColumns.UNIQUE_ROW_ID, - SmsDatabase.BODY, SmsDatabase.TYPE, - MmsSmsColumns.THREAD_ID, - SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, - MmsSmsColumns.NORMALIZED_DATE_SENT, - MmsSmsColumns.NORMALIZED_DATE_RECEIVED, - MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX, - SmsDatabase.STATUS, MmsDatabase.PART_COUNT, - MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, - MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, - MmsDatabase.STATUS, - MmsSmsColumns.DELIVERY_RECEIPT_COUNT, - MmsSmsColumns.READ_RECEIPT_COUNT, - MmsSmsColumns.MISMATCHED_IDENTITIES, - MmsDatabase.NETWORK_FAILURE, - MmsSmsColumns.SUBSCRIPTION_ID, - MmsSmsColumns.EXPIRES_IN, - MmsSmsColumns.EXPIRE_STARTED, - MmsSmsColumns.NOTIFIED, - TRANSPORT, - AttachmentDatabase.ATTACHMENT_JSON_ALIAS, - MmsDatabase.QUOTE_ID, - MmsDatabase.QUOTE_AUTHOR, - MmsDatabase.QUOTE_BODY, - MmsDatabase.QUOTE_ATTACHMENT, - MmsDatabase.SHARED_CONTACTS}; - - public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } - - public Cursor getConversationSnippet(long threadId) { - String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC"; - String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; - - return queryTables(PROJECTION, selection, order, "1"); - } - - public Cursor getUnread() { - String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC"; - String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.NOTIFIED + " = 0"; - - return queryTables(PROJECTION, selection, order, null); - } - - public int getConversationCount(long threadId) { - int count = DatabaseFactory.getSmsDatabase(context).getMessageCountForThread(threadId); - count += DatabaseFactory.getMmsDatabase(context).getMessageCountForThread(threadId); - - return count; - } - - private Cursor queryTables(String[] projection, String selection, String order, String limit) { - String[] mmsProjection = {MmsDatabase.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT, - MmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED, - MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " AS " + MmsSmsColumns.ID, - "'MMS::' || " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID - + " || '::' || " + MmsDatabase.DATE_SENT - + " AS " + MmsSmsColumns.UNIQUE_ROW_ID, - "json_group_array(json_object(" + - "'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " + - "'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " + - "'" + AttachmentDatabase.MMS_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + "," + - "'" + AttachmentDatabase.SIZE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.SIZE + ", " + - "'" + AttachmentDatabase.FILE_NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FILE_NAME + ", " + - "'" + AttachmentDatabase.DATA + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DATA + ", " + - "'" + AttachmentDatabase.THUMBNAIL + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL + ", " + - "'" + AttachmentDatabase.CONTENT_TYPE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_TYPE + ", " + - "'" + AttachmentDatabase.CONTENT_LOCATION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_LOCATION + ", " + - "'" + AttachmentDatabase.FAST_PREFLIGHT_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", " + - "'" + AttachmentDatabase.VOICE_NOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", " + - "'" + AttachmentDatabase.WIDTH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + ", " + - "'" + AttachmentDatabase.HEIGHT + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + ", " + - "'" + AttachmentDatabase.QUOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.QUOTE + ", " + - "'" + AttachmentDatabase.CONTENT_DISPOSITION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", " + - "'" + AttachmentDatabase.NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " + - "'" + AttachmentDatabase.TRANSFER_STATE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFER_STATE + - ")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS, - SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID, - SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE, - MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT, - MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, - MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, - MmsSmsColumns.DELIVERY_RECEIPT_COUNT, MmsSmsColumns.READ_RECEIPT_COUNT, - MmsSmsColumns.MISMATCHED_IDENTITIES, - MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED, - MmsSmsColumns.NOTIFIED, - MmsDatabase.NETWORK_FAILURE, TRANSPORT, - MmsDatabase.QUOTE_ID, - MmsDatabase.QUOTE_AUTHOR, - MmsDatabase.QUOTE_BODY, - MmsDatabase.QUOTE_ATTACHMENT, - MmsDatabase.SHARED_CONTACTS}; - - String[] smsProjection = {SmsDatabase.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT, - SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED, - MmsSmsColumns.ID, - "'SMS::' || " + MmsSmsColumns.ID - + " || '::' || " + SmsDatabase.DATE_SENT - + " AS " + MmsSmsColumns.UNIQUE_ROW_ID, - "NULL AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS, - SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID, - SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE, - MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT, - MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, - MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, - MmsSmsColumns.DELIVERY_RECEIPT_COUNT, MmsSmsColumns.READ_RECEIPT_COUNT, - MmsSmsColumns.MISMATCHED_IDENTITIES, - MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED, - MmsSmsColumns.NOTIFIED, - MmsDatabase.NETWORK_FAILURE, TRANSPORT, - MmsDatabase.QUOTE_ID, - MmsDatabase.QUOTE_AUTHOR, - MmsDatabase.QUOTE_BODY, - MmsDatabase.QUOTE_ATTACHMENT, - MmsDatabase.SHARED_CONTACTS}; - - SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); - SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); - - mmsQueryBuilder.setDistinct(true); - smsQueryBuilder.setDistinct(true); - - smsQueryBuilder.setTables(SmsDatabase.TABLE_NAME); - mmsQueryBuilder.setTables(MmsDatabase.TABLE_NAME + " LEFT OUTER JOIN " + - AttachmentDatabase.TABLE_NAME + - " ON " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID); - - - Set mmsColumnsPresent = new HashSet<>(); - mmsColumnsPresent.add(MmsSmsColumns.ID); - mmsColumnsPresent.add(MmsSmsColumns.READ); - mmsColumnsPresent.add(MmsSmsColumns.THREAD_ID); - mmsColumnsPresent.add(MmsSmsColumns.BODY); - mmsColumnsPresent.add(MmsSmsColumns.ADDRESS); - mmsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID); - mmsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT); - mmsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT); - mmsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES); - mmsColumnsPresent.add(MmsSmsColumns.SUBSCRIPTION_ID); - mmsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN); - mmsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED); - mmsColumnsPresent.add(MmsDatabase.MESSAGE_TYPE); - mmsColumnsPresent.add(MmsDatabase.MESSAGE_BOX); - mmsColumnsPresent.add(MmsDatabase.DATE_SENT); - mmsColumnsPresent.add(MmsDatabase.DATE_RECEIVED); - mmsColumnsPresent.add(MmsDatabase.PART_COUNT); - mmsColumnsPresent.add(MmsDatabase.CONTENT_LOCATION); - mmsColumnsPresent.add(MmsDatabase.TRANSACTION_ID); - mmsColumnsPresent.add(MmsDatabase.MESSAGE_SIZE); - mmsColumnsPresent.add(MmsDatabase.EXPIRY); - mmsColumnsPresent.add(MmsDatabase.NOTIFIED); - mmsColumnsPresent.add(MmsDatabase.STATUS); - mmsColumnsPresent.add(MmsDatabase.NETWORK_FAILURE); - - mmsColumnsPresent.add(AttachmentDatabase.ROW_ID); - mmsColumnsPresent.add(AttachmentDatabase.UNIQUE_ID); - mmsColumnsPresent.add(AttachmentDatabase.MMS_ID); - mmsColumnsPresent.add(AttachmentDatabase.SIZE); - mmsColumnsPresent.add(AttachmentDatabase.FILE_NAME); - mmsColumnsPresent.add(AttachmentDatabase.DATA); - mmsColumnsPresent.add(AttachmentDatabase.THUMBNAIL); - mmsColumnsPresent.add(AttachmentDatabase.CONTENT_TYPE); - mmsColumnsPresent.add(AttachmentDatabase.CONTENT_LOCATION); - mmsColumnsPresent.add(AttachmentDatabase.DIGEST); - mmsColumnsPresent.add(AttachmentDatabase.FAST_PREFLIGHT_ID); - mmsColumnsPresent.add(AttachmentDatabase.VOICE_NOTE); - mmsColumnsPresent.add(AttachmentDatabase.WIDTH); - mmsColumnsPresent.add(AttachmentDatabase.HEIGHT); - mmsColumnsPresent.add(AttachmentDatabase.QUOTE); - mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION); - mmsColumnsPresent.add(AttachmentDatabase.NAME); - mmsColumnsPresent.add(AttachmentDatabase.TRANSFER_STATE); - mmsColumnsPresent.add(AttachmentDatabase.ATTACHMENT_JSON_ALIAS); - mmsColumnsPresent.add(MmsDatabase.QUOTE_ID); - mmsColumnsPresent.add(MmsDatabase.QUOTE_AUTHOR); - mmsColumnsPresent.add(MmsDatabase.QUOTE_BODY); - mmsColumnsPresent.add(MmsDatabase.QUOTE_ATTACHMENT); - mmsColumnsPresent.add(MmsDatabase.SHARED_CONTACTS); - - Set smsColumnsPresent = new HashSet<>(); - smsColumnsPresent.add(MmsSmsColumns.ID); - smsColumnsPresent.add(MmsSmsColumns.BODY); - smsColumnsPresent.add(MmsSmsColumns.ADDRESS); - smsColumnsPresent.add(MmsSmsColumns.ADDRESS_DEVICE_ID); - smsColumnsPresent.add(MmsSmsColumns.READ); - smsColumnsPresent.add(MmsSmsColumns.THREAD_ID); - smsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT); - smsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT); - smsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES); - smsColumnsPresent.add(MmsSmsColumns.SUBSCRIPTION_ID); - smsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN); - smsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED); - smsColumnsPresent.add(MmsSmsColumns.NOTIFIED); - smsColumnsPresent.add(SmsDatabase.TYPE); - smsColumnsPresent.add(SmsDatabase.SUBJECT); - smsColumnsPresent.add(SmsDatabase.DATE_SENT); - smsColumnsPresent.add(SmsDatabase.DATE_RECEIVED); - smsColumnsPresent.add(SmsDatabase.STATUS); - - @SuppressWarnings("deprecation") - String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID, null); - @SuppressWarnings("deprecation") - String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(TRANSPORT, smsProjection, smsColumnsPresent, 4, SMS_TRANSPORT, selection, null, null, null); - - SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); - String unionQuery = unionQueryBuilder.buildUnionQuery(new String[] {smsSubQuery, mmsSubQuery}, order, limit); - - SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); - outerQueryBuilder.setTables("(" + unionQuery + ")"); - - @SuppressWarnings("deprecation") - String query = outerQueryBuilder.buildQuery(projection, null, null, null, null, null, null); - - Log.w("MmsSmsDatabase", "Executing query: " + query); - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - return db.rawQuery(query, null); - } - - public Reader readerFor(@NonNull Cursor cursor) { - return new Reader(cursor); - } - - public class Reader { - - private final Cursor cursor; - private SmsDatabase.Reader smsReader; - private MmsDatabase.Reader mmsReader; - - public Reader(Cursor cursor) { - this.cursor = cursor; - } - - private SmsDatabase.Reader getSmsReader() { - if (smsReader == null) { - smsReader = DatabaseFactory.getSmsDatabase(context).readerFor(cursor); - } - - return smsReader; - } - - private MmsDatabase.Reader getMmsReader() { - if (mmsReader == null) { - mmsReader = DatabaseFactory.getMmsDatabase(context).readerFor(cursor); - } - - return mmsReader; - } - - public MessageRecord getNext() { - if (cursor == null || !cursor.moveToNext()) - return null; - - return getCurrent(); - } - - public MessageRecord getCurrent() { - String type = cursor.getString(cursor.getColumnIndexOrThrow(TRANSPORT)); - - if (MmsSmsDatabase.MMS_TRANSPORT.equals(type)) return getMmsReader().getCurrent(); - else if (MmsSmsDatabase.SMS_TRANSPORT.equals(type)) return getSmsReader().getCurrent(); - else throw new AssertionError("Bad type: " + type); - } - - public void close() { - cursor.close(); - } - } -} diff --git a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java index 0e05b8386..2f168f56b 100644 --- a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -5,19 +5,14 @@ import android.content.Context; import android.database.Cursor; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; - -import com.annimon.stream.Stream; import net.sqlcipher.database.SQLiteDatabase; import org.thoughtcrime.securesms.color.MaterialColor; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.guava.Optional; -import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -29,34 +24,8 @@ public class RecipientDatabase extends Database { private static final String ID = "_id"; static final String ADDRESS = "recipient_ids"; private static final String BLOCK = "block"; - private static final String NOTIFICATION = "notification"; - private static final String VIBRATE = "vibrate"; - private static final String MUTE_UNTIL = "mute_until"; private static final String COLOR = "color"; - private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder"; - private static final String DEFAULT_SUBSCRIPTION_ID = "default_subscription_id"; - private static final String EXPIRE_MESSAGES = "expire_messages"; private static final String REGISTERED = "registered"; - private static final String PROFILE_KEY = "profile_key"; - private static final String SYSTEM_DISPLAY_NAME = "system_display_name"; - private static final String SYSTEM_PHOTO_URI = "system_contact_photo"; - private static final String SYSTEM_PHONE_LABEL = "system_phone_label"; - private static final String SYSTEM_CONTACT_URI = "system_contact_uri"; - private static final String SIGNAL_PROFILE_NAME = "signal_profile_name"; - private static final String SIGNAL_PROFILE_AVATAR = "signal_profile_avatar"; - private static final String PROFILE_SHARING = "profile_sharing_approval"; - private static final String CALL_RINGTONE = "call_ringtone"; - private static final String CALL_VIBRATE = "call_vibrate"; - - private static final String[] RECIPIENT_PROJECTION = new String[] { - BLOCK, NOTIFICATION, CALL_RINGTONE, VIBRATE, CALL_VIBRATE, MUTE_UNTIL, COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, EXPIRE_MESSAGES, REGISTERED, - PROFILE_KEY, SYSTEM_DISPLAY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_CONTACT_URI, - SIGNAL_PROFILE_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING - }; - - static final List TYPED_RECIPIENT_PROJECTION = Stream.of(RECIPIENT_PROJECTION) - .map(columnName -> TABLE_NAME + "." + columnName) - .toList(); public enum RegisteredState { UNKNOWN(0), REGISTERED(1), NOT_REGISTERED(2); @@ -70,36 +39,8 @@ public class RecipientDatabase extends Database { public int getId() { return id; } - - public static RegisteredState fromId(int id) { - return values()[id]; - } } - public static final String CREATE_TABLE = - "CREATE TABLE " + TABLE_NAME + - " (" + ID + " INTEGER PRIMARY KEY, " + - ADDRESS + " TEXT UNIQUE, " + - BLOCK + " INTEGER DEFAULT 0," + - NOTIFICATION + " TEXT DEFAULT NULL, " + - VIBRATE + " INTEGER DEFAULT 0, " + - MUTE_UNTIL + " INTEGER DEFAULT 0, " + - COLOR + " TEXT DEFAULT NULL, " + - SEEN_INVITE_REMINDER + " INTEGER DEFAULT 0, " + - DEFAULT_SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + - EXPIRE_MESSAGES + " INTEGER DEFAULT 0, " + - REGISTERED + " INTEGER DEFAULT 0, " + - SYSTEM_DISPLAY_NAME + " TEXT DEFAULT NULL, " + - SYSTEM_PHOTO_URI + " TEXT DEFAULT NULL, " + - SYSTEM_PHONE_LABEL + " TEXT DEFAULT NULL, " + - SYSTEM_CONTACT_URI + " TEXT DEFAULT NULL, " + - PROFILE_KEY + " TEXT DEFAULT NULL, " + - SIGNAL_PROFILE_NAME + " TEXT DEFAULT NULL, " + - SIGNAL_PROFILE_AVATAR + " TEXT DEFAULT NULL, " + - PROFILE_SHARING + " INTEGER DEFAULT 0, " + - CALL_RINGTONE + " TEXT DEFAULT NULL, " + - CALL_VIBRATE + " INTEGER DEFAULT 0);"; - public RecipientDatabase(Context context, SQLCipherOpenHelper databaseHelper) { super(context, databaseHelper); } @@ -111,67 +52,6 @@ public class RecipientDatabase extends Database { null, null, null, null, null); } - public Optional getRecipientSettings(@NonNull Address address) { - SQLiteDatabase database = databaseHelper.getReadableDatabase(); - Cursor cursor = null; - - try { - cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null); - - if (cursor != null && cursor.moveToNext()) { - return getRecipientSettings(cursor); - } - - return Optional.absent(); - } finally { - if (cursor != null) cursor.close(); - } - } - - Optional getRecipientSettings(@NonNull Cursor cursor) { - boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1; - long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL)); - String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR)); - boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1; - int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID)); - int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES)); - int registeredState = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED)); - String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY)); - String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME)); - String systemContactPhoto = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHOTO_URI)); - String systemPhoneLabel = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_PHONE_LABEL)); - String systemContactUri = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_CONTACT_URI)); - String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME)); - String signalProfileAvatar = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_AVATAR)); - - MaterialColor color; - byte[] profileKey = null; - - try { - color = serializedColor == null ? null : MaterialColor.fromSerialized(serializedColor); - } catch (MaterialColor.UnknownColorException e) { - Log.w(TAG, e); - color = null; - } - - if (profileKeyString != null) { - try { - profileKey = Base64.decode(profileKeyString); - } catch (IOException e) { - Log.w(TAG, e); - profileKey = null; - } - } - - return Optional.of(new RecipientSettings(blocked, muteUntil, - color, seenInviteReminder, - defaultSubscriptionId, expireMessages, - RegisteredState.fromId(registeredState), - profileKey, systemDisplayName, systemContactPhoto, - systemPhoneLabel, systemContactUri, - signalProfileName, signalProfileAvatar)); - } - public void setColor(@NonNull Recipient recipient, @NonNull MaterialColor color) { ContentValues values = new ContentValues(); values.put(COLOR, color.serialize()); diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java deleted file mode 100644 index 8b2b3c162..000000000 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * Copyright (C) 2013 - 2017 Open Whisper Systems - * - * 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 . - */ -package org.thoughtcrime.securesms.database; - -import android.content.Context; -import android.database.Cursor; - -import net.sqlcipher.database.SQLiteDatabase; - -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.database.model.SmsMessageRecord; -import org.thoughtcrime.securesms.recipients.Recipient; - -import java.util.LinkedList; - -/** - * Database for storage of SMS messages. - * - * @author Moxie Marlinspike - */ -public class SmsDatabase extends MessagingDatabase { - - private static final String TAG = SmsDatabase.class.getSimpleName(); - - public static final String TABLE_NAME = "sms"; - public static final String PERSON = "person"; - static final String DATE_RECEIVED = "date"; - static final String DATE_SENT = "date_sent"; - public static final String PROTOCOL = "protocol"; - public static final String STATUS = "status"; - public static final String TYPE = "type"; - public static final String REPLY_PATH_PRESENT = "reply_path_present"; - public static final String SUBJECT = "subject"; - public static final String SERVICE_CENTER = "service_center"; - - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " integer PRIMARY KEY, " + - THREAD_ID + " INTEGER, " + ADDRESS + " TEXT, " + ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " + PERSON + " INTEGER, " + - DATE_RECEIVED + " INTEGER, " + DATE_SENT + " INTEGER, " + PROTOCOL + " INTEGER, " + READ + " INTEGER DEFAULT 0, " + - STATUS + " INTEGER DEFAULT -1," + TYPE + " INTEGER, " + REPLY_PATH_PRESENT + " INTEGER, " + - DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0," + SUBJECT + " TEXT, " + BODY + " TEXT, " + - MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + SERVICE_CENTER + " TEXT, " + SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + - EXPIRES_IN + " INTEGER DEFAULT 0, " + EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " DEFAULT 0, " + - READ_RECEIPT_COUNT + " INTEGER DEFAULT 0);"; - - public static final String[] CREATE_INDEXS = { - "CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS sms_read_index ON " + TABLE_NAME + " (" + READ + ");", - "CREATE INDEX IF NOT EXISTS sms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS sms_type_index ON " + TABLE_NAME + " (" + TYPE + ");", - "CREATE INDEX IF NOT EXISTS sms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ");", - "CREATE INDEX IF NOT EXISTS sms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");" - }; - - public SmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } - - public int getMessageCountForThread(long threadId) { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - Cursor cursor = null; - - try { - cursor = db.query(TABLE_NAME, new String[] {"COUNT(*)"}, THREAD_ID + " = ?", - new String[] {threadId+""}, null, null, null); - - if (cursor != null && cursor.moveToFirst()) - return cursor.getInt(0); - } finally { - if (cursor != null) - cursor.close(); - } - - return 0; - } - - public static class Status { - public static final int STATUS_NONE = -1; - public static final int STATUS_COMPLETE = 0; - public static final int STATUS_PENDING = 0x20; - public static final int STATUS_FAILED = 0x40; - } - - public Reader readerFor(Cursor cursor) { - return new Reader(cursor); - } - - public class Reader { - - private final Cursor cursor; - - public Reader(Cursor cursor) { - this.cursor = cursor; - } - - public SmsMessageRecord getNext() { - if (cursor == null || !cursor.moveToNext()) - return null; - - return getCurrent(); - } - - public int getCount() { - if (cursor == null) return 0; - else return cursor.getCount(); - } - - public SmsMessageRecord getCurrent() { - long messageId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.ID)); - Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.ADDRESS))); - int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.ADDRESS_DEVICE_ID)); - long type = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.TYPE)); - long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.NORMALIZED_DATE_RECEIVED)); - long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.NORMALIZED_DATE_SENT)); - long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.THREAD_ID)); - int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.STATUS)); - int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.DELIVERY_RECEIPT_COUNT)); - int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.READ_RECEIPT_COUNT)); - int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.SUBSCRIPTION_ID)); - long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.EXPIRES_IN)); - long expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.EXPIRE_STARTED)); - String body = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.BODY)); - -// if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { -// readReceiptCount = 0; -// } - - Recipient recipient = Recipient.from(context, address, true); - - return new SmsMessageRecord(context, messageId, body, recipient, - recipient, - addressDeviceId, - dateSent, dateReceived, deliveryReceiptCount, type, - threadId, status, new LinkedList<>(), subscriptionId, - expiresIn, expireStarted, readReceiptCount); - } - - public void close() { - cursor.close(); - } - } - -} diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java deleted file mode 100644 index d92a8e6a9..000000000 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * Copyright (C) 2013-2017 Open Whisper Systems - * - * 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 . - */ -package org.thoughtcrime.securesms.database; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.Log; - -import com.annimon.stream.Stream; - -import net.sqlcipher.database.SQLiteDatabase; - -import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; -import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; -import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.mms.Slide; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Util; -import org.thoughtcrime.securesms.util.guava.Optional; - -import java.io.Closeable; -import java.util.List; - -public class ThreadDatabase extends Database { - - private static final String TAG = ThreadDatabase.class.getSimpleName(); - - public static final String TABLE_NAME = "thread"; - public static final String ID = "_id"; - public static final String DATE = "date"; - public static final String MESSAGE_COUNT = "message_count"; - public static final String ADDRESS = "recipient_ids"; - public static final String SNIPPET = "snippet"; - private static final String SNIPPET_CHARSET = "snippet_cs"; - public static final String READ = "read"; - public static final String UNREAD_COUNT = "unread_count"; - public static final String TYPE = "type"; - private static final String ERROR = "error"; - public static final String SNIPPET_TYPE = "snippet_type"; - public static final String SNIPPET_URI = "snippet_uri"; - public static final String ARCHIVED = "archived"; - public static final String STATUS = "status"; - public static final String DELIVERY_RECEIPT_COUNT = "delivery_receipt_count"; - public static final String READ_RECEIPT_COUNT = "read_receipt_count"; - public static final String EXPIRES_IN = "expires_in"; - public static final String LAST_SEEN = "last_seen"; - private static final String HAS_SENT = "has_sent"; - - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + - ID + " INTEGER PRIMARY KEY, " + DATE + " INTEGER DEFAULT 0, " + - MESSAGE_COUNT + " INTEGER DEFAULT 0, " + ADDRESS + " TEXT, " + SNIPPET + " TEXT, " + - SNIPPET_CHARSET + " INTEGER DEFAULT 0, " + READ + " INTEGER DEFAULT 1, " + - TYPE + " INTEGER DEFAULT 0, " + ERROR + " INTEGER DEFAULT 0, " + - SNIPPET_TYPE + " INTEGER DEFAULT 0, " + SNIPPET_URI + " TEXT DEFAULT NULL, " + - ARCHIVED + " INTEGER DEFAULT 0, " + STATUS + " INTEGER DEFAULT 0, " + - DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + EXPIRES_IN + " INTEGER DEFAULT 0, " + - LAST_SEEN + " INTEGER DEFAULT 0, " + HAS_SENT + " INTEGER DEFAULT 0, " + - READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNREAD_COUNT + " INTEGER DEFAULT 0);"; - - public static final String[] CREATE_INDEXS = { - "CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + ADDRESS + ");", - "CREATE INDEX IF NOT EXISTS archived_count_index ON " + TABLE_NAME + " (" + ARCHIVED + ", " + MESSAGE_COUNT + ");", - }; - - private static final String[] THREAD_PROJECTION = { - ID, DATE, MESSAGE_COUNT, ADDRESS, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, TYPE, ERROR, SNIPPET_TYPE, - SNIPPET_URI, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN, READ_RECEIPT_COUNT - }; - - private static final List TYPED_THREAD_PROJECTION = Stream.of(THREAD_PROJECTION) - .map(columnName -> TABLE_NAME + "." + columnName) - .toList(); - - private static final List COMBINED_THREAD_RECIPIENT_GROUP_PROJECTION = Stream.concat(Stream.concat(Stream.of(TYPED_THREAD_PROJECTION), - Stream.of(RecipientDatabase.TYPED_RECIPIENT_PROJECTION)), - Stream.of(GroupDatabase.TYPED_GROUP_PROJECTION)) - .toList(); - - public ThreadDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } - - private long createThreadForRecipient(Address address, boolean group, int distributionType) { - ContentValues contentValues = new ContentValues(4); - long date = System.currentTimeMillis(); - - contentValues.put(DATE, date - date % 1000); - contentValues.put(ADDRESS, address.serialize()); - - if (group) - contentValues.put(TYPE, distributionType); - - contentValues.put(MESSAGE_COUNT, 0); - - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - return db.insert(TABLE_NAME, null, contentValues); - } - - private void updateThread(long threadId, long count, String body, @Nullable Uri attachment, - long date, int status, int deliveryReceiptCount, long type, boolean unarchive, - long expiresIn, int readReceiptCount) - { - ContentValues contentValues = new ContentValues(7); - contentValues.put(DATE, date - date % 1000); - contentValues.put(MESSAGE_COUNT, count); - contentValues.put(SNIPPET, body); - contentValues.put(SNIPPET_URI, attachment == null ? null : attachment.toString()); - contentValues.put(SNIPPET_TYPE, type); - contentValues.put(STATUS, status); - contentValues.put(DELIVERY_RECEIPT_COUNT, deliveryReceiptCount); - contentValues.put(READ_RECEIPT_COUNT, readReceiptCount); - contentValues.put(EXPIRES_IN, expiresIn); - - if (unarchive) { - contentValues.put(ARCHIVED, 0); - } - - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""}); - notifyConversationListListeners(); - } - - private void deleteThread(long threadId) { - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - db.delete(TABLE_NAME, ID_WHERE, new String[] {threadId + ""}); - notifyConversationListListeners(); - } - - public Cursor getDirectShareList() { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - String query = createQuery(MESSAGE_COUNT + " != 0", 0); - - return db.rawQuery(query, null); - } - - public long getThreadIdFor(Recipient recipient) { - return getThreadIdFor(recipient, DistributionTypes.DEFAULT); - } - - public long getThreadIdFor(Recipient recipient, int distributionType) { - SQLiteDatabase db = databaseHelper.getReadableDatabase(); - String where = ADDRESS + " = ?"; - String[] recipientsArg = new String[]{recipient.getAddress().serialize()}; - Cursor cursor = null; - - try { - cursor = db.query(TABLE_NAME, new String[]{ID}, where, recipientsArg, null, null, null); - - if (cursor != null && cursor.moveToFirst()) { - return cursor.getLong(cursor.getColumnIndexOrThrow(ID)); - } else { - return createThreadForRecipient(recipient.getAddress(), recipient.isGroupRecipient(), distributionType); - } - } finally { - if (cursor != null) - cursor.close(); - } - } - - public boolean update(long threadId, boolean unarchive) { - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); - long count = mmsSmsDatabase.getConversationCount(threadId); - - if (count == 0) { - deleteThread(threadId); - notifyConversationListListeners(); - return true; - } - - MmsSmsDatabase.Reader reader = null; - - try { - reader = mmsSmsDatabase.readerFor(mmsSmsDatabase.getConversationSnippet(threadId)); - MessageRecord record; - - if (reader != null && (record = reader.getNext()) != null) { - updateThread(threadId, count, getFormattedBodyFor(record), getAttachmentUriFor(record), - record.getTimestamp(), record.getDeliveryStatus(), record.getDeliveryReceiptCount(), - record.getType(), unarchive, record.getExpiresIn(), record.getReadReceiptCount()); - notifyConversationListListeners(); - return false; - } else { - deleteThread(threadId); - notifyConversationListListeners(); - return true; - } - } finally { - if (reader != null) - reader.close(); - } - } - - private @NonNull String getFormattedBodyFor(@NonNull MessageRecord messageRecord) { - return messageRecord.getBody(); - } - - private @Nullable Uri getAttachmentUriFor(MessageRecord record) { - if (!record.isMms() || record.isMmsNotification() || record.isGroupAction()) return null; - - SlideDeck slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); - Slide thumbnail = slideDeck.getThumbnailSlide(); - - return thumbnail != null ? thumbnail.getThumbnailUri() : null; - } - - private @NonNull String createQuery(@NonNull String where, int limit) { - String projection = Util.join(COMBINED_THREAD_RECIPIENT_GROUP_PROJECTION, ","); - String query = - "SELECT " + projection + " FROM " + TABLE_NAME + - " LEFT OUTER JOIN " + RecipientDatabase.TABLE_NAME + - " ON " + TABLE_NAME + "." + ADDRESS + " = " + RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.ADDRESS + - " LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME + - " ON " + TABLE_NAME + "." + ADDRESS + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID + - " WHERE " + where + - " ORDER BY " + TABLE_NAME + "." + DATE + " DESC"; - - if (limit > 0) { - query += " LIMIT " + limit; - } - - return query; - } - - public Reader readerFor(Cursor cursor) { - return new Reader(cursor); - } - - public static class DistributionTypes { - public static final int DEFAULT = 2; - public static final int CONVERSATION = 2; - public static final int ARCHIVE = 3; - public static final int INBOX_ZERO = 4; - } - - public class Reader implements Closeable { - - private final Cursor cursor; - - public Reader(Cursor cursor) { - this.cursor = cursor; - } - - public ThreadRecord getNext() { - if (cursor == null || !cursor.moveToNext()) - return null; - - return getCurrent(); - } - - public ThreadRecord getCurrent() { - long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID)); - int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.TYPE)); - Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.ADDRESS))); - - Optional settings; - Optional groupRecord; - - if (distributionType != DistributionTypes.ARCHIVE && distributionType != DistributionTypes.INBOX_ZERO) { - settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(cursor); - groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(cursor); - } else { - settings = Optional.absent(); - groupRecord = Optional.absent(); - } - - Recipient recipient = Recipient.from(context, address, settings, groupRecord, true); - String body = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET)); - long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE)); - long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT)); - int unreadCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT)); - long type = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_TYPE)); - boolean archived = cursor.getInt(cursor.getColumnIndex(ThreadDatabase.ARCHIVED)) != 0; - int status = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.STATUS)); - int deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.DELIVERY_RECEIPT_COUNT)); - int readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.READ_RECEIPT_COUNT)); - long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.EXPIRES_IN)); - long lastSeen = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.LAST_SEEN)); - Uri snippetUri = getSnippetUri(cursor); - -// if (!TextSecurePreferences.isReadReceiptsEnabled(context)) { -// readReceiptCount = 0; -// } - - return new ThreadRecord(context, body, snippetUri, recipient, date, count, - unreadCount, threadId, deliveryReceiptCount, status, type, - distributionType, archived, expiresIn, lastSeen, readReceiptCount, false, null); - } - - private @Nullable Uri getSnippetUri(Cursor cursor) { - if (cursor.isNull(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_URI))) { - return null; - } - - try { - return Uri.parse(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_URI))); - } catch (IllegalArgumentException e) { - Log.w(TAG, e); - return null; - } - } - - @Override - public void close() { - if (cursor != null) { - cursor.close(); - } - } - } -} diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index e8a78f35a..b37764c05 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -14,12 +14,6 @@ import net.sqlcipher.database.SQLiteDatabaseHook; import net.sqlcipher.database.SQLiteOpenHelper; import org.thoughtcrime.securesms.crypto.DatabaseSecret; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.ThreadDatabase; import java.io.File; @@ -65,18 +59,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { - db.execSQL(SmsDatabase.CREATE_TABLE); - db.execSQL(MmsDatabase.CREATE_TABLE); - db.execSQL(AttachmentDatabase.CREATE_TABLE); - db.execSQL(ThreadDatabase.CREATE_TABLE); - db.execSQL(GroupDatabase.CREATE_TABLE); - db.execSQL(RecipientDatabase.CREATE_TABLE); - - executeStatements(db, SmsDatabase.CREATE_INDEXS); - executeStatements(db, MmsDatabase.CREATE_INDEXS); - executeStatements(db, AttachmentDatabase.CREATE_INDEXS); - executeStatements(db, ThreadDatabase.CREATE_INDEXS); - executeStatements(db, GroupDatabase.CREATE_INDEXS); } @Override diff --git a/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java b/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java index 5bfe4e12d..0649a7a22 100644 --- a/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java +++ b/src/org/thoughtcrime/securesms/database/loaders/ThreadMediaLoader.java @@ -6,8 +6,6 @@ import android.database.Cursor; import android.support.annotation.NonNull; import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.AbstractCursorLoader; public class ThreadMediaLoader extends AbstractCursorLoader { @@ -23,10 +21,11 @@ public class ThreadMediaLoader extends AbstractCursorLoader { @Override public Cursor getCursor() { - long threadId = DatabaseFactory.getThreadDatabase(getContext()).getThreadIdFor(Recipient.from(getContext(), address, true)); - - if (gallery) return DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId); - else return DatabaseFactory.getMediaDatabase(getContext()).getDocumentMediaForThread(threadId); + return null; +// long threadId = DatabaseFactory.getThreadDatabase(getContext()).getThreadIdFor(Recipient.from(getContext(), address, true)); +// +// if (gallery) return DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId); +// else return DatabaseFactory.getMediaDatabase(getContext()).getDocumentMediaForThread(threadId); } public Address getAddress() { diff --git a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java index daa9a5e5f..7fda6d328 100644 --- a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java @@ -21,7 +21,6 @@ import android.support.annotation.NonNull; import android.text.SpannableString; import org.thoughtcrime.securesms.database.MmsSmsColumns; -import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.recipients.Recipient; /** @@ -70,9 +69,11 @@ public abstract class DisplayRecord { return MmsSmsColumns.Types.isFailedMessageType(type) || MmsSmsColumns.Types.isPendingSecureSmsFallbackType(type) || - deliveryStatus >= SmsDatabase.Status.STATUS_FAILED; + false; +// deliveryStatus >= SmsDatabase.Status.STATUS_FAILED; } + public boolean isPending() { return MmsSmsColumns.Types.isPendingMessageType(type) && !MmsSmsColumns.Types.isIdentityVerified(type) && @@ -102,19 +103,19 @@ public abstract class DisplayRecord { } public boolean isKeyExchange() { - return SmsDatabase.Types.isKeyExchangeType(type); + return false; } public boolean isEndSession() { - return SmsDatabase.Types.isEndSessionType(type); + return false; } public boolean isGroupUpdate() { - return SmsDatabase.Types.isGroupUpdate(type); + return false; } public boolean isGroupQuit() { - return SmsDatabase.Types.isGroupQuit(type); + return false; } public boolean isGroupAction() { @@ -122,55 +123,32 @@ public abstract class DisplayRecord { } public boolean isExpirationTimerUpdate() { - return SmsDatabase.Types.isExpirationTimerUpdate(type); + return false; } public boolean isCallLog() { - return SmsDatabase.Types.isCallLog(type); + return false; } public boolean isJoined() { - return SmsDatabase.Types.isJoinedType(type); + return false; } public boolean isIncomingCall() { - return SmsDatabase.Types.isIncomingCall(type); + return false; } public boolean isOutgoingCall() { - return SmsDatabase.Types.isOutgoingCall(type); + return false; } public boolean isMissedCall() { - return SmsDatabase.Types.isMissedCall(type); - } - - public boolean isVerificationStatusChange() { - return SmsDatabase.Types.isIdentityDefault(type) || SmsDatabase.Types.isIdentityVerified(type); - } - - public int getDeliveryStatus() { - return deliveryStatus; - } - - public int getDeliveryReceiptCount() { - return deliveryReceiptCount; - } - - public int getReadReceiptCount() { - return readReceiptCount; + return false; } public boolean isDelivered() { - return (deliveryStatus >= SmsDatabase.Status.STATUS_COMPLETE && - deliveryStatus < SmsDatabase.Status.STATUS_PENDING) || deliveryReceiptCount > 0; - } - - public boolean isRemoteRead() { - return readReceiptCount > 0; - } - - public boolean isPendingInsecureSmsFallback() { return false; +// return (deliveryStatus >= SmsDatabase.Status.STATUS_COMPLETE && +// deliveryStatus < SmsDatabase.Status.STATUS_PENDING) || deliveryReceiptCount > 0; } } diff --git a/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java index 4eedda8da..b4f17ede0 100644 --- a/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java @@ -23,8 +23,6 @@ import android.text.SpannableString; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.contactshare.Contact; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase.Status; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.mms.SlideDeck; @@ -58,7 +56,7 @@ public class MediaMmsMessageRecord extends MmsMessageRecord { @Nullable Quote quote, @Nullable List contacts) { super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, - dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures, + dateReceived, threadId, 0, deliveryReceiptCount, mailbox, mismatches, failures, subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount, quote, contacts); this.context = context.getApplicationContext(); @@ -76,13 +74,7 @@ public class MediaMmsMessageRecord extends MmsMessageRecord { @Override public SpannableString getDisplayBody() { - if (MmsDatabase.Types.isFailedDecryptType(type)) { - return emphasisAdded(context.getString(R.string.MmsMessageRecord_bad_encrypted_mms_message)); - } else if (MmsDatabase.Types.isDuplicateMessageType(type)) { - return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message)); - } else if (MmsDatabase.Types.isNoRemoteSessionType(type)) { - return emphasisAdded(context.getString(R.string.MmsMessageRecord_mms_message_encrypted_for_non_existing_session)); - } else if (isLegacyMessage()) { + if (isLegacyMessage()) { return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported)); } diff --git a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java index 03bb7348f..f6b14bc3e 100644 --- a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -24,7 +24,6 @@ import android.text.style.StyleSpan; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.MmsSmsColumns; -import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.recipients.Recipient; @@ -130,7 +129,7 @@ public abstract class MessageRecord extends DisplayRecord { } public boolean isPush() { - return SmsDatabase.Types.isPushType(type) && !SmsDatabase.Types.isForcedSms(type); + return false; } public long getTimestamp() { @@ -140,40 +139,28 @@ public abstract class MessageRecord extends DisplayRecord { return getDateReceived(); } - public boolean isForcedSms() { - return SmsDatabase.Types.isForcedSms(type); - } - public boolean isIdentityVerified() { - return SmsDatabase.Types.isIdentityVerified(type); + return false; } public boolean isIdentityDefault() { - return SmsDatabase.Types.isIdentityDefault(type); - } - - public boolean isIdentityMismatchFailure() { - return mismatches != null && !mismatches.isEmpty(); + return false; } public boolean isBundleKeyExchange() { - return SmsDatabase.Types.isBundleKeyExchange(type); - } - - public boolean isContentBundleKeyExchange() { - return SmsDatabase.Types.isContentBundleKeyExchange(type); + return false; } public boolean isIdentityUpdate() { - return SmsDatabase.Types.isIdentityUpdate(type); + return false; } public boolean isCorruptedKeyExchange() { - return SmsDatabase.Types.isCorruptedKeyExchange(type); + return false; } public boolean isInvalidVersionKeyExchange() { - return SmsDatabase.Types.isInvalidVersionKeyExchange(type); + return false; } public boolean isUpdate() { diff --git a/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java index c028f6480..b71634258 100644 --- a/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java @@ -20,8 +20,6 @@ import android.content.Context; import android.text.SpannableString; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase.Status; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.mms.SlideDeck; @@ -54,7 +52,7 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord { int subscriptionId, SlideDeck slideDeck, int readReceiptCount) { super(context, id, "", conversationRecipient, individualRecipient, recipientDeviceId, - dateSent, dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, + dateSent, dateReceived, threadId, 0, deliveryReceiptCount, mailbox, new LinkedList(), new LinkedList(), subscriptionId, 0, 0, slideDeck, readReceiptCount, null, Collections.emptyList()); @@ -112,12 +110,6 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord { @Override public SpannableString getDisplayBody() { - if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED) { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_multimedia_message)); - } else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_downloading_mms_message)); - } else { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message)); - } + return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message)); } } diff --git a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java index 00c092521..b622d7688 100644 --- a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java @@ -22,7 +22,6 @@ import android.text.SpannableString; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.MmsSmsColumns; -import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.recipients.Recipient; @@ -61,9 +60,7 @@ public class SmsMessageRecord extends MessageRecord { @Override public SpannableString getDisplayBody() { - if (SmsDatabase.Types.isFailedDecryptType(type)) { - return emphasisAdded(context.getString(R.string.MessageDisplayHelper_bad_encrypted_message)); - } else if (isCorruptedKeyExchange()) { + 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)); @@ -75,10 +72,6 @@ public class SmsMessageRecord extends MessageRecord { return new SpannableString(""); } else if (isKeyExchange() && !isOutgoing()) { return emphasisAdded(context.getString(R.string.ConversationItem_received_key_exchange_message_tap_to_process)); - } else if (SmsDatabase.Types.isDuplicateMessageType(type)) { - return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message)); - } else if (SmsDatabase.Types.isNoRemoteSessionType(type)) { - return emphasisAdded(context.getString(R.string.MessageDisplayHelper_message_encrypted_for_non_existing_session)); } else if (isEndSession() && isOutgoing()) { return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset)); } else if (isEndSession()) { diff --git a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java index 969a7f8f4..4bc98b877 100644 --- a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java @@ -23,16 +23,11 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.Spannable; import android.text.SpannableString; -import android.text.TextUtils; import android.text.style.StyleSpan; import com.b44t.messenger.DcLot; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.MmsSmsColumns; -import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.ExpirationUtil; /** * The message record model which represents thread heading messages. @@ -42,8 +37,6 @@ import org.thoughtcrime.securesms.util.ExpirationUtil; */ public class ThreadRecord extends DisplayRecord { - private @NonNull final Context context; - private @Nullable final Uri snippetUri; private final long count; private final int unreadCount; private final int distributionType; @@ -60,8 +53,6 @@ public class ThreadRecord extends DisplayRecord { int readReceiptCount, boolean verified, @Nullable DcLot dcSummary) { super(context, body, recipient, date, date, threadId, status, deliveryReceiptCount, snippetType, readReceiptCount); - this.context = context.getApplicationContext(); - this.snippetUri = snippetUri; this.count = count; this.unreadCount = unreadCount; this.distributionType = distributionType; @@ -120,4 +111,11 @@ public class ThreadRecord extends DisplayRecord { public boolean isVerified() { return verified; } + + public static class DistributionTypes { + public static final int DEFAULT = 2; + public static final int CONVERSATION = 2; + public static final int ARCHIVE = 3; + public static final int INBOX_ZERO = 4; + } } diff --git a/src/org/thoughtcrime/securesms/mms/PartAuthority.java b/src/org/thoughtcrime/securesms/mms/PartAuthority.java index 94af73a3b..5f350dea3 100644 --- a/src/org/thoughtcrime/securesms/mms/PartAuthority.java +++ b/src/org/thoughtcrime/securesms/mms/PartAuthority.java @@ -24,8 +24,6 @@ public class PartAuthority { private static final Uri PART_CONTENT_URI = Uri.parse(PART_URI_STRING); private static final Uri THUMB_CONTENT_URI = Uri.parse(THUMB_URI_STRING); - private static final int PART_ROW = 1; - private static final int THUMB_ROW = 2; private static final int PERSISTENT_ROW = 3; private static final int SINGLE_USE_ROW = 4; @@ -33,8 +31,6 @@ public class PartAuthority { static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - uriMatcher.addURI("org.thoughtcrime.securesms", "part/*/#", PART_ROW); - uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/*/#", THUMB_ROW); uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH_OLD, PERSISTENT_ROW); uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH_NEW, PERSISTENT_ROW); uriMatcher.addURI(SingleUseBlobProvider.AUTHORITY, SingleUseBlobProvider.PATH, SINGLE_USE_ROW); @@ -46,8 +42,6 @@ public class PartAuthority { int match = uriMatcher.match(uri); try { switch (match) { - case PART_ROW: return DatabaseFactory.getAttachmentDatabase(context).getAttachmentStream(new PartUriParser(uri).getPartId(), 0); - case THUMB_ROW: return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(new PartUriParser(uri).getPartId()); case PERSISTENT_ROW: return PersistentBlobProvider.getInstance(context).getStream(context, ContentUris.parseId(uri)); case SINGLE_USE_ROW: return SingleUseBlobProvider.getInstance().getStream(ContentUris.parseId(uri)); default: return context.getContentResolver().openInputStream(uri); @@ -61,12 +55,6 @@ public class PartAuthority { int match = uriMatcher.match(uri); switch (match) { - case THUMB_ROW: - case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); - - if (attachment != null) return attachment.getFileName(); - else return null; case PERSISTENT_ROW: return PersistentBlobProvider.getFileName(context, uri); case SINGLE_USE_ROW: @@ -79,12 +67,6 @@ public class PartAuthority { int match = uriMatcher.match(uri); switch (match) { - case THUMB_ROW: - case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); - - if (attachment != null) return attachment.getSize(); - else return null; case PERSISTENT_ROW: return PersistentBlobProvider.getFileSize(context, uri); case SINGLE_USE_ROW: @@ -97,12 +79,6 @@ public class PartAuthority { int match = uriMatcher.match(uri); switch (match) { - case THUMB_ROW: - case PART_ROW: - Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(new PartUriParser(uri).getPartId()); - - if (attachment != null) return attachment.getContentType(); - else return null; case PERSISTENT_ROW: return PersistentBlobProvider.getMimeType(context, uri); case SINGLE_USE_ROW: @@ -129,8 +105,6 @@ public class PartAuthority { public static boolean isLocalUri(final @NonNull Uri uri) { int match = uriMatcher.match(uri); switch (match) { - case PART_ROW: - case THUMB_ROW: case PERSISTENT_ROW: case SINGLE_USE_ROW: return true; diff --git a/src/org/thoughtcrime/securesms/recipients/Recipient.java b/src/org/thoughtcrime/securesms/recipients/Recipient.java index 2df69143e..0de27da1f 100644 --- a/src/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/src/org/thoughtcrime/securesms/recipients/Recipient.java @@ -41,12 +41,8 @@ import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto; import org.thoughtcrime.securesms.contacts.avatars.SystemContactPhoto; import org.thoughtcrime.securesms.contacts.avatars.TransparentContactPhoto; import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails; -import org.thoughtcrime.securesms.util.FutureTaskListener; -import org.thoughtcrime.securesms.util.ListenableFutureTask; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.guava.Optional; @@ -57,7 +53,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.WeakHashMap; -import java.util.concurrent.ExecutionException; public class Recipient implements RecipientModifiedListener { @@ -116,100 +111,7 @@ public class Recipient implements RecipientModifiedListener { return dcContext.getRecipient(dcContext.getContact(contactId)); } } - return provider.getRecipient(context, address, Optional.absent(), Optional.absent(), asynchronous); - } - - @SuppressWarnings("ConstantConditions") - public static @NonNull Recipient from(@NonNull Context context, @NonNull Address address, @NonNull Optional settings, @NonNull Optional groupRecord, boolean asynchronous) { - if (address == null) throw new AssertionError(address); - return provider.getRecipient(context, address, settings, groupRecord, asynchronous); - } - - Recipient(@NonNull Address address, - @Nullable Recipient stale, - @NonNull Optional details, - @NonNull ListenableFutureTask future) - { - this.address = address; - this.color = null; - this.resolving = true; - - if (stale != null) { - this.name = stale.name; - this.contactUri = stale.contactUri; - this.systemContactPhoto = stale.systemContactPhoto; - this.color = stale.color; - this.customLabel = stale.customLabel; - this.messageRingtone = stale.messageRingtone; - this.callRingtone = stale.callRingtone; - this.blocked = stale.blocked; - this.expireMessages = stale.expireMessages; - this.seenInviteReminder = stale.seenInviteReminder; - this.defaultSubscriptionId = stale.defaultSubscriptionId; - this.registered = stale.registered; - this.profileKey = stale.profileKey; - this.profileName = stale.profileName; - this.profileAvatar = stale.profileAvatar; - this.participants.clear(); - this.participants.addAll(stale.participants); - } - - if (details.isPresent()) { - this.name = details.get().name; - this.systemContactPhoto = details.get().systemContactPhoto; - this.color = details.get().color; - this.blocked = details.get().blocked; - this.expireMessages = details.get().expireMessages; - this.seenInviteReminder = details.get().seenInviteReminder; - this.defaultSubscriptionId = details.get().defaultSubscriptionId; - this.registered = details.get().registered; - this.profileKey = details.get().profileKey; - this.profileName = details.get().profileName; - this.profileAvatar = details.get().profileAvatar; - this.participants.clear(); - this.participants.addAll(details.get().participants); - } - - future.addListener(new FutureTaskListener() { - @Override - public void onSuccess(RecipientDetails result) { - if (result != null) { - synchronized (Recipient.this) { - Recipient.this.name = result.name; - Recipient.this.contactUri = result.contactUri; - Recipient.this.systemContactPhoto = result.systemContactPhoto; - Recipient.this.color = result.color; - Recipient.this.customLabel = result.customLabel; - Recipient.this.blocked = result.blocked; - Recipient.this.expireMessages = result.expireMessages; - Recipient.this.seenInviteReminder = result.seenInviteReminder; - Recipient.this.defaultSubscriptionId = result.defaultSubscriptionId; - Recipient.this.registered = result.registered; - Recipient.this.profileKey = result.profileKey; - Recipient.this.profileName = result.profileName; - Recipient.this.profileAvatar = result.profileAvatar; - Recipient.this.profileName = result.profileName; - - Recipient.this.participants.clear(); - Recipient.this.participants.addAll(result.participants); - Recipient.this.resolving = false; - - if (!listeners.isEmpty()) { - for (Recipient recipient : participants) recipient.addListener(Recipient.this); - } - - Recipient.this.notifyAll(); - } - - notifyListeners(); - } - } - - @Override - public void onFailure(ExecutionException error) { - Log.w(TAG, error); - } - }); + return dcContext.getRecipient(dcContext.getContact(0)); } public Recipient(@NonNull Address address, @NonNull RecipientDetails details) { @@ -417,10 +319,6 @@ public class Recipient implements RecipientModifiedListener { notifyListeners(); } - public synchronized int getExpireMessages() { - return expireMessages; - } - public synchronized RegisteredState getRegistered() { if (isPushGroupRecipient()) return RegisteredState.REGISTERED; else if (isMmsGroupRecipient()) return RegisteredState.NOT_REGISTERED; @@ -441,10 +339,6 @@ public class Recipient implements RecipientModifiedListener { if (notify) notifyListeners(); } - public synchronized boolean isSystemContact() { - return contactUri != null; - } - public synchronized Recipient resolve() { while (resolving) Util.wait(this, 0); return this; diff --git a/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java b/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java index ee91d8145..fa95e2971 100644 --- a/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java +++ b/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java @@ -16,21 +16,13 @@ */ package org.thoughtcrime.securesms.recipients; -import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.text.TextUtils; -import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.color.MaterialColor; -import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; -import org.thoughtcrime.securesms.util.ListenableFutureTask; -import org.thoughtcrime.securesms.util.SoftHashMap; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.guava.Optional; @@ -38,118 +30,16 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; public class RecipientProvider { @SuppressWarnings("unused") private static final String TAG = RecipientProvider.class.getSimpleName(); - private static final RecipientCache recipientCache = new RecipientCache(); - private static final ExecutorService asyncRecipientResolver = Util.newSingleThreadedLifoExecutor(); - private static final Map STATIC_DETAILS = new HashMap() {{ put("262966", new RecipientDetails("Amazon", null, false, null, null)); }}; - @NonNull Recipient getRecipient(@NonNull Context context, @NonNull Address address, @NonNull Optional settings, @NonNull Optional groupRecord, boolean asynchronous) { - Recipient cachedRecipient = recipientCache.get(address); - - if (cachedRecipient != null && (asynchronous || !cachedRecipient.isResolving()) && ((!groupRecord.isPresent() && !settings.isPresent()) || !cachedRecipient.isResolving() || cachedRecipient.getName() != null)) { - return cachedRecipient; - } - - Optional prefetchedRecipientDetails = createPrefetchedRecipientDetails(context, address, settings, groupRecord); - - if (asynchronous) { - cachedRecipient = new Recipient(address, cachedRecipient, prefetchedRecipientDetails, getRecipientDetailsAsync(context, address, settings, groupRecord)); - } else { - cachedRecipient = new Recipient(address, getRecipientDetailsSync(context, address, settings, groupRecord, false)); - } - - recipientCache.set(address, cachedRecipient); - return cachedRecipient; - } - - @NonNull Optional getCached(@NonNull Address address) { - return Optional.fromNullable(recipientCache.get(address)); - } - - private @NonNull Optional createPrefetchedRecipientDetails(@NonNull Context context, @NonNull Address address, - @NonNull Optional settings, - @NonNull Optional groupRecord) - { - if (address.isGroup() && settings.isPresent() && groupRecord.isPresent()) { - return Optional.of(getGroupRecipientDetails(context, address, groupRecord, settings, true)); - } else if (!address.isGroup() && settings.isPresent()) { - return Optional.of(new RecipientDetails(null, null, !TextUtils.isEmpty(settings.get().getSystemDisplayName()), settings.get(), null)); - } - - return Optional.absent(); - } - - private @NonNull ListenableFutureTask getRecipientDetailsAsync(final Context context, final @NonNull Address address, final @NonNull Optional settings, final @NonNull Optional groupRecord) - { - Callable task = () -> getRecipientDetailsSync(context, address, settings, groupRecord, true); - - ListenableFutureTask future = new ListenableFutureTask<>(task); - asyncRecipientResolver.submit(future); - return future; - } - - private @NonNull RecipientDetails getRecipientDetailsSync(Context context, @NonNull Address address, Optional settings, Optional groupRecord, boolean nestedAsynchronous) { - if (address.isGroup()) return getGroupRecipientDetails(context, address, groupRecord, settings, nestedAsynchronous); - else return getIndividualRecipientDetails(context, address, settings); - } - - private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, @NonNull Address address, Optional settings) { - if (!settings.isPresent()) { - settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address); - } - - if (!settings.isPresent() && STATIC_DETAILS.containsKey(address.serialize())) { - return STATIC_DETAILS.get(address.serialize()); - } else { - boolean systemContact = settings.isPresent() && !TextUtils.isEmpty(settings.get().getSystemDisplayName()); - return new RecipientDetails(null, null, systemContact, settings.orNull(), null); - } - } - - private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId, Optional groupRecord, Optional settings, boolean asynchronous) { - - if (!groupRecord.isPresent()) { - groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId.toGroupString()); - } - - if (!settings.isPresent()) { - settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(groupId); - } - - if (groupRecord.isPresent()) { - String title = groupRecord.get().getTitle(); - List
memberAddresses = groupRecord.get().getMembers(); - List members = new LinkedList<>(); - Long avatarId = null; - - for (Address memberAddress : memberAddresses) { - members.add(getRecipient(context, memberAddress, Optional.absent(), Optional.absent(), asynchronous)); - } - - if (!groupId.isMmsGroup() && title == null) { - title = context.getString(R.string.RecipientProvider_unnamed_group); - } - - if (groupRecord.get().getAvatar() != null && groupRecord.get().getAvatar().length > 0) { - avatarId = groupRecord.get().getAvatarId(); - } - - return new RecipientDetails(title, avatarId, false, settings.orNull(), members); - } - - return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, false, settings.orNull(), null); - } - public static class RecipientDetails { @Nullable final String name; @Nullable final String customLabel; @@ -192,19 +82,4 @@ public class RecipientProvider { else this.name = name; } } - - private static class RecipientCache { - - private final Map cache = new SoftHashMap<>(1000); - - public synchronized Recipient get(Address address) { - return cache.get(address); - } - - public synchronized void set(Address address, Recipient recipient) { - cache.put(address, recipient); - } - - } - } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/service/DirectShareService.java b/src/org/thoughtcrime/securesms/service/DirectShareService.java index 06aad3b2f..11ac6b217 100644 --- a/src/org/thoughtcrime/securesms/service/DirectShareService.java +++ b/src/org/thoughtcrime/securesms/service/DirectShareService.java @@ -16,13 +16,10 @@ import android.support.annotation.RequiresApi; import android.util.Log; import org.thoughtcrime.securesms.ShareActivity; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.BitmapUtil; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutionException; @@ -36,56 +33,58 @@ public class DirectShareService extends ChooserTargetService { public List onGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter) { - List results = new LinkedList<>(); - ComponentName componentName = new ComponentName(this, ShareActivity.class); - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this); - Cursor cursor = threadDatabase.getDirectShareList(); - - try { - ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor); - ThreadRecord record; - - while ((record = reader.getNext()) != null && results.size() < 10) { - Recipient recipient = Recipient.from(this, record.getRecipient().getAddress(), false); - String name = recipient.toShortString(); - - Bitmap avatar; - - if (recipient.getContactPhoto(getApplicationContext()) != null) { - try { - avatar = GlideApp.with(this) - .asBitmap() - .load(recipient.getContactPhoto(getApplicationContext())) - .circleCrop() - .submit(getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width), - getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width)) - .get(); - } catch (InterruptedException | ExecutionException e) { - Log.w(TAG, e); - avatar = getFallbackDrawable(recipient); - } - } else { - avatar = getFallbackDrawable(recipient); - } - - Parcel parcel = Parcel.obtain(); - parcel.writeParcelable(recipient.getAddress(), 0); - - Bundle bundle = new Bundle(); - bundle.putLong(ShareActivity.EXTRA_THREAD_ID, record.getThreadId()); - bundle.putByteArray(ShareActivity.EXTRA_ADDRESS_MARSHALLED, parcel.marshall()); - bundle.putInt(ShareActivity.EXTRA_DISTRIBUTION_TYPE, record.getDistributionType()); - bundle.setClassLoader(getClassLoader()); - - results.add(new ChooserTarget(name, Icon.createWithBitmap(avatar), 1.0f, componentName, bundle)); - parcel.recycle(); - - } - - return results; - } finally { - if (cursor != null) cursor.close(); - } + // TODO: return the first 10 entries of the chat List here. + return Collections.EMPTY_LIST; +// List results = new LinkedList<>(); +// ComponentName componentName = new ComponentName(this, ShareActivity.class); +// ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this); +// Cursor cursor = threadDatabase.getDirectShareList(); +// +// try { +// ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor); +// ThreadRecord record; +// +// while ((record = reader.getNext()) != null && results.size() < 10) { +// Recipient recipient = Recipient.from(this, record.getRecipient().getAddress(), false); +// String name = recipient.toShortString(); +// +// Bitmap avatar; +// +// if (recipient.getContactPhoto(getApplicationContext()) != null) { +// try { +// avatar = GlideApp.with(this) +// .asBitmap() +// .load(recipient.getContactPhoto(getApplicationContext())) +// .circleCrop() +// .submit(getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width), +// getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width)) +// .get(); +// } catch (InterruptedException | ExecutionException e) { +// Log.w(TAG, e); +// avatar = getFallbackDrawable(recipient); +// } +// } else { +// avatar = getFallbackDrawable(recipient); +// } +// +// Parcel parcel = Parcel.obtain(); +// parcel.writeParcelable(recipient.getAddress(), 0); +// +// Bundle bundle = new Bundle(); +// bundle.putLong(ShareActivity.EXTRA_THREAD_ID, record.getThreadId()); +// bundle.putByteArray(ShareActivity.EXTRA_ADDRESS_MARSHALLED, parcel.marshall()); +// bundle.putInt(ShareActivity.EXTRA_DISTRIBUTION_TYPE, record.getDistributionType()); +// bundle.setClassLoader(getClassLoader()); +// +// results.add(new ChooserTarget(name, Icon.createWithBitmap(avatar), 1.0f, componentName, bundle)); +// parcel.recycle(); +// +// } +// +// return results; +// } finally { +// if (cursor != null) cursor.close(); +// } } private Bitmap getFallbackDrawable(@NonNull Recipient recipient) {