2015-06-09 14:37:20 +00:00
|
|
|
package org.thoughtcrime.securesms.database;
|
|
|
|
|
|
|
|
import android.content.ContentValues;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.database.Cursor;
|
|
|
|
import android.database.sqlite.SQLiteDatabase;
|
|
|
|
import android.database.sqlite.SQLiteOpenHelper;
|
|
|
|
import android.net.Uri;
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
import android.util.Log;
|
|
|
|
|
2017-08-07 04:43:11 +00:00
|
|
|
import com.annimon.stream.Stream;
|
|
|
|
|
2015-06-30 16:16:05 +00:00
|
|
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
2017-08-22 17:44:04 +00:00
|
|
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
2017-08-01 15:56:00 +00:00
|
|
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
2017-08-15 01:11:13 +00:00
|
|
|
import org.thoughtcrime.securesms.util.Base64;
|
2017-08-22 17:44:04 +00:00
|
|
|
import org.whispersystems.libsignal.util.Pair;
|
2016-03-23 17:34:41 +00:00
|
|
|
import org.whispersystems.libsignal.util.guava.Optional;
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-15 01:11:13 +00:00
|
|
|
import java.io.IOException;
|
2017-08-07 21:24:53 +00:00
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.LinkedList;
|
2017-08-07 04:43:11 +00:00
|
|
|
import java.util.List;
|
2017-08-07 21:24:53 +00:00
|
|
|
import java.util.Set;
|
2017-08-07 04:43:11 +00:00
|
|
|
|
2017-08-22 01:37:39 +00:00
|
|
|
public class RecipientDatabase extends Database {
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-22 01:37:39 +00:00
|
|
|
private static final String TAG = RecipientDatabase.class.getSimpleName();
|
2015-06-11 20:00:50 +00:00
|
|
|
private static final String RECIPIENT_PREFERENCES_URI = "content://textsecure/recipients/";
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-07 04:43:11 +00:00
|
|
|
static final String TABLE_NAME = "recipient_preferences";
|
2016-02-06 00:10:33 +00:00
|
|
|
private static final String ID = "_id";
|
2017-08-07 23:47:38 +00:00
|
|
|
static final String ADDRESS = "recipient_ids";
|
2016-02-06 00:10:33 +00:00
|
|
|
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";
|
2016-08-16 03:23:56 +00:00
|
|
|
private static final String EXPIRE_MESSAGES = "expire_messages";
|
2017-08-07 21:24:53 +00:00
|
|
|
private static final String REGISTERED = "registered";
|
2017-08-15 01:11:13 +00:00
|
|
|
private static final String PROFILE_KEY = "profile_key";
|
2017-08-07 22:31:12 +00:00
|
|
|
private static final String SYSTEM_DISPLAY_NAME = "system_display_name";
|
2017-08-15 01:11:13 +00:00
|
|
|
private static final String SIGNAL_PROFILE_NAME = "signal_profile_name";
|
|
|
|
private static final String SIGNAL_PROFILE_AVATAR = "signal_profile_avatar";
|
2017-08-17 04:49:41 +00:00
|
|
|
private static final String PROFILE_SHARING = "profile_sharing_approval";
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-07 04:43:11 +00:00
|
|
|
private static final String[] RECIPIENT_PROJECTION = new String[] {
|
2017-08-15 01:11:13 +00:00
|
|
|
BLOCK, NOTIFICATION, VIBRATE, MUTE_UNTIL, COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, EXPIRE_MESSAGES, REGISTERED,
|
2017-08-17 04:49:41 +00:00
|
|
|
PROFILE_KEY, SYSTEM_DISPLAY_NAME, SIGNAL_PROFILE_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING
|
2017-08-07 04:43:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static final List<String> TYPED_RECIPIENT_PROJECTION = Stream.of(RECIPIENT_PROJECTION)
|
|
|
|
.map(columnName -> TABLE_NAME + "." + columnName)
|
|
|
|
.toList();
|
|
|
|
|
2015-06-09 14:37:20 +00:00
|
|
|
public enum VibrateState {
|
|
|
|
DEFAULT(0), ENABLED(1), DISABLED(2);
|
|
|
|
|
|
|
|
private final int id;
|
|
|
|
|
|
|
|
VibrateState(int id) {
|
|
|
|
this.id = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getId() {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static VibrateState fromId(int id) {
|
|
|
|
return values()[id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public enum RegisteredState {
|
|
|
|
UNKNOWN(0), REGISTERED(1), NOT_REGISTERED(2);
|
|
|
|
|
|
|
|
private final int id;
|
|
|
|
|
|
|
|
RegisteredState(int id) {
|
|
|
|
this.id = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getId() {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static RegisteredState fromId(int id) {
|
|
|
|
return values()[id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-09 14:37:20 +00:00
|
|
|
public static final String CREATE_TABLE =
|
|
|
|
"CREATE TABLE " + TABLE_NAME +
|
|
|
|
" (" + ID + " INTEGER PRIMARY KEY, " +
|
2017-08-01 15:56:00 +00:00
|
|
|
ADDRESS + " TEXT UNIQUE, " +
|
2015-06-09 14:37:20 +00:00
|
|
|
BLOCK + " INTEGER DEFAULT 0," +
|
|
|
|
NOTIFICATION + " TEXT DEFAULT NULL, " +
|
|
|
|
VIBRATE + " INTEGER DEFAULT " + VibrateState.DEFAULT.getId() + ", " +
|
2015-06-23 22:10:50 +00:00
|
|
|
MUTE_UNTIL + " INTEGER DEFAULT 0, " +
|
2015-10-14 04:44:01 +00:00
|
|
|
COLOR + " TEXT DEFAULT NULL, " +
|
2016-02-06 00:10:33 +00:00
|
|
|
SEEN_INVITE_REMINDER + " INTEGER DEFAULT 0, " +
|
2016-08-16 03:23:56 +00:00
|
|
|
DEFAULT_SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
|
2017-08-07 21:24:53 +00:00
|
|
|
EXPIRE_MESSAGES + " INTEGER DEFAULT 0, " +
|
2017-08-07 22:31:12 +00:00
|
|
|
REGISTERED + " INTEGER DEFAULT 0, " +
|
2017-08-15 01:11:13 +00:00
|
|
|
SYSTEM_DISPLAY_NAME + " TEXT DEFAULT NULL, " +
|
|
|
|
PROFILE_KEY + " TEXT DEFAULT NULL, " +
|
|
|
|
SIGNAL_PROFILE_NAME + " TEXT DEFAULT NULL, " +
|
2017-08-17 04:49:41 +00:00
|
|
|
SIGNAL_PROFILE_AVATAR + " TEXT DEFAULT NULL, " +
|
|
|
|
PROFILE_SHARING + " INTEGER DEFAULT 0);";
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-22 01:37:39 +00:00
|
|
|
public RecipientDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
2015-06-09 14:37:20 +00:00
|
|
|
super(context, databaseHelper);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Cursor getBlocked() {
|
|
|
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
Cursor cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS}, BLOCK + " = 1",
|
2015-06-11 20:00:50 +00:00
|
|
|
null, null, null, null, null);
|
|
|
|
cursor.setNotificationUri(context.getContentResolver(), Uri.parse(RECIPIENT_PREFERENCES_URI));
|
|
|
|
|
|
|
|
return cursor;
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2016-08-26 23:53:23 +00:00
|
|
|
public BlockedReader readerForBlocked(Cursor cursor) {
|
|
|
|
return new BlockedReader(context, cursor);
|
|
|
|
}
|
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
|
2017-08-22 01:47:37 +00:00
|
|
|
public Optional<RecipientSettings> getRecipientSettings(@NonNull Address address) {
|
2015-06-09 14:37:20 +00:00
|
|
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
|
|
|
Cursor cursor = null;
|
|
|
|
|
|
|
|
try {
|
2017-08-01 15:56:00 +00:00
|
|
|
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null);
|
2015-06-09 14:37:20 +00:00
|
|
|
|
|
|
|
if (cursor != null && cursor.moveToNext()) {
|
2017-08-22 17:44:04 +00:00
|
|
|
return getRecipientSettings(cursor);
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Optional.absent();
|
|
|
|
} finally {
|
|
|
|
if (cursor != null) cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
Optional<RecipientSettings> getRecipientSettings(@NonNull Cursor cursor) {
|
2017-08-07 04:43:11 +00:00
|
|
|
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
|
|
|
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
|
|
|
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
|
|
|
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
|
|
|
|
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
|
|
|
|
Uri notificationUri = notification == null ? null : Uri.parse(notification);
|
|
|
|
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));
|
2017-08-22 17:44:04 +00:00
|
|
|
int registeredState = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED));
|
2017-08-15 01:11:13 +00:00
|
|
|
String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY));
|
|
|
|
String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME));
|
|
|
|
String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME));
|
|
|
|
String signalProfileAvatar = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_AVATAR));
|
2017-08-22 17:44:04 +00:00
|
|
|
boolean profileSharing = cursor.getInt(cursor.getColumnIndexOrThrow(PROFILE_SHARING)) == 1;
|
2017-08-07 04:43:11 +00:00
|
|
|
|
|
|
|
MaterialColor color;
|
2017-08-15 01:11:13 +00:00
|
|
|
byte[] profileKey = null;
|
2017-08-07 04:43:11 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
color = serializedColor == null ? null : MaterialColor.fromSerialized(serializedColor);
|
|
|
|
} catch (MaterialColor.UnknownColorException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
color = null;
|
|
|
|
}
|
|
|
|
|
2017-08-15 01:11:13 +00:00
|
|
|
if (profileKeyString != null) {
|
|
|
|
try {
|
|
|
|
profileKey = Base64.decode(profileKeyString);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
profileKey = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 01:47:37 +00:00
|
|
|
return Optional.of(new RecipientSettings(blocked, muteUntil,
|
|
|
|
VibrateState.fromId(vibrateState),
|
|
|
|
notificationUri, color, seenInviteReminder,
|
2017-08-22 17:44:04 +00:00
|
|
|
defaultSubscriptionId, expireMessages,
|
|
|
|
RegisteredState.fromId(registeredState),
|
2017-08-22 01:47:37 +00:00
|
|
|
profileKey, systemDisplayName, signalProfileName,
|
|
|
|
signalProfileAvatar, profileSharing));
|
2017-08-07 04:43:11 +00:00
|
|
|
}
|
|
|
|
|
2017-08-16 02:23:42 +00:00
|
|
|
public BulkOperationsHandle resetAllDisplayNames() {
|
|
|
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
|
|
|
database.beginTransaction();
|
|
|
|
|
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(SYSTEM_DISPLAY_NAME, (String)null);
|
|
|
|
|
|
|
|
database.update(TABLE_NAME, contentValues, null, null);
|
|
|
|
|
|
|
|
return new BulkOperationsHandle(database);
|
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setColor(@NonNull Recipient recipient, @NonNull MaterialColor color) {
|
2015-06-23 22:10:50 +00:00
|
|
|
ContentValues values = new ContentValues();
|
2015-06-30 16:16:05 +00:00
|
|
|
values.put(COLOR, color.serialize());
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setColor(color);
|
2015-06-23 22:10:50 +00:00
|
|
|
}
|
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
public void setDefaultSubscriptionId(@NonNull Recipient recipient, int defaultSubscriptionId) {
|
2016-02-06 00:10:33 +00:00
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
values.put(DEFAULT_SUBSCRIPTION_ID, defaultSubscriptionId);
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setDefaultSubscriptionId(Optional.of(defaultSubscriptionId));
|
2016-02-06 00:10:33 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setBlocked(@NonNull Recipient recipient, boolean blocked) {
|
2015-06-09 14:37:20 +00:00
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
values.put(BLOCK, blocked ? 1 : 0);
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setBlocked(blocked);
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setRingtone(@NonNull Recipient recipient, @Nullable Uri notification) {
|
2015-06-09 14:37:20 +00:00
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
values.put(NOTIFICATION, notification == null ? null : notification.toString());
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setRingtone(notification);
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setVibrate(@NonNull Recipient recipient, @NonNull VibrateState enabled) {
|
2015-06-09 14:37:20 +00:00
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
values.put(VIBRATE, enabled.getId());
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setVibrate(enabled);
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setMuted(@NonNull Recipient recipient, long until) {
|
2015-06-09 14:37:20 +00:00
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
values.put(MUTE_UNTIL, until);
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setMuted(until);
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setSeenInviteReminder(@NonNull Recipient recipient, boolean seen) {
|
2015-10-14 04:44:01 +00:00
|
|
|
ContentValues values = new ContentValues(1);
|
|
|
|
values.put(SEEN_INVITE_REMINDER, seen ? 1 : 0);
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setHasSeenInviteReminder(seen);
|
2015-10-14 04:44:01 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setExpireMessages(@NonNull Recipient recipient, int expiration) {
|
2017-08-01 15:56:00 +00:00
|
|
|
recipient.setExpireMessages(expiration);
|
2016-08-16 03:23:56 +00:00
|
|
|
|
|
|
|
ContentValues values = new ContentValues(1);
|
|
|
|
values.put(EXPIRE_MESSAGES, expiration);
|
2017-08-07 22:31:12 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
2017-08-22 17:44:04 +00:00
|
|
|
recipient.resolve().setExpireMessages(expiration);
|
2017-08-07 22:31:12 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setProfileKey(@NonNull Recipient recipient, @Nullable byte[] profileKey) {
|
2017-08-15 01:11:13 +00:00
|
|
|
ContentValues values = new ContentValues(1);
|
|
|
|
values.put(PROFILE_KEY, profileKey == null ? null : Base64.encodeBytes(profileKey));
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), values);
|
|
|
|
recipient.resolve().setProfileKey(profileKey);
|
2017-08-15 01:11:13 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setProfileName(@NonNull Recipient recipient, @Nullable String profileName) {
|
2017-08-15 01:11:13 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(SIGNAL_PROFILE_NAME, profileName);
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), contentValues);
|
|
|
|
recipient.resolve().setProfileName(profileName);
|
2017-08-15 01:11:13 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setProfileAvatar(@NonNull Recipient recipient, @Nullable String profileAvatar) {
|
2017-08-15 01:11:13 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(SIGNAL_PROFILE_AVATAR, profileAvatar);
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), contentValues);
|
|
|
|
recipient.resolve().setProfileAvatar(profileAvatar);
|
2017-08-15 01:11:13 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setProfileSharing(@NonNull Recipient recipient, boolean enabled) {
|
2017-08-17 04:49:41 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(PROFILE_SHARING, enabled ? 1 : 0);
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), contentValues);
|
|
|
|
recipient.setProfileSharing(enabled);
|
2017-08-17 04:49:41 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public Set<Recipient> getAllRecipients() {
|
2017-08-07 21:24:53 +00:00
|
|
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
2017-08-22 17:44:04 +00:00
|
|
|
Set<Recipient> results = new HashSet<>();
|
2017-08-07 21:24:53 +00:00
|
|
|
|
|
|
|
try (Cursor cursor = db.query(TABLE_NAME, new String[] {ADDRESS}, null, null, null, null, null)) {
|
|
|
|
while (cursor != null && cursor.moveToNext()) {
|
2017-08-22 17:44:04 +00:00
|
|
|
results.add(Recipient.from(context, Address.fromExternal(context, cursor.getString(0)), true));
|
2017-08-07 21:24:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setRegistered(@NonNull Recipient recipient, RegisteredState registeredState) {
|
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(REGISTERED, registeredState.getId());
|
|
|
|
updateOrInsert(recipient.getAddress(), contentValues);
|
|
|
|
recipient.setRegistered(registeredState);
|
|
|
|
}
|
2017-08-07 21:24:53 +00:00
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setRegistered(@NonNull List<Recipient> activeRecipients,
|
|
|
|
@NonNull List<Recipient> inactiveRecipients)
|
|
|
|
{
|
|
|
|
for (Recipient activeRecipient : activeRecipients) {
|
2017-08-16 02:23:42 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
2017-08-22 17:44:04 +00:00
|
|
|
contentValues.put(REGISTERED, RegisteredState.REGISTERED.getId());
|
2017-08-07 21:24:53 +00:00
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(activeRecipient.getAddress(), contentValues);
|
|
|
|
activeRecipient.setRegistered(RegisteredState.REGISTERED);
|
2017-08-07 21:24:53 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
for (Recipient inactiveRecipient : inactiveRecipients) {
|
2017-08-16 02:23:42 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
2017-08-22 17:44:04 +00:00
|
|
|
contentValues.put(REGISTERED, RegisteredState.NOT_REGISTERED.getId());
|
2017-08-07 21:24:53 +00:00
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(inactiveRecipient.getAddress(), contentValues);
|
|
|
|
inactiveRecipient.setRegistered(RegisteredState.NOT_REGISTERED);
|
2017-08-07 21:24:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<Address> getRegistered() {
|
|
|
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
|
|
|
List<Address> results = new LinkedList<>();
|
|
|
|
|
|
|
|
try (Cursor cursor = db.query(TABLE_NAME, new String[] {ADDRESS}, REGISTERED + " = ?", new String[] {"1"}, null, null, null)) {
|
|
|
|
while (cursor != null && cursor.moveToNext()) {
|
|
|
|
results.add(Address.fromSerialized(cursor.getString(0)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2017-08-07 22:31:12 +00:00
|
|
|
private void updateOrInsert(Address address, ContentValues contentValues) {
|
2015-06-09 14:37:20 +00:00
|
|
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
|
|
|
|
|
|
|
database.beginTransaction();
|
|
|
|
|
2017-08-16 02:23:42 +00:00
|
|
|
updateOrInsert(database, address, contentValues);
|
|
|
|
|
|
|
|
database.setTransactionSuccessful();
|
|
|
|
database.endTransaction();
|
|
|
|
|
|
|
|
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateOrInsert(SQLiteDatabase database, Address address, ContentValues contentValues) {
|
2017-08-01 15:56:00 +00:00
|
|
|
int updated = database.update(TABLE_NAME, contentValues, ADDRESS + " = ?",
|
2017-08-07 22:31:12 +00:00
|
|
|
new String[] {address.serialize()});
|
2015-06-09 14:37:20 +00:00
|
|
|
|
|
|
|
if (updated < 1) {
|
2017-08-07 22:31:12 +00:00
|
|
|
contentValues.put(ADDRESS, address.serialize());
|
2015-06-09 14:37:20 +00:00
|
|
|
database.insert(TABLE_NAME, null, contentValues);
|
|
|
|
}
|
2017-08-16 02:23:42 +00:00
|
|
|
}
|
2015-06-09 14:37:20 +00:00
|
|
|
|
2017-08-16 02:23:42 +00:00
|
|
|
public class BulkOperationsHandle {
|
2015-06-11 20:00:50 +00:00
|
|
|
|
2017-08-16 02:23:42 +00:00
|
|
|
private final SQLiteDatabase database;
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
private final List<Pair<Recipient, String>> pendingDisplayNames = new LinkedList<>();
|
|
|
|
|
|
|
|
BulkOperationsHandle(SQLiteDatabase database) {
|
2017-08-16 02:23:42 +00:00
|
|
|
this.database = database;
|
|
|
|
}
|
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public void setDisplayName(@NonNull Recipient recipient, @Nullable String displayName) {
|
2017-08-16 02:23:42 +00:00
|
|
|
ContentValues contentValues = new ContentValues(1);
|
|
|
|
contentValues.put(SYSTEM_DISPLAY_NAME, displayName);
|
2017-08-22 17:44:04 +00:00
|
|
|
updateOrInsert(recipient.getAddress(), contentValues);
|
|
|
|
pendingDisplayNames.add(new Pair<>(recipient, displayName));
|
2017-08-16 02:23:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void finish() {
|
|
|
|
database.setTransactionSuccessful();
|
|
|
|
database.endTransaction();
|
2017-08-22 17:44:04 +00:00
|
|
|
|
|
|
|
Stream.of(pendingDisplayNames).forEach(pair -> pair.first().resolve().setSystemDisplayName(pair.second()));
|
|
|
|
|
2017-08-16 02:23:42 +00:00
|
|
|
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
|
|
|
}
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-08-22 01:47:37 +00:00
|
|
|
public static class RecipientSettings {
|
2017-08-22 17:44:04 +00:00
|
|
|
private final boolean blocked;
|
|
|
|
private final long muteUntil;
|
|
|
|
private final VibrateState vibrateState;
|
|
|
|
private final Uri notification;
|
|
|
|
private final MaterialColor color;
|
|
|
|
private final boolean seenInviteReminder;
|
|
|
|
private final int defaultSubscriptionId;
|
|
|
|
private final int expireMessages;
|
|
|
|
private final RegisteredState registered;
|
|
|
|
private final byte[] profileKey;
|
|
|
|
private final String systemDisplayName;
|
|
|
|
private final String signalProfileName;
|
|
|
|
private final String signalProfileAvatar;
|
|
|
|
private final boolean profileSharing;
|
2015-06-30 16:16:05 +00:00
|
|
|
|
2017-08-22 01:47:37 +00:00
|
|
|
RecipientSettings(boolean blocked, long muteUntil,
|
|
|
|
@NonNull VibrateState vibrateState,
|
|
|
|
@Nullable Uri notification,
|
|
|
|
@Nullable MaterialColor color,
|
|
|
|
boolean seenInviteReminder,
|
|
|
|
int defaultSubscriptionId,
|
|
|
|
int expireMessages,
|
2017-08-22 17:44:04 +00:00
|
|
|
@NonNull RegisteredState registered,
|
2017-08-22 01:47:37 +00:00
|
|
|
@Nullable byte[] profileKey,
|
|
|
|
@Nullable String systemDisplayName,
|
|
|
|
@Nullable String signalProfileName,
|
|
|
|
@Nullable String signalProfileAvatar,
|
|
|
|
boolean profileSharing)
|
2015-06-23 22:10:50 +00:00
|
|
|
{
|
2016-02-06 00:10:33 +00:00
|
|
|
this.blocked = blocked;
|
|
|
|
this.muteUntil = muteUntil;
|
|
|
|
this.vibrateState = vibrateState;
|
|
|
|
this.notification = notification;
|
|
|
|
this.color = color;
|
|
|
|
this.seenInviteReminder = seenInviteReminder;
|
|
|
|
this.defaultSubscriptionId = defaultSubscriptionId;
|
2016-08-16 03:23:56 +00:00
|
|
|
this.expireMessages = expireMessages;
|
2017-08-07 21:24:53 +00:00
|
|
|
this.registered = registered;
|
2017-08-15 01:11:13 +00:00
|
|
|
this.profileKey = profileKey;
|
2017-08-07 22:31:12 +00:00
|
|
|
this.systemDisplayName = systemDisplayName;
|
2017-08-15 01:11:13 +00:00
|
|
|
this.signalProfileName = signalProfileName;
|
|
|
|
this.signalProfileAvatar = signalProfileAvatar;
|
2017-08-17 04:49:41 +00:00
|
|
|
this.profileSharing = profileSharing;
|
2015-06-23 22:10:50 +00:00
|
|
|
}
|
|
|
|
|
2015-06-30 16:16:05 +00:00
|
|
|
public @Nullable MaterialColor getColor() {
|
2015-06-23 22:10:50 +00:00
|
|
|
return color;
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isBlocked() {
|
|
|
|
return blocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getMuteUntil() {
|
|
|
|
return muteUntil;
|
|
|
|
}
|
|
|
|
|
|
|
|
public @NonNull VibrateState getVibrateState() {
|
|
|
|
return vibrateState;
|
|
|
|
}
|
|
|
|
|
|
|
|
public @Nullable Uri getRingtone() {
|
|
|
|
return notification;
|
|
|
|
}
|
2015-10-14 04:44:01 +00:00
|
|
|
|
|
|
|
public boolean hasSeenInviteReminder() {
|
|
|
|
return seenInviteReminder;
|
|
|
|
}
|
2016-02-06 00:10:33 +00:00
|
|
|
|
|
|
|
public Optional<Integer> getDefaultSubscriptionId() {
|
|
|
|
return defaultSubscriptionId != -1 ? Optional.of(defaultSubscriptionId) : Optional.<Integer>absent();
|
|
|
|
}
|
2016-08-16 03:23:56 +00:00
|
|
|
|
|
|
|
public int getExpireMessages() {
|
|
|
|
return expireMessages;
|
|
|
|
}
|
2017-08-07 21:24:53 +00:00
|
|
|
|
2017-08-22 17:44:04 +00:00
|
|
|
public RegisteredState getRegistered() {
|
2017-08-07 21:24:53 +00:00
|
|
|
return registered;
|
|
|
|
}
|
2017-08-07 22:31:12 +00:00
|
|
|
|
2017-08-15 01:11:13 +00:00
|
|
|
public byte[] getProfileKey() {
|
|
|
|
return profileKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public @Nullable String getSystemDisplayName() {
|
2017-08-07 22:31:12 +00:00
|
|
|
return systemDisplayName;
|
|
|
|
}
|
2017-08-15 01:11:13 +00:00
|
|
|
|
|
|
|
public @Nullable String getProfileName() {
|
|
|
|
return signalProfileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public @Nullable String getProfileAvatar() {
|
|
|
|
return signalProfileAvatar;
|
|
|
|
}
|
2017-08-17 04:49:41 +00:00
|
|
|
|
|
|
|
public boolean isProfileSharing() {
|
|
|
|
return profileSharing;
|
|
|
|
}
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|
2016-08-26 23:53:23 +00:00
|
|
|
|
|
|
|
public static class BlockedReader {
|
|
|
|
|
|
|
|
private final Context context;
|
|
|
|
private final Cursor cursor;
|
|
|
|
|
2017-08-02 18:04:10 +00:00
|
|
|
BlockedReader(Context context, Cursor cursor) {
|
2016-08-26 23:53:23 +00:00
|
|
|
this.context = context;
|
|
|
|
this.cursor = cursor;
|
|
|
|
}
|
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
public @NonNull Recipient getCurrent() {
|
|
|
|
String serialized = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS));
|
2017-08-22 01:32:38 +00:00
|
|
|
return Recipient.from(context, Address.fromSerialized(serialized), false);
|
2016-08-26 23:53:23 +00:00
|
|
|
}
|
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
public @Nullable Recipient getNext() {
|
2016-08-26 23:53:23 +00:00
|
|
|
if (!cursor.moveToNext()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return getCurrent();
|
|
|
|
}
|
|
|
|
}
|
2015-06-09 14:37:20 +00:00
|
|
|
}
|