mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-26 13:01:55 +00:00
Clean up contact queries.
// FREEBIE
This commit is contained in:
parent
d1940fe0f9
commit
704f2b91e2
@ -32,9 +32,10 @@ import android.widget.AdapterView;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
|
||||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
||||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
|
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
|
||||||
|
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -140,11 +141,10 @@ public class PushContactSelectionListFragment extends Fragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
if (getActivity().getIntent().getBooleanExtra(PushContactSelectionActivity.PUSH_ONLY_EXTRA, false)) {
|
boolean pushOnly = getActivity().getIntent().getBooleanExtra(PushContactSelectionActivity.PUSH_ONLY_EXTRA, false);
|
||||||
return ContactAccessor.getInstance().getCursorLoaderForPushContacts(getActivity(), cursorFilter);
|
boolean supportsSms = TextSecurePreferences.isSmsEnabled(getActivity());
|
||||||
} else {
|
|
||||||
return ContactAccessor.getInstance().getCursorLoaderForContacts(getActivity(), cursorFilter);
|
return new ContactsCursorLoader(getActivity(), !pushOnly && supportsSms, cursorFilter);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,13 +23,9 @@ import android.database.MergeCursor;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.ContactsContract;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.provider.ContactsContract.Contacts;
|
import android.provider.ContactsContract.Contacts;
|
||||||
import android.provider.ContactsContract.Data;
|
|
||||||
import android.provider.ContactsContract.PhoneLookup;
|
import android.provider.ContactsContract.PhoneLookup;
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.telephony.PhoneNumberUtils;
|
import android.telephony.PhoneNumberUtils;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
@ -65,35 +61,6 @@ public class ContactAccessor {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CursorLoader getCursorLoaderForContactsWithNumbers(Context context) {
|
|
||||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
|
||||||
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = 1";
|
|
||||||
|
|
||||||
return new CursorLoader(context, uri, null, selection, null,
|
|
||||||
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CursorLoader getCursorLoaderForContactGroups(Context context) {
|
|
||||||
return new CursorLoader(context, ContactsContract.Groups.CONTENT_URI,
|
|
||||||
null, null, null, ContactsContract.Groups.TITLE + " ASC");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Loader<Cursor> getCursorLoaderForContacts(Context context, String filter) {
|
|
||||||
return new ContactsCursorLoader(context, filter, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Loader<Cursor> getCursorLoaderForPushContacts(Context context, String filter) {
|
|
||||||
return new ContactsCursorLoader(context, filter, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cursor getCursorForContactsWithNumbers(Context context) {
|
|
||||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
|
||||||
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = 1";
|
|
||||||
|
|
||||||
return context.getContentResolver().query(uri, null, selection, null,
|
|
||||||
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ContactData> getContactsWithPush(Context context) {
|
public Collection<ContactData> getContactsWithPush(Context context) {
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
final String[] inProjection = new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME};
|
final String[] inProjection = new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME};
|
||||||
@ -136,34 +103,6 @@ public class ContactAccessor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNameForNumber(Context context, String number) {
|
|
||||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
|
|
||||||
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst())
|
|
||||||
return cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupData getGroupData(Context context, Cursor cursor) {
|
|
||||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Groups._ID));
|
|
||||||
String title = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Groups.TITLE));
|
|
||||||
|
|
||||||
return new GroupData(id, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactData getContactData(Context context, Cursor cursor) {
|
|
||||||
return getContactData(context,
|
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(Contacts.DISPLAY_NAME)),
|
|
||||||
cursor.getLong(cursor.getColumnIndexOrThrow(Contacts._ID)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactData getContactData(Context context, Uri uri) {
|
public ContactData getContactData(Context context, Uri uri) {
|
||||||
return getContactData(context, getNameFromContact(context, uri), Long.parseLong(uri.getLastPathSegment()));
|
return getContactData(context, getNameFromContact(context, uri), Long.parseLong(uri.getLastPathSegment()));
|
||||||
}
|
}
|
||||||
@ -193,32 +132,6 @@ public class ContactAccessor {
|
|||||||
return contactData;
|
return contactData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ContactData> getGroupMembership(Context context, long groupId) {
|
|
||||||
LinkedList<ContactData> contacts = new LinkedList<ContactData>();
|
|
||||||
Cursor groupMembership = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
String selection = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID + " = ? AND " +
|
|
||||||
ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + " = ?";
|
|
||||||
String[] args = new String[] {groupId+"",
|
|
||||||
ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE};
|
|
||||||
|
|
||||||
groupMembership = context.getContentResolver().query(Data.CONTENT_URI, null, selection, args, null);
|
|
||||||
|
|
||||||
while (groupMembership != null && groupMembership.moveToNext()) {
|
|
||||||
String displayName = groupMembership.getString(groupMembership.getColumnIndexOrThrow(Data.DISPLAY_NAME));
|
|
||||||
long contactId = groupMembership.getLong(groupMembership.getColumnIndexOrThrow(Data.CONTACT_ID));
|
|
||||||
|
|
||||||
contacts.add(getContactData(context, displayName, contactId));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (groupMembership != null)
|
|
||||||
groupMembership.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getNumbersForThreadSearchFilter(Context context, String constraint) {
|
public List<String> getNumbersForThreadSearchFilter(Context context, String constraint) {
|
||||||
LinkedList<String> numberList = new LinkedList<>();
|
LinkedList<String> numberList = new LinkedList<>();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
@ -258,26 +171,6 @@ public class ContactAccessor {
|
|||||||
return Phone.getTypeLabel(mContext.getResources(), type, label);
|
return Phone.getTypeLabel(mContext.getResources(), type, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getContactIdFromLookupUri(Context context, Uri uri) {
|
|
||||||
Cursor cursor = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
cursor = context.getContentResolver().query(uri,
|
|
||||||
new String[] {ContactsContract.Contacts._ID},
|
|
||||||
null, null, null);
|
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
return cursor.getLong(0);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NumberData implements Parcelable {
|
public static class NumberData implements Parcelable {
|
||||||
|
|
||||||
public static final Parcelable.Creator<NumberData> CREATOR = new Parcelable.Creator<NumberData>() {
|
public static final Parcelable.Creator<NumberData> CREATOR = new Parcelable.Creator<NumberData>() {
|
||||||
@ -313,16 +206,6 @@ public class ContactAccessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GroupData {
|
|
||||||
public final long id;
|
|
||||||
public final String name;
|
|
||||||
|
|
||||||
public GroupData(long id, String name) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ContactData implements Parcelable {
|
public static class ContactData implements Parcelable {
|
||||||
|
|
||||||
public static final Parcelable.Creator<ContactData> CREATOR = new Parcelable.Creator<ContactData>() {
|
public static final Parcelable.Creator<ContactData> CREATOR = new Parcelable.Creator<ContactData>() {
|
||||||
@ -345,13 +228,6 @@ public class ContactAccessor {
|
|||||||
this.numbers = new LinkedList<NumberData>();
|
this.numbers = new LinkedList<NumberData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContactData(long id, String name, List<NumberData> numbers) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.numbers = numbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ContactData(Parcel in) {
|
public ContactData(Parcel in) {
|
||||||
id = in.readLong();
|
id = in.readLong();
|
||||||
name = in.readString();
|
name = in.readString();
|
||||||
|
@ -70,21 +70,21 @@ public class ContactSelectionListAdapter extends CursorAdapter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindView(View view, Context context, Cursor cursor) {
|
public void bindView(View view, Context context, Cursor cursor) {
|
||||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN));
|
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN));
|
||||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
int contactType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.CONTACT_TYPE_COLUMN));
|
||||||
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN));
|
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN));
|
||||||
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
|
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
|
||||||
int numberType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_TYPE_COLUMN));
|
int numberType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_TYPE_COLUMN));
|
||||||
String label = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.LABEL_COLUMN));
|
String label = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.LABEL_COLUMN));
|
||||||
String labelText = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(),
|
String labelText = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(),
|
||||||
numberType, label).toString();
|
numberType, label).toString();
|
||||||
|
|
||||||
int color = (type == ContactsDatabase.PUSH_TYPE) ? drawables.getColor(0, 0xa0000000) :
|
int color = (contactType == ContactsDatabase.PUSH_TYPE) ? drawables.getColor(0, 0xa0000000) :
|
||||||
drawables.getColor(1, 0xff000000);
|
drawables.getColor(1, 0xff000000);
|
||||||
|
|
||||||
|
|
||||||
((ContactSelectionListItem)view).unbind();
|
((ContactSelectionListItem)view).unbind();
|
||||||
((ContactSelectionListItem)view).set(id, type, name, number, labelText, color, multiSelect);
|
((ContactSelectionListItem)view).set(id, contactType, name, number, labelText, color, multiSelect);
|
||||||
((ContactSelectionListItem)view).setChecked(selectedContacts.containsKey(id));
|
((ContactSelectionListItem)view).setChecked(selectedContacts.containsKey(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +105,10 @@ public class ContactSelectionListAdapter extends CursorAdapter
|
|||||||
|
|
||||||
cursor.moveToPosition(i);
|
cursor.moveToPosition(i);
|
||||||
|
|
||||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
int contactType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.CONTACT_TYPE_COLUMN));
|
||||||
|
|
||||||
if (type == ContactsDatabase.PUSH_TYPE) holder.text.setText(R.string.contact_selection_list__header_textsecure_users);
|
if (contactType == ContactsDatabase.PUSH_TYPE) holder.text.setText(R.string.contact_selection_list__header_textsecure_users);
|
||||||
else holder.text.setText(R.string.contact_selection_list__header_other);
|
else holder.text.setText(R.string.contact_selection_list__header_other);
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ public class ContactSelectionListAdapter extends CursorAdapter
|
|||||||
Cursor cursor = getCursor();
|
Cursor cursor = getCursor();
|
||||||
cursor.moveToPosition(i);
|
cursor.moveToPosition(i);
|
||||||
|
|
||||||
return cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
return cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.CONTACT_TYPE_COLUMN));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, String> getSelectedContacts() {
|
public Map<Long, String> getSelectedContacts() {
|
||||||
|
@ -18,12 +18,15 @@ package org.thoughtcrime.securesms.contacts;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.MergeCursor;
|
||||||
import android.support.v4.content.CursorLoader;
|
import android.support.v4.content.CursorLoader;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||||
|
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CursorLoader that initializes a ContactsDatabase instance
|
* CursorLoader that initializes a ContactsDatabase instance
|
||||||
@ -31,47 +34,34 @@ import java.util.concurrent.Semaphore;
|
|||||||
* @author Jake McGinty
|
* @author Jake McGinty
|
||||||
*/
|
*/
|
||||||
public class ContactsCursorLoader extends CursorLoader {
|
public class ContactsCursorLoader extends CursorLoader {
|
||||||
private static final String TAG = ContactsCursorLoader.class.getSimpleName();
|
|
||||||
private static final int DB_PERMITS = 100;
|
|
||||||
|
|
||||||
private final Context context;
|
private static final String TAG = ContactsCursorLoader.class.getSimpleName();
|
||||||
private final String filter;
|
|
||||||
private final boolean pushOnly;
|
|
||||||
private final Semaphore dbSemaphore = new Semaphore(DB_PERMITS);
|
|
||||||
private ContactsDatabase db;
|
|
||||||
|
|
||||||
public ContactsCursorLoader(Context context, String filter, boolean pushOnly) {
|
private final String filter;
|
||||||
|
private boolean includeSmsContacts;
|
||||||
|
|
||||||
|
public ContactsCursorLoader(Context context, boolean includeSmsContacts, String filter) {
|
||||||
super(context);
|
super(context);
|
||||||
this.context = context;
|
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.pushOnly = pushOnly;
|
this.includeSmsContacts = includeSmsContacts;
|
||||||
this.db = new ContactsDatabase(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor loadInBackground() {
|
public Cursor loadInBackground() {
|
||||||
try {
|
ContactsDatabase contactsDatabase = DatabaseFactory.getContactsDatabase(getContext());
|
||||||
dbSemaphore.acquire();
|
ArrayList<Cursor> cursorList = new ArrayList<>(3);
|
||||||
return db.query(filter, pushOnly);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw new AssertionError(ie);
|
|
||||||
} finally {
|
|
||||||
dbSemaphore.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
cursorList.add(contactsDatabase.queryTextSecureContacts(filter));
|
||||||
public void onReset() {
|
|
||||||
Log.w(TAG, "onReset()");
|
if (includeSmsContacts) {
|
||||||
try {
|
cursorList.add(contactsDatabase.querySystemContacts(filter));
|
||||||
dbSemaphore.acquire(DB_PERMITS);
|
|
||||||
db.close();
|
|
||||||
db = new ContactsDatabase(context);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw new AssertionError(ie);
|
|
||||||
} finally {
|
|
||||||
dbSemaphore.release(DB_PERMITS);
|
|
||||||
}
|
}
|
||||||
super.onReset();
|
|
||||||
|
if (!TextUtils.isEmpty(filter) && NumberUtil.isValidSmsOrEmail(filter)) {
|
||||||
|
cursorList.add(contactsDatabase.getNewNumberCursor(filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MergeCursor(cursorList.toArray(new Cursor[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,26 @@ package org.thoughtcrime.securesms.contacts;
|
|||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.OperationApplicationException;
|
import android.content.OperationApplicationException;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.CursorWrapper;
|
import android.database.CursorWrapper;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
import android.database.MergeCursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -55,46 +48,25 @@ import java.util.Set;
|
|||||||
* @author Jake McGinty
|
* @author Jake McGinty
|
||||||
*/
|
*/
|
||||||
public class ContactsDatabase {
|
public class ContactsDatabase {
|
||||||
|
|
||||||
private static final String TAG = ContactsDatabase.class.getSimpleName();
|
private static final String TAG = ContactsDatabase.class.getSimpleName();
|
||||||
private final DatabaseOpenHelper dbHelper;
|
|
||||||
private final Context context;
|
|
||||||
|
|
||||||
public static final String TABLE_NAME = "CONTACTS";
|
public static final String ID_COLUMN = "_id";
|
||||||
public static final String ID_COLUMN = ContactsContract.CommonDataKinds.Phone._ID;
|
public static final String NAME_COLUMN = "name";
|
||||||
public static final String NAME_COLUMN = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME;
|
public static final String NUMBER_COLUMN = "number";
|
||||||
public static final String NUMBER_TYPE_COLUMN = ContactsContract.CommonDataKinds.Phone.TYPE;
|
public static final String NUMBER_TYPE_COLUMN = "number_type";
|
||||||
public static final String NUMBER_COLUMN = ContactsContract.CommonDataKinds.Phone.NUMBER;
|
public static final String LABEL_COLUMN = "label";
|
||||||
public static final String LABEL_COLUMN = ContactsContract.CommonDataKinds.Phone.LABEL;
|
public static final String CONTACT_TYPE_COLUMN = "contact_type";
|
||||||
public static final String TYPE_COLUMN = "type";
|
|
||||||
|
|
||||||
private static final String FILTER_SELECTION = NAME_COLUMN + " LIKE ? OR " + NUMBER_COLUMN + " LIKE ?";
|
|
||||||
private static final String CONTACT_LIST_SORT = NAME_COLUMN + " COLLATE NOCASE ASC";
|
|
||||||
private static final String[] ANDROID_PROJECTION = new String[]{ID_COLUMN,
|
|
||||||
NAME_COLUMN,
|
|
||||||
NUMBER_TYPE_COLUMN,
|
|
||||||
LABEL_COLUMN,
|
|
||||||
NUMBER_COLUMN};
|
|
||||||
|
|
||||||
private static final String[] CONTACTS_PROJECTION = new String[]{ID_COLUMN,
|
|
||||||
NAME_COLUMN,
|
|
||||||
NUMBER_TYPE_COLUMN,
|
|
||||||
LABEL_COLUMN,
|
|
||||||
NUMBER_COLUMN,
|
|
||||||
TYPE_COLUMN};
|
|
||||||
|
|
||||||
public static final int NORMAL_TYPE = 0;
|
public static final int NORMAL_TYPE = 0;
|
||||||
public static final int PUSH_TYPE = 1;
|
public static final int PUSH_TYPE = 1;
|
||||||
public static final int GROUP_TYPE = 2;
|
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
public ContactsDatabase(Context context) {
|
public ContactsDatabase(Context context) {
|
||||||
this.dbHelper = new DatabaseOpenHelper(context);
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
|
||||||
dbHelper.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void setRegisteredUsers(Account account, List<String> e164numbers)
|
public synchronized void setRegisteredUsers(Account account, List<String> e164numbers)
|
||||||
throws RemoteException, OperationApplicationException
|
throws RemoteException, OperationApplicationException
|
||||||
{
|
{
|
||||||
@ -153,6 +125,7 @@ public class ContactsDatabase {
|
|||||||
.withValueBackReference(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID, index)
|
.withValueBackReference(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID, index)
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, e164number)
|
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, e164number)
|
||||||
|
.withValue(ContactsContract.Data.SYNC2, "__TS")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
operations.add(ContentProviderOperation.newInsert(dataUri)
|
operations.add(ContentProviderOperation.newInsert(dataUri)
|
||||||
@ -176,183 +149,184 @@ public class ContactsDatabase {
|
|||||||
.withSelection(BaseColumns._ID + " = ?", new String[] {String.valueOf(rowId)})
|
.withSelection(BaseColumns._ID + " = ?", new String[] {String.valueOf(rowId)})
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NonNull Cursor querySystemContacts(String filter) {
|
||||||
|
Uri uri;
|
||||||
|
|
||||||
public Cursor query(String filter, boolean pushOnly) {
|
|
||||||
// FIXME: This doesn't make sense to me. You pass in pushOnly, but then
|
|
||||||
// conditionally check to see whether other contacts should be included
|
|
||||||
// in the query method itself? I don't think this method should have any
|
|
||||||
// understanding of that stuff.
|
|
||||||
final boolean includeAndroidContacts = !pushOnly && TextSecurePreferences.isSmsEnabled(context);
|
|
||||||
final Cursor localCursor = queryLocalDb(filter);
|
|
||||||
final Cursor androidCursor;
|
|
||||||
final MatrixCursor newNumberCursor;
|
|
||||||
|
|
||||||
if (includeAndroidContacts) {
|
|
||||||
androidCursor = queryAndroidDb(filter);
|
|
||||||
} else {
|
|
||||||
androidCursor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(filter) && NumberUtil.isValidSmsOrEmail(filter)) {
|
|
||||||
newNumberCursor = new MatrixCursor(CONTACTS_PROJECTION, 1);
|
|
||||||
newNumberCursor.addRow(new Object[]{-1L, context.getString(R.string.contact_selection_list__unknown_contact),
|
|
||||||
ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM, "\u21e2", filter, NORMAL_TYPE});
|
|
||||||
} else {
|
|
||||||
newNumberCursor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Cursor> cursors = new ArrayList<Cursor>();
|
|
||||||
if (localCursor != null) cursors.add(localCursor);
|
|
||||||
if (androidCursor != null) cursors.add(androidCursor);
|
|
||||||
if (newNumberCursor != null) cursors.add(newNumberCursor);
|
|
||||||
|
|
||||||
switch (cursors.size()) {
|
|
||||||
case 0: return null;
|
|
||||||
case 1: return cursors.get(0);
|
|
||||||
default: return new MergeCursor(cursors.toArray(new Cursor[]{}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cursor queryAndroidDb(String filter) {
|
|
||||||
final Uri baseUri;
|
|
||||||
if (!TextUtils.isEmpty(filter)) {
|
if (!TextUtils.isEmpty(filter)) {
|
||||||
baseUri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI,
|
uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(filter));
|
||||||
Uri.encode(filter));
|
|
||||||
} else {
|
} else {
|
||||||
baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
||||||
}
|
}
|
||||||
Cursor cursor = context.getContentResolver().query(baseUri, ANDROID_PROJECTION, null, null, CONTACT_LIST_SORT);
|
|
||||||
return cursor == null ? null : new TypedCursorWrapper(cursor);
|
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone._ID,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.NUMBER,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.TYPE,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.LABEL};
|
||||||
|
|
||||||
|
String sort = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE NOCASE ASC";
|
||||||
|
|
||||||
|
Map<String, String> projectionMap = new HashMap<String, String>() {{
|
||||||
|
put(ID_COLUMN, ContactsContract.CommonDataKinds.Phone._ID);
|
||||||
|
put(NAME_COLUMN, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
|
||||||
|
put(NUMBER_COLUMN, ContactsContract.CommonDataKinds.Phone.NUMBER);
|
||||||
|
put(NUMBER_TYPE_COLUMN, ContactsContract.CommonDataKinds.Phone.TYPE);
|
||||||
|
put(LABEL_COLUMN, ContactsContract.CommonDataKinds.Phone.LABEL);
|
||||||
|
}};
|
||||||
|
|
||||||
|
Cursor cursor = context.getContentResolver().query(uri, projection,
|
||||||
|
ContactsContract.Data.SYNC2 + " IS NULL OR " +
|
||||||
|
ContactsContract.Data.SYNC2 + " != ?",
|
||||||
|
new String[] {"__TS"},
|
||||||
|
sort);
|
||||||
|
|
||||||
|
return new ProjectionMappingCursor(cursor, projectionMap,
|
||||||
|
new Pair<String, Object>(CONTACT_TYPE_COLUMN, NORMAL_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cursor queryLocalDb(String filter) {
|
public @NonNull Cursor queryTextSecureContacts(String filter) {
|
||||||
final String selection;
|
String[] projection = new String[] {ContactsContract.Data._ID,
|
||||||
final String[] selectionArgs;
|
ContactsContract.Contacts.DISPLAY_NAME,
|
||||||
final String fuzzyFilter = "%" + filter + "%";
|
ContactsContract.Data.DATA1};
|
||||||
if (!TextUtils.isEmpty(filter)) {
|
|
||||||
selection = FILTER_SELECTION;
|
String sort = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE NOCASE ASC";
|
||||||
selectionArgs = new String[]{fuzzyFilter, fuzzyFilter};
|
|
||||||
|
Map<String, String> projectionMap = new HashMap<String, String>(){{
|
||||||
|
put(ID_COLUMN, ContactsContract.Data._ID);
|
||||||
|
put(NAME_COLUMN, ContactsContract.Contacts.DISPLAY_NAME);
|
||||||
|
put(NUMBER_COLUMN, ContactsContract.Data.DATA1);
|
||||||
|
}};
|
||||||
|
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(filter)) {
|
||||||
|
cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||||
|
projection,
|
||||||
|
ContactsContract.Data.MIMETYPE + " = ?",
|
||||||
|
new String[] {"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact"},
|
||||||
|
sort);
|
||||||
} else {
|
} else {
|
||||||
selection = null;
|
cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||||
selectionArgs = null;
|
projection,
|
||||||
|
ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?",
|
||||||
|
new String[] {"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact",
|
||||||
|
"%" + filter + "%"},
|
||||||
|
sort);
|
||||||
}
|
}
|
||||||
return queryLocalDb(selection, selectionArgs, null);
|
|
||||||
|
return new ProjectionMappingCursor(cursor, projectionMap,
|
||||||
|
new Pair<String, Object>(LABEL_COLUMN, "TextSecure"),
|
||||||
|
new Pair<String, Object>(NUMBER_TYPE_COLUMN, 0),
|
||||||
|
new Pair<String, Object>(CONTACT_TYPE_COLUMN, PUSH_TYPE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cursor queryLocalDb(String selection, String[] selectionArgs, String[] columns) {
|
public Cursor getNewNumberCursor(String filter) {
|
||||||
SQLiteDatabase localDb = dbHelper.getReadableDatabase();
|
MatrixCursor newNumberCursor = new MatrixCursor(new String[] {ID_COLUMN, NAME_COLUMN, NUMBER_COLUMN, NUMBER_TYPE_COLUMN, LABEL_COLUMN, CONTACT_TYPE_COLUMN}, 1);
|
||||||
final Cursor localCursor;
|
newNumberCursor.addRow(new Object[]{-1L, context.getString(R.string.contact_selection_list__unknown_contact),
|
||||||
if (localDb != null) localCursor = localDb.query(TABLE_NAME, columns, selection, selectionArgs, null, null, CONTACT_LIST_SORT);
|
filter, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM,
|
||||||
else localCursor = null;
|
"\u21e2", NORMAL_TYPE});
|
||||||
if (localCursor != null && !localCursor.moveToFirst()) {
|
|
||||||
localCursor.close();
|
return newNumberCursor;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return localCursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DatabaseOpenHelper extends SQLiteOpenHelper {
|
private static class ProjectionMappingCursor extends CursorWrapper {
|
||||||
|
|
||||||
private final Context context;
|
private final Map<String, String> projectionMap;
|
||||||
private SQLiteDatabase mDatabase;
|
private final Pair<String, Object>[] extras;
|
||||||
|
|
||||||
private static final String TABLE_CREATE =
|
@SafeVarargs
|
||||||
"CREATE TABLE " + TABLE_NAME + " (" +
|
public ProjectionMappingCursor(Cursor cursor,
|
||||||
ID_COLUMN + " INTEGER PRIMARY KEY, " +
|
Map<String, String> projectionMap,
|
||||||
NAME_COLUMN + " TEXT, " +
|
Pair<String, Object>... extras)
|
||||||
NUMBER_TYPE_COLUMN + " INTEGER, " +
|
{
|
||||||
LABEL_COLUMN + " TEXT, " +
|
|
||||||
NUMBER_COLUMN + " TEXT, " +
|
|
||||||
TYPE_COLUMN + " INTEGER);";
|
|
||||||
|
|
||||||
DatabaseOpenHelper(Context context) {
|
|
||||||
super(context, null, null, 1);
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db) {
|
|
||||||
Log.d(TAG, "onCreate called for contacts database.");
|
|
||||||
mDatabase = db;
|
|
||||||
mDatabase.execSQL(TABLE_CREATE);
|
|
||||||
if (TextSecurePreferences.isPushRegistered(context)) {
|
|
||||||
try {
|
|
||||||
loadPushUsers();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
Log.e(TAG, "Issue when trying to load push users into memory db.", ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
|
||||||
+ newVersion + ", which will destroy all old data");
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadPushUsers() throws IOException {
|
|
||||||
Log.d(TAG, "populating push users into virtual db.");
|
|
||||||
Collection<ContactAccessor.ContactData> pushUsers = ContactAccessor.getInstance().getContactsWithPush(context);
|
|
||||||
for (ContactAccessor.ContactData user : pushUsers) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put(ID_COLUMN, user.id);
|
|
||||||
values.put(NAME_COLUMN, user.name);
|
|
||||||
values.put(NUMBER_TYPE_COLUMN, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
|
|
||||||
values.put(LABEL_COLUMN, (String)null);
|
|
||||||
values.put(NUMBER_COLUMN, user.numbers.get(0).number);
|
|
||||||
values.put(TYPE_COLUMN, PUSH_TYPE);
|
|
||||||
mDatabase.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE);
|
|
||||||
}
|
|
||||||
Log.d(TAG, "finished populating push users.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TypedCursorWrapper extends CursorWrapper {
|
|
||||||
|
|
||||||
private final int pushColumnIndex;
|
|
||||||
|
|
||||||
public TypedCursorWrapper(Cursor cursor) {
|
|
||||||
super(cursor);
|
super(cursor);
|
||||||
pushColumnIndex = cursor.getColumnCount();
|
this.projectionMap = projectionMap;
|
||||||
|
this.extras = extras;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnCount() {
|
public int getColumnCount() {
|
||||||
return super.getColumnCount() + 1;
|
return super.getColumnCount() + extras.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnIndex(String columnName) {
|
public int getColumnIndex(String columnName) {
|
||||||
if (TYPE_COLUMN.equals(columnName)) return super.getColumnCount();
|
for (int i=0;i<extras.length;i++) {
|
||||||
else return super.getColumnIndex(columnName);
|
if (extras[i].first.equals(columnName)) {
|
||||||
|
return super.getColumnCount() + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getColumnIndex(projectionMap.get(columnName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
|
public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
|
||||||
if (TYPE_COLUMN.equals(columnName)) return super.getColumnCount();
|
int index = getColumnIndex(columnName);
|
||||||
else return super.getColumnIndexOrThrow(columnName);
|
|
||||||
|
if (index == -1) throw new IllegalArgumentException("Bad column name!");
|
||||||
|
else return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName(int columnIndex) {
|
public String getColumnName(int columnIndex) {
|
||||||
if (columnIndex == pushColumnIndex) return TYPE_COLUMN;
|
int baseColumnCount = super.getColumnCount();
|
||||||
else return super.getColumnName(columnIndex);
|
|
||||||
|
if (columnIndex >= baseColumnCount) {
|
||||||
|
int offset = columnIndex - baseColumnCount;
|
||||||
|
return extras[offset].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getReverseProjection(super.getColumnName(columnIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getColumnNames() {
|
public String[] getColumnNames() {
|
||||||
final String[] columns = new String[super.getColumnCount() + 1];
|
String[] names = super.getColumnNames();
|
||||||
System.arraycopy(super.getColumnNames(), 0, columns, 0, super.getColumnCount());
|
String[] allNames = new String[names.length + extras.length];
|
||||||
columns[pushColumnIndex] = TYPE_COLUMN;
|
|
||||||
return columns;
|
for (int i=0;i<names.length;i++) {
|
||||||
|
allNames[i] = getReverseProjection(names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i<extras.length;i++) {
|
||||||
|
allNames[names.length + i] = extras[i].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int columnIndex) {
|
public int getInt(int columnIndex) {
|
||||||
if (columnIndex == pushColumnIndex) return NORMAL_TYPE;
|
if (columnIndex >= super.getColumnCount()) {
|
||||||
else return super.getInt(columnIndex);
|
int offset = columnIndex - super.getColumnCount();
|
||||||
|
return (Integer)extras[offset].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getInt(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) {
|
||||||
|
if (columnIndex >= super.getColumnCount()) {
|
||||||
|
int offset = columnIndex - super.getColumnCount();
|
||||||
|
return (String)extras[offset].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getString(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private @Nullable String getReverseProjection(String columnName) {
|
||||||
|
for (Map.Entry<String, String> entry : projectionMap.entrySet()) {
|
||||||
|
if (entry.getValue().equals(columnName)) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
|
import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
|
||||||
|
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
||||||
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
@ -86,6 +87,7 @@ public class DatabaseFactory {
|
|||||||
private final PushDatabase pushDatabase;
|
private final PushDatabase pushDatabase;
|
||||||
private final GroupDatabase groupDatabase;
|
private final GroupDatabase groupDatabase;
|
||||||
private final RecipientPreferenceDatabase recipientPreferenceDatabase;
|
private final RecipientPreferenceDatabase recipientPreferenceDatabase;
|
||||||
|
private final ContactsDatabase contactsDatabase;
|
||||||
|
|
||||||
public static DatabaseFactory getInstance(Context context) {
|
public static DatabaseFactory getInstance(Context context) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@ -148,6 +150,10 @@ public class DatabaseFactory {
|
|||||||
return getInstance(context).recipientPreferenceDatabase;
|
return getInstance(context).recipientPreferenceDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ContactsDatabase getContactsDatabase(Context context) {
|
||||||
|
return getInstance(context).contactsDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
private DatabaseFactory(Context context) {
|
private DatabaseFactory(Context context) {
|
||||||
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
this.sms = new SmsDatabase(context, databaseHelper);
|
this.sms = new SmsDatabase(context, databaseHelper);
|
||||||
@ -163,6 +169,7 @@ public class DatabaseFactory {
|
|||||||
this.pushDatabase = new PushDatabase(context, databaseHelper);
|
this.pushDatabase = new PushDatabase(context, databaseHelper);
|
||||||
this.groupDatabase = new GroupDatabase(context, databaseHelper);
|
this.groupDatabase = new GroupDatabase(context, databaseHelper);
|
||||||
this.recipientPreferenceDatabase = new RecipientPreferenceDatabase(context, databaseHelper);
|
this.recipientPreferenceDatabase = new RecipientPreferenceDatabase(context, databaseHelper);
|
||||||
|
this.contactsDatabase = new ContactsDatabase(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset(Context context) {
|
public void reset(Context context) {
|
||||||
|
@ -12,6 +12,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
||||||
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
||||||
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
||||||
@ -94,7 +95,7 @@ public class DirectoryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new ContactsDatabase(context).setRegisteredUsers(account.get(), e164numbers);
|
DatabaseFactory.getContactsDatabase(context).setRegisteredUsers(account.get(), e164numbers);
|
||||||
} catch (RemoteException | OperationApplicationException e) {
|
} catch (RemoteException | OperationApplicationException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user