mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-21 00:21:30 +00:00
Access all RecipientDatabase settings directly from Recipient
// FREEBIE
This commit is contained in:
parent
d1790dfe17
commit
f17af19d09
@ -108,8 +108,7 @@ import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
|||||||
import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientPreferenceEvent;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||||
@ -142,7 +141,6 @@ import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
|||||||
import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
||||||
import org.thoughtcrime.securesms.util.Dialogs;
|
import org.thoughtcrime.securesms.util.Dialogs;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper.Capability;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.ExpirationUtil;
|
import org.thoughtcrime.securesms.util.ExpirationUtil;
|
||||||
@ -574,10 +572,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
|
DatabaseFactory.getRecipientDatabase(ConversationActivity.this).setExpireMessages(recipient, expirationTime);
|
||||||
.setExpireMessages(recipient, expirationTime);
|
|
||||||
recipient.setExpireMessages(expirationTime);
|
|
||||||
|
|
||||||
OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(getRecipient(), System.currentTimeMillis(), expirationTime * 1000);
|
OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(getRecipient(), System.currentTimeMillis(), expirationTime * 1000);
|
||||||
MessageSender.send(ConversationActivity.this, masterSecret, outgoingMessage, threadId, false, null);
|
MessageSender.send(ConversationActivity.this, masterSecret, outgoingMessage, threadId, false, null);
|
||||||
|
|
||||||
@ -639,8 +634,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
.setPositiveButton(R.string.ConversationActivity_unblock, new DialogInterface.OnClickListener() {
|
.setPositiveButton(R.string.ConversationActivity_unblock, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
recipient.setBlocked(false);
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
@ -1014,17 +1007,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
protected boolean[] doInBackground(Recipient... params) {
|
protected boolean[] doInBackground(Recipient... params) {
|
||||||
Context context = ConversationActivity.this;
|
Context context = ConversationActivity.this;
|
||||||
Recipient recipient = params[0];
|
Recipient recipient = params[0];
|
||||||
Capability capability = DirectoryHelper.getUserCapabilities(context, recipient);
|
RegisteredState registeredState = recipient.resolve().getRegistered();
|
||||||
|
|
||||||
if (capability == Capability.UNKNOWN) {
|
if (registeredState == RegisteredState.UNKNOWN) {
|
||||||
try {
|
try {
|
||||||
capability = DirectoryHelper.refreshDirectoryFor(context, masterSecret, recipient);
|
registeredState = DirectoryHelper.refreshDirectoryFor(context, masterSecret, recipient);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new boolean[] {capability == Capability.SUPPORTED, Util.isDefaultSmsProvider(context)};
|
return new boolean[] {registeredState == RegisteredState.REGISTERED, Util.isDefaultSmsProvider(context)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1041,11 +1034,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onSecurityUpdated() {
|
private void onSecurityUpdated() {
|
||||||
updateRecipientPreferences();
|
updateInviteReminder(recipient.hasSeenInviteReminder());
|
||||||
}
|
updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId());
|
||||||
|
|
||||||
private void updateRecipientPreferences() {
|
|
||||||
new RecipientPreferencesTask().execute(recipient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateInviteReminder(boolean seenInvite) {
|
protected void updateInviteReminder(boolean seenInvite) {
|
||||||
@ -1284,19 +1274,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
titleView.setVerified(identityRecords.isVerified());
|
titleView.setVerified(identityRecords.isVerified());
|
||||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||||
setActionBarColor(recipient.getColor());
|
setActionBarColor(recipient.getColor());
|
||||||
|
updateInviteReminder(recipient.hasSeenInviteReminder());
|
||||||
|
updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId());
|
||||||
|
initializeSecurity(isSecureText, isDefaultSms);
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
updateRecipientPreferences();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
||||||
public void onRecipientPreferenceUpdate(final RecipientPreferenceEvent event) {
|
|
||||||
if (event.getRecipient().getAddress().equals(this.recipient.getAddress())) {
|
|
||||||
new RecipientPreferencesTask().execute(this.recipient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onIdentityRecordUpdate(final IdentityRecord event) {
|
public void onIdentityRecordUpdate(final IdentityRecord event) {
|
||||||
initializeIdentityRecords();
|
initializeIdentityRecords();
|
||||||
@ -1652,7 +1637,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
@Override
|
@Override
|
||||||
protected Long doInBackground(OutgoingMediaMessage... messages) {
|
protected Long doInBackground(OutgoingMediaMessage... messages) {
|
||||||
if (initiating) {
|
if (initiating) {
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getAddress(), true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
||||||
@ -1692,7 +1677,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
@Override
|
@Override
|
||||||
protected Long doInBackground(OutgoingTextMessage... messages) {
|
protected Long doInBackground(OutgoingTextMessage... messages) {
|
||||||
if (initiatingConversation) {
|
if (initiatingConversation) {
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getAddress(), true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
||||||
@ -1989,27 +1974,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
updateToggleButtonState();
|
updateToggleButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RecipientPreferencesTask extends AsyncTask<Recipient, Void, Pair<Recipient,RecipientSettings>> {
|
|
||||||
@Override
|
|
||||||
protected Pair<Recipient, RecipientSettings> doInBackground(Recipient... recipient) {
|
|
||||||
if (recipient.length != 1 || recipient[0] == null) {
|
|
||||||
throw new AssertionError("task needs exactly one Recipients object");
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<RecipientSettings> prefs = DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
|
|
||||||
.getRecipientSettings(recipient[0].getAddress());
|
|
||||||
return new Pair<>(recipient[0], prefs.orNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(@NonNull Pair<Recipient, RecipientSettings> result) {
|
|
||||||
if (result.first == recipient) {
|
|
||||||
updateInviteReminder(result.second != null && result.second.hasSeenInviteReminder());
|
|
||||||
updateDefaultSubscriptionId(result.second != null ? result.second.getDefaultSubscriptionId() : Optional.<Integer>absent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UnverifiedDismissedListener implements UnverifiedBannerView.DismissListener {
|
private class UnverifiedDismissedListener implements UnverifiedBannerView.DismissListener {
|
||||||
@Override
|
@Override
|
||||||
public void onDismissed(final List<IdentityRecord> unverifiedIdentities) {
|
public void onDismissed(final List<IdentityRecord> unverifiedIdentities) {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
package org.thoughtcrime.securesms;
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -54,7 +53,7 @@ import org.thoughtcrime.securesms.database.Address;
|
|||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager;
|
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
|
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
|
||||||
@ -167,9 +166,8 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isActiveInDirectory(Context context, Recipient recipient) {
|
private static boolean isActiveInDirectory(Recipient recipient) {
|
||||||
Optional<RecipientSettings> preferences = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(recipient.getAddress());
|
return recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED;
|
||||||
return preferences.isPresent() && preferences.get().isRegistered();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSelectedContacts(@NonNull Recipient... recipients) {
|
private void addSelectedContacts(@NonNull Recipient... recipients) {
|
||||||
@ -495,7 +493,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||||||
final List<Result> results = new LinkedList<>();
|
final List<Result> results = new LinkedList<>();
|
||||||
|
|
||||||
for (Recipient recipient : recipients) {
|
for (Recipient recipient : recipients) {
|
||||||
boolean isPush = isActiveInDirectory(activity, recipient);
|
boolean isPush = isActiveInDirectory(recipient);
|
||||||
|
|
||||||
if (failIfNotPush && !isPush) {
|
if (failIfNotPush && !isPush) {
|
||||||
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
||||||
|
@ -231,8 +231,7 @@ public class InviteActivity extends PassphraseRequiredActionBarActivity implemen
|
|||||||
|
|
||||||
for (String number : numbers) {
|
for (String number : numbers) {
|
||||||
Recipient recipient = Recipient.from(context, Address.fromExternal(context, number), false);
|
Recipient recipient = Recipient.from(context, Address.fromExternal(context, number), false);
|
||||||
Optional<RecipientSettings> settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(recipient.getAddress());
|
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
|
||||||
int subscriptionId = settings.isPresent() ? settings.get().getDefaultSubscriptionId().or(-1) : -1;
|
|
||||||
|
|
||||||
MessageSender.send(context, masterSecret, new OutgoingTextMessage(recipient, message, subscriptionId), -1L, true, null);
|
MessageSender.send(context, masterSecret, new OutgoingTextMessage(recipient, message, subscriptionId), -1L, true, null);
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||||
@ -43,7 +44,6 @@ import org.thoughtcrime.securesms.preferences.AdvancedRingtonePreference;
|
|||||||
import org.thoughtcrime.securesms.preferences.ColorPreference;
|
import org.thoughtcrime.securesms.preferences.ColorPreference;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
@ -350,8 +350,6 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
uri = Uri.parse(value);
|
uri = Uri.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
recipient.setRingtone(uri);
|
|
||||||
|
|
||||||
new AsyncTask<Uri, Void, Void>() {
|
new AsyncTask<Uri, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Uri... params) {
|
protected Void doInBackground(Uri... params) {
|
||||||
@ -371,8 +369,6 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
int value = Integer.parseInt((String) newValue);
|
int value = Integer.parseInt((String) newValue);
|
||||||
final VibrateState vibrateState = VibrateState.fromId(value);
|
final VibrateState vibrateState = VibrateState.fromId(value);
|
||||||
|
|
||||||
recipient.setVibrate(vibrateState);
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
@ -397,16 +393,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
if (selectedColor == null) return true;
|
if (selectedColor == null) return true;
|
||||||
|
|
||||||
if (preference.isEnabled() && !currentColor.equals(selectedColor)) {
|
if (preference.isEnabled() && !currentColor.equals(selectedColor)) {
|
||||||
recipient.setColor(selectedColor);
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
Context context = getActivity();
|
Context context = getActivity();
|
||||||
DatabaseFactory.getRecipientDatabase(context)
|
DatabaseFactory.getRecipientDatabase(context).setColor(recipient, selectedColor);
|
||||||
.setColor(recipient, selectedColor);
|
|
||||||
|
|
||||||
if (DirectoryHelper.getUserCapabilities(context, recipient) == DirectoryHelper.Capability.SUPPORTED) {
|
if (recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED) {
|
||||||
ApplicationContext.getInstance(context)
|
ApplicationContext.getInstance(context)
|
||||||
.getJobManager()
|
.getJobManager()
|
||||||
.add(new MultiDeviceContactUpdateJob(context, recipient.getAddress()));
|
.add(new MultiDeviceContactUpdateJob(context, recipient.getAddress()));
|
||||||
@ -516,8 +509,6 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setBlocked(final Recipient recipient, final boolean blocked) {
|
private void setBlocked(final Recipient recipient, final boolean blocked) {
|
||||||
recipient.setBlocked(blocked);
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
|
@ -29,8 +29,8 @@ import android.util.Log;
|
|||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
|
||||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -102,9 +102,9 @@ public class ContactsCursorLoader extends CursorLoader {
|
|||||||
ContactsDatabase.CONTACT_TYPE_COLUMN});
|
ContactsDatabase.CONTACT_TYPE_COLUMN});
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
final String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
|
final String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
|
||||||
final Recipient recipient = Recipient.from(getContext(), Address.fromExternal(getContext(), number), true);
|
final Recipient recipient = Recipient.from(getContext(), Address.fromExternal(getContext(), number), false);
|
||||||
|
|
||||||
if (DirectoryHelper.getUserCapabilities(getContext(), recipient) != DirectoryHelper.Capability.SUPPORTED) {
|
if (recipient.resolve().getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) {
|
||||||
matrix.addRow(new Object[]{cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN)),
|
matrix.addRow(new Object[]{cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN)),
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN)),
|
cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN)),
|
||||||
number,
|
number,
|
||||||
|
@ -32,4 +32,9 @@ public class BitmapContactPhoto implements ContactPhoto {
|
|||||||
public Drawable asCallCard(Context context) {
|
public Drawable asCallCard(Context context) {
|
||||||
return new BitmapDrawable(context.getResources(), bitmap);
|
return new BitmapDrawable(context.getResources(), bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGenerated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,5 +8,6 @@ public interface ContactPhoto {
|
|||||||
public Drawable asDrawable(Context context, int color);
|
public Drawable asDrawable(Context context, int color);
|
||||||
public Drawable asDrawable(Context context, int color, boolean inverted);
|
public Drawable asDrawable(Context context, int color, boolean inverted);
|
||||||
public Drawable asCallCard(Context context);
|
public Drawable asCallCard(Context context);
|
||||||
|
public boolean isGenerated();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,4 +50,9 @@ public class GeneratedContactPhoto implements ContactPhoto {
|
|||||||
public Drawable asCallCard(Context context) {
|
public Drawable asCallCard(Context context) {
|
||||||
return ContextCompat.getDrawable(context, R.drawable.ic_contact_picture_large);
|
return ContextCompat.getDrawable(context, R.drawable.ic_contact_picture_large);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGenerated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,11 @@ public class ResourceContactPhoto implements ContactPhoto {
|
|||||||
return context.getResources().getDrawable(resourceId);
|
return context.getResources().getDrawable(resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGenerated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static class ExpandingLayerDrawable extends LayerDrawable {
|
private static class ExpandingLayerDrawable extends LayerDrawable {
|
||||||
public ExpandingLayerDrawable(Drawable[] layers) {
|
public ExpandingLayerDrawable(Drawable[] layers) {
|
||||||
super(layers);
|
super(layers);
|
||||||
|
@ -26,4 +26,9 @@ public class TransparentContactPhoto implements ContactPhoto {
|
|||||||
public Drawable asCallCard(Context context) {
|
public Drawable asCallCard(Context context) {
|
||||||
return ContextCompat.getDrawable(context, R.drawable.ic_contact_picture_large);
|
return ContextCompat.getDrawable(context, R.drawable.ic_contact_picture_large);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGenerated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1290,7 @@ public class DatabaseFactory {
|
|||||||
String address = new NumberMigrator(TextSecurePreferences.getLocalNumber(context)).migrate(cursor.getString(0));
|
String address = new NumberMigrator(TextSecurePreferences.getLocalNumber(context)).migrate(cursor.getString(0));
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
|
|
||||||
contentValues.put("registered", cursor.getInt(1) == 1);
|
contentValues.put("registered", cursor.getInt(1) == 1 ? 1 : 2);
|
||||||
|
|
||||||
if (db.update("recipient_preferences", contentValues, "recipient_ids = ?", new String[] {address}) < 1) {
|
if (db.update("recipient_preferences", contentValues, "recipient_ids = ?", new String[] {address}) < 1) {
|
||||||
contentValues.put("recipient_ids", address);
|
contentValues.put("recipient_ids", address);
|
||||||
|
@ -12,10 +12,11 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.util.Base64;
|
import org.thoughtcrime.securesms.util.Base64;
|
||||||
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -74,6 +75,24 @@ public class RecipientDatabase extends Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final String CREATE_TABLE =
|
public static final String CREATE_TABLE =
|
||||||
"CREATE TABLE " + TABLE_NAME +
|
"CREATE TABLE " + TABLE_NAME +
|
||||||
" (" + ID + " INTEGER PRIMARY KEY, " +
|
" (" + ID + " INTEGER PRIMARY KEY, " +
|
||||||
@ -120,7 +139,7 @@ public class RecipientDatabase extends Database {
|
|||||||
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null);
|
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null);
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
return getRecipientPreferences(cursor);
|
return getRecipientSettings(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
@ -129,7 +148,7 @@ public class RecipientDatabase extends Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<RecipientSettings> getRecipientPreferences(@NonNull Cursor cursor) {
|
Optional<RecipientSettings> getRecipientSettings(@NonNull Cursor cursor) {
|
||||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
||||||
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
||||||
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
||||||
@ -139,7 +158,7 @@ public class RecipientDatabase extends Database {
|
|||||||
boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1;
|
boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1;
|
||||||
int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID));
|
int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID));
|
||||||
int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES));
|
int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES));
|
||||||
boolean registered = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED)) == 1;
|
int registeredState = cursor.getInt(cursor.getColumnIndexOrThrow(REGISTERED));
|
||||||
String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY));
|
String profileKeyString = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_KEY));
|
||||||
String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME));
|
String systemDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME));
|
||||||
String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME));
|
String signalProfileName = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_NAME));
|
||||||
@ -168,7 +187,8 @@ public class RecipientDatabase extends Database {
|
|||||||
return Optional.of(new RecipientSettings(blocked, muteUntil,
|
return Optional.of(new RecipientSettings(blocked, muteUntil,
|
||||||
VibrateState.fromId(vibrateState),
|
VibrateState.fromId(vibrateState),
|
||||||
notificationUri, color, seenInviteReminder,
|
notificationUri, color, seenInviteReminder,
|
||||||
defaultSubscriptionId, expireMessages, registered,
|
defaultSubscriptionId, expireMessages,
|
||||||
|
RegisteredState.fromId(registeredState),
|
||||||
profileKey, systemDisplayName, signalProfileName,
|
profileKey, systemDisplayName, signalProfileName,
|
||||||
signalProfileAvatar, profileSharing));
|
signalProfileAvatar, profileSharing));
|
||||||
}
|
}
|
||||||
@ -185,117 +205,129 @@ public class RecipientDatabase extends Database {
|
|||||||
return new BulkOperationsHandle(database);
|
return new BulkOperationsHandle(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColor(Recipient recipient, MaterialColor color) {
|
public void setColor(@NonNull Recipient recipient, @NonNull MaterialColor color) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(COLOR, color.serialize());
|
values.put(COLOR, color.serialize());
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultSubscriptionId(@NonNull Recipient recipient, int defaultSubscriptionId) {
|
public void setDefaultSubscriptionId(@NonNull Recipient recipient, int defaultSubscriptionId) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(DEFAULT_SUBSCRIPTION_ID, defaultSubscriptionId);
|
values.put(DEFAULT_SUBSCRIPTION_ID, defaultSubscriptionId);
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
EventBus.getDefault().post(new RecipientPreferenceEvent(recipient));
|
recipient.resolve().setDefaultSubscriptionId(Optional.of(defaultSubscriptionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlocked(Recipient recipient, boolean blocked) {
|
public void setBlocked(@NonNull Recipient recipient, boolean blocked) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(BLOCK, blocked ? 1 : 0);
|
values.put(BLOCK, blocked ? 1 : 0);
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setBlocked(blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRingtone(Recipient recipient, @Nullable Uri notification) {
|
public void setRingtone(@NonNull Recipient recipient, @Nullable Uri notification) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(NOTIFICATION, notification == null ? null : notification.toString());
|
values.put(NOTIFICATION, notification == null ? null : notification.toString());
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setRingtone(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVibrate(Recipient recipient, @NonNull VibrateState enabled) {
|
public void setVibrate(@NonNull Recipient recipient, @NonNull VibrateState enabled) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(VIBRATE, enabled.getId());
|
values.put(VIBRATE, enabled.getId());
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setVibrate(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMuted(Recipient recipient, long until) {
|
public void setMuted(@NonNull Recipient recipient, long until) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(MUTE_UNTIL, until);
|
values.put(MUTE_UNTIL, until);
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setMuted(until);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSeenInviteReminder(Recipient recipient, boolean seen) {
|
public void setSeenInviteReminder(@NonNull Recipient recipient, boolean seen) {
|
||||||
ContentValues values = new ContentValues(1);
|
ContentValues values = new ContentValues(1);
|
||||||
values.put(SEEN_INVITE_REMINDER, seen ? 1 : 0);
|
values.put(SEEN_INVITE_REMINDER, seen ? 1 : 0);
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setHasSeenInviteReminder(seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpireMessages(Recipient recipient, int expiration) {
|
public void setExpireMessages(@NonNull Recipient recipient, int expiration) {
|
||||||
recipient.setExpireMessages(expiration);
|
recipient.setExpireMessages(expiration);
|
||||||
|
|
||||||
ContentValues values = new ContentValues(1);
|
ContentValues values = new ContentValues(1);
|
||||||
values.put(EXPIRE_MESSAGES, expiration);
|
values.put(EXPIRE_MESSAGES, expiration);
|
||||||
updateOrInsert(recipient.getAddress(), values);
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setExpireMessages(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSystemDisplayName(@NonNull Address address, @Nullable String systemDisplayName) {
|
public void setProfileKey(@NonNull Recipient recipient, @Nullable byte[] profileKey) {
|
||||||
ContentValues values = new ContentValues(1);
|
|
||||||
values.put(SYSTEM_DISPLAY_NAME, systemDisplayName);
|
|
||||||
updateOrInsert(address, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProfileKey(@NonNull Address address, @Nullable byte[] profileKey) {
|
|
||||||
ContentValues values = new ContentValues(1);
|
ContentValues values = new ContentValues(1);
|
||||||
values.put(PROFILE_KEY, profileKey == null ? null : Base64.encodeBytes(profileKey));
|
values.put(PROFILE_KEY, profileKey == null ? null : Base64.encodeBytes(profileKey));
|
||||||
updateOrInsert(address, values);;
|
updateOrInsert(recipient.getAddress(), values);
|
||||||
|
recipient.resolve().setProfileKey(profileKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfileName(@NonNull Address address, @Nullable String profileName) {
|
public void setProfileName(@NonNull Recipient recipient, @Nullable String profileName) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(SIGNAL_PROFILE_NAME, profileName);
|
contentValues.put(SIGNAL_PROFILE_NAME, profileName);
|
||||||
updateOrInsert(address, contentValues);
|
updateOrInsert(recipient.getAddress(), contentValues);
|
||||||
|
recipient.resolve().setProfileName(profileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfileAvatar(@NonNull Address address, @Nullable String profileAvatar) {
|
public void setProfileAvatar(@NonNull Recipient recipient, @Nullable String profileAvatar) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(SIGNAL_PROFILE_AVATAR, profileAvatar);
|
contentValues.put(SIGNAL_PROFILE_AVATAR, profileAvatar);
|
||||||
updateOrInsert(address, contentValues);
|
updateOrInsert(recipient.getAddress(), contentValues);
|
||||||
|
recipient.resolve().setProfileAvatar(profileAvatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfileSharing(@NonNull Address address, boolean enabled) {
|
public void setProfileSharing(@NonNull Recipient recipient, boolean enabled) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(PROFILE_SHARING, enabled ? 1 : 0);
|
contentValues.put(PROFILE_SHARING, enabled ? 1 : 0);
|
||||||
updateOrInsert(address, contentValues);
|
updateOrInsert(recipient.getAddress(), contentValues);
|
||||||
|
recipient.setProfileSharing(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Address> getAllRecipients() {
|
public Set<Recipient> getAllRecipients() {
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
Set<Address> results = new HashSet<>();
|
Set<Recipient> results = new HashSet<>();
|
||||||
|
|
||||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] {ADDRESS}, null, null, null, null, null)) {
|
try (Cursor cursor = db.query(TABLE_NAME, new String[] {ADDRESS}, null, null, null, null, null)) {
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
results.add(Address.fromExternal(context, cursor.getString(0)));
|
results.add(Recipient.from(context, Address.fromExternal(context, cursor.getString(0)), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistered(@NonNull List<Address> activeAddresses,
|
public void setRegistered(@NonNull Recipient recipient, RegisteredState registeredState) {
|
||||||
@NonNull List<Address> inactiveAddresses)
|
|
||||||
{
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
|
||||||
|
|
||||||
for (Address activeAddress : activeAddresses) {
|
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(REGISTERED, 1);
|
contentValues.put(REGISTERED, registeredState.getId());
|
||||||
|
updateOrInsert(recipient.getAddress(), contentValues);
|
||||||
updateOrInsert(activeAddress, contentValues);
|
recipient.setRegistered(registeredState);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Address inactiveAddress : inactiveAddresses) {
|
public void setRegistered(@NonNull List<Recipient> activeRecipients,
|
||||||
|
@NonNull List<Recipient> inactiveRecipients)
|
||||||
|
{
|
||||||
|
for (Recipient activeRecipient : activeRecipients) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(REGISTERED, 0);
|
contentValues.put(REGISTERED, RegisteredState.REGISTERED.getId());
|
||||||
|
|
||||||
updateOrInsert(inactiveAddress, contentValues);
|
updateOrInsert(activeRecipient.getAddress(), contentValues);
|
||||||
|
activeRecipient.setRegistered(RegisteredState.REGISTERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Recipient inactiveRecipient : inactiveRecipients) {
|
||||||
|
ContentValues contentValues = new ContentValues(1);
|
||||||
|
contentValues.put(REGISTERED, RegisteredState.NOT_REGISTERED.getId());
|
||||||
|
|
||||||
|
updateOrInsert(inactiveRecipient.getAddress(), contentValues);
|
||||||
|
inactiveRecipient.setRegistered(RegisteredState.NOT_REGISTERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
||||||
@ -341,20 +373,25 @@ public class RecipientDatabase extends Database {
|
|||||||
|
|
||||||
private final SQLiteDatabase database;
|
private final SQLiteDatabase database;
|
||||||
|
|
||||||
public BulkOperationsHandle(SQLiteDatabase database) {
|
private final List<Pair<Recipient, String>> pendingDisplayNames = new LinkedList<>();
|
||||||
|
|
||||||
|
BulkOperationsHandle(SQLiteDatabase database) {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplayName(@NonNull Address address, @Nullable String displayName) {
|
public void setDisplayName(@NonNull Recipient recipient, @Nullable String displayName) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(SYSTEM_DISPLAY_NAME, displayName);
|
contentValues.put(SYSTEM_DISPLAY_NAME, displayName);
|
||||||
updateOrInsert(address, contentValues);
|
updateOrInsert(recipient.getAddress(), contentValues);
|
||||||
|
pendingDisplayNames.add(new Pair<>(recipient, displayName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finish() {
|
public void finish() {
|
||||||
database.setTransactionSuccessful();
|
database.setTransactionSuccessful();
|
||||||
database.endTransaction();
|
database.endTransaction();
|
||||||
Recipient.clearCache(context);
|
|
||||||
|
Stream.of(pendingDisplayNames).forEach(pair -> pair.first().resolve().setSystemDisplayName(pair.second()));
|
||||||
|
|
||||||
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
context.getContentResolver().notifyChange(Uri.parse(RECIPIENT_PREFERENCES_URI), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,7 +405,7 @@ public class RecipientDatabase extends Database {
|
|||||||
private final boolean seenInviteReminder;
|
private final boolean seenInviteReminder;
|
||||||
private final int defaultSubscriptionId;
|
private final int defaultSubscriptionId;
|
||||||
private final int expireMessages;
|
private final int expireMessages;
|
||||||
private final boolean registered;
|
private final RegisteredState registered;
|
||||||
private final byte[] profileKey;
|
private final byte[] profileKey;
|
||||||
private final String systemDisplayName;
|
private final String systemDisplayName;
|
||||||
private final String signalProfileName;
|
private final String signalProfileName;
|
||||||
@ -382,7 +419,7 @@ public class RecipientDatabase extends Database {
|
|||||||
boolean seenInviteReminder,
|
boolean seenInviteReminder,
|
||||||
int defaultSubscriptionId,
|
int defaultSubscriptionId,
|
||||||
int expireMessages,
|
int expireMessages,
|
||||||
boolean registered,
|
@NonNull RegisteredState registered,
|
||||||
@Nullable byte[] profileKey,
|
@Nullable byte[] profileKey,
|
||||||
@Nullable String systemDisplayName,
|
@Nullable String systemDisplayName,
|
||||||
@Nullable String signalProfileName,
|
@Nullable String signalProfileName,
|
||||||
@ -437,7 +474,7 @@ public class RecipientDatabase extends Database {
|
|||||||
return expireMessages;
|
return expireMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRegistered() {
|
public RegisteredState getRegistered() {
|
||||||
return registered;
|
return registered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,17 +522,4 @@ public class RecipientDatabase extends Database {
|
|||||||
return getCurrent();
|
return getCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RecipientPreferenceEvent {
|
|
||||||
|
|
||||||
private final Recipient recipient;
|
|
||||||
|
|
||||||
public RecipientPreferenceEvent(Recipient recipients) {
|
|
||||||
this.recipient = recipients;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Recipient getRecipient() {
|
|
||||||
return recipient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -624,7 +624,7 @@ public class ThreadDatabase extends Database {
|
|||||||
Optional<GroupRecord> groupRecord;
|
Optional<GroupRecord> groupRecord;
|
||||||
|
|
||||||
if (distributionType != DistributionTypes.ARCHIVE) {
|
if (distributionType != DistributionTypes.ARCHIVE) {
|
||||||
settings = DatabaseFactory.getRecipientDatabase(context).getRecipientPreferences(cursor);
|
settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(cursor);
|
||||||
groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(cursor);
|
groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(cursor);
|
||||||
} else {
|
} else {
|
||||||
settings = Optional.absent();
|
settings = Optional.absent();
|
||||||
|
@ -46,6 +46,7 @@ public class GroupManager {
|
|||||||
final byte[] avatarBytes = BitmapUtil.toByteArray(avatar);
|
final byte[] avatarBytes = BitmapUtil.toByteArray(avatar);
|
||||||
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||||
final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms);
|
final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms);
|
||||||
|
final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false);
|
||||||
final Set<Address> memberAddresses = getMemberAddresses(members);
|
final Set<Address> memberAddresses = getMemberAddresses(members);
|
||||||
|
|
||||||
memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)));
|
memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)));
|
||||||
@ -53,10 +54,9 @@ public class GroupManager {
|
|||||||
|
|
||||||
if (!mms) {
|
if (!mms) {
|
||||||
groupDatabase.updateAvatar(groupId, avatarBytes);
|
groupDatabase.updateAvatar(groupId, avatarBytes);
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Address.fromSerialized(groupId), true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient, true);
|
||||||
return sendGroupUpdate(context, masterSecret, groupId, memberAddresses, name, avatarBytes);
|
return sendGroupUpdate(context, masterSecret, groupId, memberAddresses, name, avatarBytes);
|
||||||
} else {
|
} else {
|
||||||
Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), true);
|
|
||||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION);
|
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION);
|
||||||
return new GroupActionResult(groupRecipient, threadId);
|
return new GroupActionResult(groupRecipient, threadId);
|
||||||
}
|
}
|
||||||
|
@ -805,17 +805,12 @@ public class PushDecryptJob extends ContextJob {
|
|||||||
{
|
{
|
||||||
RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
|
RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
|
||||||
Address sourceAddress = Address.fromExternal(context, envelope.getSource());
|
Address sourceAddress = Address.fromExternal(context, envelope.getSource());
|
||||||
Optional<RecipientSettings> settings = database.getRecipientSettings(sourceAddress);
|
Recipient recipient = Recipient.from(context, sourceAddress, false);
|
||||||
|
|
||||||
if (!settings.isPresent() || settings.get().getProfileKey() == null ||
|
if (recipient.getProfileKey() == null || MessageDigest.isEqual(recipient.getProfileKey(), message.getProfileKey().get())) {
|
||||||
!MessageDigest.isEqual(message.getProfileKey().get(), settings.get().getProfileKey()))
|
database.setProfileKey(recipient, message.getProfileKey().get());
|
||||||
{
|
|
||||||
database.setProfileKey(sourceAddress, message.getProfileKey().get());
|
|
||||||
|
|
||||||
Recipient recipient = Recipient.from(context, sourceAddress, true);
|
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileJob(context, recipient));
|
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileJob(context, recipient));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<InsertResult> insertPlaceholder(@NonNull SignalServiceEnvelope envelope) {
|
private Optional<InsertResult> insertPlaceholder(@NonNull SignalServiceEnvelope envelope) {
|
||||||
|
@ -114,7 +114,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|||||||
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
||||||
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
|
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
|
||||||
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
|
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
|
||||||
Optional<byte[]> profileKey = getProfileKey(message.getRecipient().getAddress());
|
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
|
||||||
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
|
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
|
||||||
.withBody(message.getBody())
|
.withBody(message.getBody())
|
||||||
.withAttachments(attachmentStreams)
|
.withAttachments(attachmentStreams)
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package org.thoughtcrime.securesms.jobs;
|
package org.thoughtcrime.securesms.jobs;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
@ -28,10 +30,10 @@ public abstract class PushReceivedJob extends ContextJob {
|
|||||||
|
|
||||||
public void handle(SignalServiceEnvelope envelope, boolean sendExplicitReceipt) {
|
public void handle(SignalServiceEnvelope envelope, boolean sendExplicitReceipt) {
|
||||||
Address source = Address.fromExternal(context, envelope.getSource());
|
Address source = Address.fromExternal(context, envelope.getSource());
|
||||||
|
|
||||||
if (!isActiveNumber(context, source)) {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setRegistered(Util.asList(source), new LinkedList<>());
|
|
||||||
Recipient recipient = Recipient.from(context, source, false);
|
Recipient recipient = Recipient.from(context, source, false);
|
||||||
|
|
||||||
|
if (!isActiveNumber(recipient)) {
|
||||||
|
DatabaseFactory.getRecipientDatabase(context).setRegistered(recipient, RecipientDatabase.RegisteredState.REGISTERED);
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, KeyCachingService.getMasterSecret(context), recipient));
|
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, KeyCachingService.getMasterSecret(context), recipient));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,9 +70,8 @@ public abstract class PushReceivedJob extends ContextJob {
|
|||||||
envelope.getTimestamp()));
|
envelope.getTimestamp()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isActiveNumber(Context context, Address address) {
|
private boolean isActiveNumber(@NonNull Recipient recipient) {
|
||||||
Optional<RecipientSettings> settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address);
|
return recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED;
|
||||||
return settings.isPresent() && settings.get().isRegistered();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.jobs;
|
package org.thoughtcrime.securesms.jobs;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -64,17 +65,11 @@ public abstract class PushSendJob extends SendJob {
|
|||||||
onPushSend(masterSecret);
|
onPushSend(masterSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Optional<byte[]> getProfileKey(Address address) {
|
protected Optional<byte[]> getProfileKey(@NonNull Recipient recipient) {
|
||||||
try {
|
try {
|
||||||
Optional<RecipientSettings> recipientsPreferences = DatabaseFactory.getRecipientDatabase(context)
|
if (!recipient.resolve().isSystemContact() && !recipient.resolve().isProfileSharing()) {
|
||||||
.getRecipientSettings(address);
|
return Optional.absent();
|
||||||
|
}
|
||||||
if (!recipientsPreferences.isPresent()) return Optional.absent();
|
|
||||||
|
|
||||||
boolean isSystemContact = !TextUtils.isEmpty(recipientsPreferences.get().getSystemDisplayName());
|
|
||||||
boolean isApproved = recipientsPreferences.get().isProfileSharing();
|
|
||||||
|
|
||||||
if (!isSystemContact & !isApproved) return Optional.absent();
|
|
||||||
|
|
||||||
String profileKey = TextSecurePreferences.getProfileKey(context);
|
String profileKey = TextSecurePreferences.getProfileKey(context);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
|||||||
try {
|
try {
|
||||||
SignalServiceAddress address = getPushAddress(message.getIndividualRecipient().getAddress());
|
SignalServiceAddress address = getPushAddress(message.getIndividualRecipient().getAddress());
|
||||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||||
Optional<byte[]> profileKey = getProfileKey(message.getIndividualRecipient().getAddress());
|
Optional<byte[]> profileKey = getProfileKey(message.getIndividualRecipient());
|
||||||
SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder()
|
SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder()
|
||||||
.withTimestamp(message.getDateSent())
|
.withTimestamp(message.getDateSent())
|
||||||
.withBody(message.getBody().getBody())
|
.withBody(message.getBody().getBody())
|
||||||
|
@ -5,16 +5,16 @@ import android.content.Context;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||||
|
|
||||||
@ -52,19 +52,14 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
|
|||||||
@Override
|
@Override
|
||||||
public void onRun() throws IOException {
|
public void onRun() throws IOException {
|
||||||
RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
|
RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
|
||||||
Optional<RecipientSettings> recipientSettings = database.getRecipientSettings(recipient.getAddress());
|
byte[] profileKey = recipient.resolve().getProfileKey();
|
||||||
|
|
||||||
if (!recipientSettings.isPresent()) {
|
if (profileKey == null) {
|
||||||
Log.w(TAG, "Recipient preference row is gone!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientSettings.get().getProfileKey() == null) {
|
|
||||||
Log.w(TAG, "Recipient profile key is gone!");
|
Log.w(TAG, "Recipient profile key is gone!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util.equals(profileAvatar, recipientSettings.get().getProfileAvatar())) {
|
if (Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
|
||||||
Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
|
Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,13 +67,14 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
|
|||||||
if (TextUtils.isEmpty(profileAvatar)) {
|
if (TextUtils.isEmpty(profileAvatar)) {
|
||||||
Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize());
|
Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize());
|
||||||
AvatarHelper.delete(context, recipient.getAddress());
|
AvatarHelper.delete(context, recipient.getAddress());
|
||||||
|
database.setProfileAvatar(recipient, profileAvatar);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
|
File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, recipientSettings.get().getProfileKey(), MAX_PROFILE_SIZE_BYTES);
|
InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, MAX_PROFILE_SIZE_BYTES);
|
||||||
File decryptDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
|
File decryptDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
|
||||||
|
|
||||||
Util.copy(avatarStream, new FileOutputStream(decryptDestination));
|
Util.copy(avatarStream, new FileOutputStream(decryptDestination));
|
||||||
@ -87,8 +83,11 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
|
|||||||
if (downloadDestination != null) downloadDestination.delete();
|
if (downloadDestination != null) downloadDestination.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
database.setProfileAvatar(recipient.getAddress(), profileAvatar);
|
database.setProfileAvatar(recipient, profileAvatar);
|
||||||
Recipient.clearCache(context);
|
|
||||||
|
if (recipient.resolve().getContactPhoto().isGenerated()) {
|
||||||
|
recipient.setContactPhoto(ContactPhotoFactory.getSignalAvatarContactPhoto(context, recipient.getAddress(), recipient.getName(), context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,11 +73,10 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
String number = recipient.getAddress().toPhoneString();
|
String number = recipient.getAddress().toPhoneString();
|
||||||
SignalServiceProfile profile = retrieveProfile(number);
|
SignalServiceProfile profile = retrieveProfile(number);
|
||||||
Optional<RecipientSettings> recipientSettings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(recipient.getAddress());
|
|
||||||
|
|
||||||
setIdentityKey(recipient, profile.getIdentityKey());
|
setIdentityKey(recipient, profile.getIdentityKey());
|
||||||
setProfileName(recipient, recipientSettings, profile.getName());
|
setProfileName(recipient, profile.getName());
|
||||||
setProfileAvatar(recipient, recipientSettings, profile.getAvatar());
|
setProfileAvatar(recipient, profile.getAvatar());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleGroupRecipient(Recipient group)
|
private void handleGroupRecipient(Recipient group)
|
||||||
@ -127,32 +126,30 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProfileName(Recipient recipient, Optional<RecipientSettings> recipientPreferences, String profileName) {
|
private void setProfileName(Recipient recipient, String profileName) {
|
||||||
try {
|
try {
|
||||||
if (!recipientPreferences.isPresent()) return;
|
byte[] profileKey = recipient.getProfileKey();
|
||||||
if (recipientPreferences.get().getProfileKey() == null) return;
|
if (profileKey == null) return;
|
||||||
|
|
||||||
String plaintextProfileName = null;
|
String plaintextProfileName = null;
|
||||||
|
|
||||||
if (profileName != null) {
|
if (profileName != null) {
|
||||||
ProfileCipher profileCipher = new ProfileCipher(recipientPreferences.get().getProfileKey());
|
ProfileCipher profileCipher = new ProfileCipher(profileKey);
|
||||||
plaintextProfileName = new String(profileCipher.decryptName(Base64.decode(profileName)));
|
plaintextProfileName = new String(profileCipher.decryptName(Base64.decode(profileName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Util.equals(plaintextProfileName, recipientPreferences.get().getProfileName())) {
|
if (!Util.equals(plaintextProfileName, recipient.getProfileName())) {
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileName(recipient.getAddress(), plaintextProfileName);
|
DatabaseFactory.getRecipientDatabase(context).setProfileName(recipient, plaintextProfileName);
|
||||||
Recipient.clearCache(context);
|
|
||||||
}
|
}
|
||||||
} catch (ProfileCipher.InvalidCiphertextException | IOException e) {
|
} catch (ProfileCipher.InvalidCiphertextException | IOException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProfileAvatar(Recipient recipient, Optional<RecipientSettings> recipientPreferences, String profileAvatar) {
|
private void setProfileAvatar(Recipient recipient, String profileAvatar) {
|
||||||
if (!recipientPreferences.isPresent()) return;
|
if (recipient.getProfileKey() == null) return;
|
||||||
if (recipientPreferences.get().getProfileKey() == null) return;
|
|
||||||
|
|
||||||
if (!Util.equals(profileAvatar, recipientPreferences.get().getProfileAvatar())) {
|
if (!Util.equals(profileAvatar, recipient.getProfileAvatar())) {
|
||||||
ApplicationContext.getInstance(context)
|
ApplicationContext.getInstance(context)
|
||||||
.getJobManager()
|
.getJobManager()
|
||||||
.add(new RetrieveProfileAvatarJob(context, recipient, profileAvatar));
|
.add(new RetrieveProfileAvatarJob(context, recipient, profileAvatar));
|
||||||
|
@ -73,9 +73,8 @@ public class AndroidAutoReplyReceiver extends MasterSecretBroadcastReceiver {
|
|||||||
|
|
||||||
long replyThreadId;
|
long replyThreadId;
|
||||||
|
|
||||||
Optional<RecipientSettings> settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address);
|
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
|
||||||
int subscriptionId = settings.isPresent() ? settings.get().getDefaultSubscriptionId().or(-1) : -1;
|
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||||
long expiresIn = settings.isPresent() ? settings.get().getExpireMessages() * 1000 : 0;
|
|
||||||
|
|
||||||
if (recipient.isGroupRecipient()) {
|
if (recipient.isGroupRecipient()) {
|
||||||
Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message");
|
Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message");
|
||||||
|
@ -67,10 +67,9 @@ public class RemoteReplyReceiver extends MasterSecretBroadcastReceiver {
|
|||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
long threadId;
|
long threadId;
|
||||||
|
|
||||||
Optional<RecipientSettings> settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address);
|
|
||||||
int subscriptionId = settings.isPresent() ? settings.get().getDefaultSubscriptionId().or(-1) : -1;
|
|
||||||
long expiresIn = settings.isPresent() ? settings.get().getExpireMessages() * 1000 : 0;
|
|
||||||
Recipient recipient = Recipient.from(context, address, false);
|
Recipient recipient = Recipient.from(context, address, false);
|
||||||
|
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
|
||||||
|
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||||
|
|
||||||
if (recipient.isGroupRecipient()) {
|
if (recipient.isGroupRecipient()) {
|
||||||
OutgoingMediaMessage reply = new OutgoingMediaMessage(recipient, responseText.toString(), new LinkedList<Attachment>(), System.currentTimeMillis(), subscriptionId, expiresIn, 0);
|
OutgoingMediaMessage reply = new OutgoingMediaMessage(recipient, responseText.toString(), new LinkedList<Attachment>(), System.currentTimeMillis(), subscriptionId, expiresIn, 0);
|
||||||
|
@ -52,11 +52,6 @@ public class UnknownSenderView extends FrameLayout {
|
|||||||
if (threadId != -1) DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true);
|
if (threadId != -1) DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void result) {
|
|
||||||
recipient.setBlocked(true);
|
|
||||||
}
|
|
||||||
}.execute();
|
}.execute();
|
||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
@ -94,7 +89,7 @@ public class UnknownSenderView extends FrameLayout {
|
|||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getAddress(), true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
if (threadId != -1) DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true);
|
if (threadId != -1) DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
|||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
|
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
|
||||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||||
@ -63,14 +64,22 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
|
|
||||||
private ContactPhoto contactPhoto;
|
private ContactPhoto contactPhoto;
|
||||||
private Uri contactUri;
|
private Uri contactUri;
|
||||||
private Uri ringtone = null;
|
private @Nullable Uri ringtone = null;
|
||||||
private long mutedUntil = 0;
|
private long mutedUntil = 0;
|
||||||
private boolean blocked = false;
|
private boolean blocked = false;
|
||||||
private VibrateState vibrate = VibrateState.DEFAULT;
|
private VibrateState vibrate = VibrateState.DEFAULT;
|
||||||
private int expireMessages = 0;
|
private int expireMessages = 0;
|
||||||
private String profileName = null;
|
private Optional<Integer> defaultSubscriptionId = Optional.absent();
|
||||||
|
private @NonNull RegisteredState registered = RegisteredState.UNKNOWN;
|
||||||
|
|
||||||
|
private @Nullable MaterialColor color;
|
||||||
|
private boolean seenInviteReminder;
|
||||||
|
private @Nullable byte[] profileKey;
|
||||||
|
private @Nullable String profileName;
|
||||||
|
private @Nullable String profileAvatar;
|
||||||
|
private boolean profileSharing;
|
||||||
|
private boolean isSystemContact;
|
||||||
|
|
||||||
@Nullable private MaterialColor color;
|
|
||||||
|
|
||||||
public static @NonNull Recipient from(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
|
public static @NonNull Recipient from(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
|
||||||
if (address == null) throw new AssertionError(address);
|
if (address == null) throw new AssertionError(address);
|
||||||
@ -108,7 +117,14 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
this.blocked = stale.blocked;
|
this.blocked = stale.blocked;
|
||||||
this.vibrate = stale.vibrate;
|
this.vibrate = stale.vibrate;
|
||||||
this.expireMessages = stale.expireMessages;
|
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.profileName = stale.profileName;
|
||||||
|
this.profileAvatar = stale.profileAvatar;
|
||||||
|
this.profileSharing = stale.profileSharing;
|
||||||
|
this.isSystemContact = stale.isSystemContact;
|
||||||
this.participants.clear();
|
this.participants.clear();
|
||||||
this.participants.addAll(stale.participants);
|
this.participants.addAll(stale.participants);
|
||||||
}
|
}
|
||||||
@ -122,7 +138,14 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
this.blocked = details.get().blocked;
|
this.blocked = details.get().blocked;
|
||||||
this.vibrate = details.get().vibrateState;
|
this.vibrate = details.get().vibrateState;
|
||||||
this.expireMessages = details.get().expireMessages;
|
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.profileName = details.get().profileName;
|
||||||
|
this.profileAvatar = details.get().profileAvatar;
|
||||||
|
this.profileSharing = details.get().profileSharing;
|
||||||
|
this.isSystemContact = details.get().systemContact;
|
||||||
this.participants.clear();
|
this.participants.clear();
|
||||||
this.participants.addAll(details.get().participants);
|
this.participants.addAll(details.get().participants);
|
||||||
}
|
}
|
||||||
@ -142,7 +165,15 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
Recipient.this.blocked = result.blocked;
|
Recipient.this.blocked = result.blocked;
|
||||||
Recipient.this.vibrate = result.vibrateState;
|
Recipient.this.vibrate = result.vibrateState;
|
||||||
Recipient.this.expireMessages = result.expireMessages;
|
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.profileName = result.profileName;
|
||||||
|
Recipient.this.profileAvatar = result.profileAvatar;
|
||||||
|
Recipient.this.profileSharing = result.profileSharing;
|
||||||
|
Recipient.this.profileName = result.profileName;
|
||||||
|
Recipient.this.isSystemContact = result.systemContact;
|
||||||
|
|
||||||
Recipient.this.participants.clear();
|
Recipient.this.participants.clear();
|
||||||
Recipient.this.participants.addAll(result.participants);
|
Recipient.this.participants.addAll(result.participants);
|
||||||
@ -151,6 +182,8 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
if (!listeners.isEmpty()) {
|
if (!listeners.isEmpty()) {
|
||||||
for (Recipient recipient : participants) recipient.addListener(Recipient.this);
|
for (Recipient recipient : participants) recipient.addListener(Recipient.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Recipient.this.notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -176,7 +209,14 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
this.blocked = details.blocked;
|
this.blocked = details.blocked;
|
||||||
this.vibrate = details.vibrateState;
|
this.vibrate = details.vibrateState;
|
||||||
this.expireMessages = details.expireMessages;
|
this.expireMessages = details.expireMessages;
|
||||||
|
this.seenInviteReminder = details.seenInviteReminder;
|
||||||
|
this.defaultSubscriptionId = details.defaultSubscriptionId;
|
||||||
|
this.registered = details.registered;
|
||||||
|
this.profileKey = details.profileKey;
|
||||||
this.profileName = details.profileName;
|
this.profileName = details.profileName;
|
||||||
|
this.profileAvatar = details.profileAvatar;
|
||||||
|
this.profileSharing = details.profileSharing;
|
||||||
|
this.isSystemContact = details.systemContact;
|
||||||
this.participants.addAll(details.participants);
|
this.participants.addAll(details.participants);
|
||||||
this.resolving = false;
|
this.resolving = false;
|
||||||
}
|
}
|
||||||
@ -222,10 +262,54 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
return customLabel;
|
return customLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getProfileName() {
|
public synchronized Optional<Integer> getDefaultSubscriptionId() {
|
||||||
|
return defaultSubscriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultSubscriptionId(Optional<Integer> defaultSubscriptionId) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.defaultSubscriptionId = defaultSubscriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized @Nullable String getProfileName() {
|
||||||
return profileName;
|
return profileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProfileName(@Nullable String profileName) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.profileName = profileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized @Nullable String getProfileAvatar() {
|
||||||
|
return profileAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileAvatar(@Nullable String profileAvatar) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.profileAvatar = profileAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isProfileSharing() {
|
||||||
|
return profileSharing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileSharing(boolean value) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.profileSharing = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isGroupRecipient() {
|
public boolean isGroupRecipient() {
|
||||||
return address.isGroup();
|
return address.isGroup();
|
||||||
}
|
}
|
||||||
@ -265,6 +349,14 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
return contactPhoto;
|
return contactPhoto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContactPhoto(@NonNull ContactPhoto contactPhoto) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.contactPhoto = contactPhoto;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized @Nullable Uri getRingtone() {
|
public synchronized @Nullable Uri getRingtone() {
|
||||||
return ringtone;
|
return ringtone;
|
||||||
}
|
}
|
||||||
@ -325,6 +417,60 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized boolean hasSeenInviteReminder() {
|
||||||
|
return seenInviteReminder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasSeenInviteReminder(boolean value) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.seenInviteReminder = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized RegisteredState getRegistered() {
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistered(@NonNull RegisteredState value) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.registered = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized @Nullable byte[] getProfileKey() {
|
||||||
|
return profileKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileKey(@Nullable byte[] profileKey) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.profileKey = profileKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isSystemContact() {
|
||||||
|
return isSystemContact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystemDisplayName(@Nullable String displayName) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (displayName == null) this.name = profileName;
|
||||||
|
else this.name = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Recipient resolve() {
|
||||||
|
while (resolving) Util.wait(this, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@ -369,4 +515,5 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
return resolving;
|
return resolving;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,9 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
|||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||||
import org.thoughtcrime.securesms.util.LRUCache;
|
import org.thoughtcrime.securesms.util.LRUCache;
|
||||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||||
@ -199,6 +201,13 @@ class RecipientProvider {
|
|||||||
public final int expireMessages;
|
public final int expireMessages;
|
||||||
@NonNull public final List<Recipient> participants;
|
@NonNull public final List<Recipient> participants;
|
||||||
@Nullable public final String profileName;
|
@Nullable public final String profileName;
|
||||||
|
public final boolean seenInviteReminder;
|
||||||
|
public final Optional<Integer> defaultSubscriptionId;
|
||||||
|
@NonNull public final RegisteredState registered;
|
||||||
|
@Nullable public final byte[] profileKey;
|
||||||
|
@Nullable public final String profileAvatar;
|
||||||
|
public final boolean profileSharing;
|
||||||
|
public final boolean systemContact;
|
||||||
|
|
||||||
public RecipientDetails(@Nullable String name, @Nullable String customLabel,
|
public RecipientDetails(@Nullable String name, @Nullable String customLabel,
|
||||||
@Nullable Uri contactUri, @NonNull ContactPhoto avatar,
|
@Nullable Uri contactUri, @NonNull ContactPhoto avatar,
|
||||||
@ -216,6 +225,13 @@ class RecipientProvider {
|
|||||||
this.expireMessages = settings != null ? settings.getExpireMessages() : 0;
|
this.expireMessages = settings != null ? settings.getExpireMessages() : 0;
|
||||||
this.participants = participants == null ? new LinkedList<Recipient>() : participants;
|
this.participants = participants == null ? new LinkedList<Recipient>() : participants;
|
||||||
this.profileName = settings != null ? settings.getProfileName() : null;
|
this.profileName = settings != null ? settings.getProfileName() : null;
|
||||||
|
this.seenInviteReminder = settings != null && settings.hasSeenInviteReminder();
|
||||||
|
this.defaultSubscriptionId = settings != null ? settings.getDefaultSubscriptionId() : Optional.absent();
|
||||||
|
this.registered = settings != null ? settings.getRegistered() : RegisteredState.UNKNOWN;
|
||||||
|
this.profileKey = settings != null ? settings.getProfileKey() : null;
|
||||||
|
this.profileAvatar = settings != null ? settings.getProfileAvatar() : null;
|
||||||
|
this.profileSharing = settings != null && settings.isProfileSharing();
|
||||||
|
this.systemContact = settings != null && !TextUtils.isEmpty(settings.getSystemDisplayName());
|
||||||
|
|
||||||
if (name == null && settings != null) this.name = settings.getSystemDisplayName();
|
if (name == null && settings != null) this.name = settings.getSystemDisplayName();
|
||||||
else this.name = name;
|
else this.name = name;
|
||||||
|
@ -53,9 +53,8 @@ public class QuickResponseService extends MasterSecretIntentService {
|
|||||||
|
|
||||||
Address address = Address.fromExternal(this, number);
|
Address address = Address.fromExternal(this, number);
|
||||||
Recipient recipient = Recipient.from(this, address, false);
|
Recipient recipient = Recipient.from(this, address, false);
|
||||||
Optional<RecipientSettings> settings = DatabaseFactory.getRecipientDatabase(this).getRecipientSettings(recipient.getAddress());
|
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
|
||||||
int subscriptionId = settings.isPresent() ? settings.get().getDefaultSubscriptionId().or(-1) : -1;
|
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||||
long expiresIn = settings.isPresent() ? settings.get().getExpireMessages() * 1000 : 0;
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(content)) {
|
if (!TextUtils.isEmpty(content)) {
|
||||||
MessageSender.send(this, masterSecret, new OutgoingTextMessage(recipient, content, expiresIn, subscriptionId), -1, false, null);
|
MessageSender.send(this, masterSecret, new OutgoingTextMessage(recipient, content, expiresIn, subscriptionId), -1, false, null);
|
||||||
|
@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||||||
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
@ -50,7 +49,6 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
|||||||
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
|
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
public class MessageSender {
|
public class MessageSender {
|
||||||
|
|
||||||
@ -232,7 +230,7 @@ public class MessageSender {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isPushDestination(context, recipient.getAddress());
|
return isPushDestination(context, recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPushMediaSend(Context context, Recipient recipient) {
|
private static boolean isPushMediaSend(Context context, Recipient recipient) {
|
||||||
@ -244,7 +242,7 @@ public class MessageSender {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isPushDestination(context, recipient.getAddress());
|
return isPushDestination(context, recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isGroupPushSend(Recipient recipient) {
|
private static boolean isGroupPushSend(Recipient recipient) {
|
||||||
@ -264,22 +262,21 @@ public class MessageSender {
|
|||||||
return Util.isOwnNumber(context, recipient.getAddress());
|
return Util.isOwnNumber(context, recipient.getAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPushDestination(Context context, Address destination) {
|
private static boolean isPushDestination(Context context, Recipient destination) {
|
||||||
RecipientDatabase recipientsDatabase = DatabaseFactory.getRecipientDatabase(context);
|
if (destination.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED) {
|
||||||
Optional<RecipientSettings> recipientPreferences = recipientsDatabase.getRecipientSettings(destination);
|
return true;
|
||||||
|
} else if (destination.resolve().getRegistered() == RecipientDatabase.RegisteredState.NOT_REGISTERED) {
|
||||||
if (recipientPreferences.isPresent()) {
|
return false;
|
||||||
return recipientPreferences.get().isRegistered();
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
SignalServiceAccountManager accountManager = AccountManagerFactory.createManager(context);
|
SignalServiceAccountManager accountManager = AccountManagerFactory.createManager(context);
|
||||||
Optional<ContactTokenDetails> registeredUser = accountManager.getContact(destination.serialize());
|
Optional<ContactTokenDetails> registeredUser = accountManager.getContact(destination.getAddress().serialize());
|
||||||
|
|
||||||
if (!registeredUser.isPresent()) {
|
if (!registeredUser.isPresent()) {
|
||||||
recipientsDatabase.setRegistered(new LinkedList<>(), Util.asList(destination));
|
DatabaseFactory.getRecipientDatabase(context).setRegistered(destination, RecipientDatabase.RegisteredState.NOT_REGISTERED);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
recipientsDatabase.setRegistered(Util.asList(destination), new LinkedList<>());
|
DatabaseFactory.getRecipientDatabase(context).setRegistered(destination, RecipientDatabase.RegisteredState.REGISTERED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
||||||
@ -44,10 +45,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class DirectoryHelper {
|
public class DirectoryHelper {
|
||||||
|
|
||||||
public enum Capability {
|
|
||||||
UNKNOWN, SUPPORTED, UNSUPPORTED
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = DirectoryHelper.class.getSimpleName();
|
private static final String TAG = DirectoryHelper.class.getSimpleName();
|
||||||
|
|
||||||
public static void refreshDirectory(@NonNull Context context, @Nullable MasterSecret masterSecret)
|
public static void refreshDirectory(@NonNull Context context, @Nullable MasterSecret masterSecret)
|
||||||
@ -76,30 +73,35 @@ public class DirectoryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
||||||
Set<Address> eligibleContactNumbers = recipientDatabase.getAllRecipients();
|
Stream<String> eligibleRecipientDatabaseContactNumbers = Stream.of(recipientDatabase.getAllRecipients()).map(recipient -> recipient.getAddress().serialize());
|
||||||
eligibleContactNumbers.addAll(ContactAccessor.getInstance().getAllContactsWithNumbers(context));
|
Stream<String> eligibleSystemDatabaseContactNumbers = Stream.of(ContactAccessor.getInstance().getAllContactsWithNumbers(context)).map(Address::serialize);
|
||||||
|
Set<String> eligibleContactNumbers = Stream.concat(eligibleRecipientDatabaseContactNumbers, eligibleSystemDatabaseContactNumbers).collect(Collectors.toSet());
|
||||||
|
|
||||||
Set<String> serializedAddress = Stream.of(eligibleContactNumbers).map(Address::serialize).collect(Collectors.toSet());
|
List<ContactTokenDetails> activeTokens = accountManager.getContacts(eligibleContactNumbers);
|
||||||
List<ContactTokenDetails> activeTokens = accountManager.getContacts(serializedAddress);
|
|
||||||
|
|
||||||
if (activeTokens != null) {
|
if (activeTokens != null) {
|
||||||
List<Address> activeAddresses = new LinkedList<>();
|
List<Recipient> activeRecipients = new LinkedList<>();
|
||||||
Set<Address> inactiveAddresses = new HashSet<>(eligibleContactNumbers);
|
List<Recipient> inactiveRecipients = new LinkedList<>();
|
||||||
|
|
||||||
|
Set<String> inactiveContactNumbers = new HashSet<>(eligibleContactNumbers);
|
||||||
|
|
||||||
for (ContactTokenDetails activeToken : activeTokens) {
|
for (ContactTokenDetails activeToken : activeTokens) {
|
||||||
Address activeAddress = Address.fromSerialized(activeToken.getNumber());
|
activeRecipients.add(Recipient.from(context, Address.fromSerialized(activeToken.getNumber()), true));
|
||||||
activeAddresses.add(activeAddress);
|
inactiveContactNumbers.remove(activeToken.getNumber());
|
||||||
inactiveAddresses.remove(activeAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recipientDatabase.setRegistered(activeAddresses, new LinkedList<>(inactiveAddresses));
|
for (String inactiveContactNumber : inactiveContactNumbers) {
|
||||||
return updateContactsDatabase(context, activeAddresses, true);
|
inactiveRecipients.add(Recipient.from(context, Address.fromSerialized(inactiveContactNumber), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
recipientDatabase.setRegistered(activeRecipients, inactiveRecipients);
|
||||||
|
return updateContactsDatabase(context, Stream.of(activeRecipients).map(Recipient::getAddress).toList(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RefreshResult(new LinkedList<>(), false);
|
return new RefreshResult(new LinkedList<>(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Capability refreshDirectoryFor(@NonNull Context context,
|
public static RegisteredState refreshDirectoryFor(@NonNull Context context,
|
||||||
@Nullable MasterSecret masterSecret,
|
@Nullable MasterSecret masterSecret,
|
||||||
@NonNull Recipient recipient)
|
@NonNull Recipient recipient)
|
||||||
throws IOException
|
throws IOException
|
||||||
@ -110,7 +112,7 @@ public class DirectoryHelper {
|
|||||||
Optional<ContactTokenDetails> details = accountManager.getContact(number);
|
Optional<ContactTokenDetails> details = accountManager.getContact(number);
|
||||||
|
|
||||||
if (details.isPresent()) {
|
if (details.isPresent()) {
|
||||||
recipientDatabase.setRegistered(Util.asList(recipient.getAddress()), new LinkedList<>());
|
recipientDatabase.setRegistered(recipient, RegisteredState.REGISTERED);
|
||||||
|
|
||||||
RefreshResult result = updateContactsDatabase(context, Util.asList(recipient.getAddress()), false);
|
RefreshResult result = updateContactsDatabase(context, Util.asList(recipient.getAddress()), false);
|
||||||
|
|
||||||
@ -122,38 +124,13 @@ public class DirectoryHelper {
|
|||||||
notifyNewUsers(context, masterSecret, result.getNewUsers());
|
notifyNewUsers(context, masterSecret, result.getNewUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Capability.SUPPORTED;
|
return RegisteredState.REGISTERED;
|
||||||
} else {
|
} else {
|
||||||
recipientDatabase.setRegistered(new LinkedList<>(), Util.asList(recipient.getAddress()));
|
recipientDatabase.setRegistered(recipient, RegisteredState.NOT_REGISTERED);
|
||||||
return Capability.UNSUPPORTED;
|
return RegisteredState.NOT_REGISTERED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull Capability getUserCapabilities(@NonNull Context context, @Nullable Recipient recipient) {
|
|
||||||
if (recipient == null) {
|
|
||||||
return Capability.UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
|
||||||
return Capability.UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipient.isMmsGroupRecipient()) {
|
|
||||||
return Capability.UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipient.isPushGroupRecipient()) {
|
|
||||||
return Capability.SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
final RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
|
||||||
final Optional<RecipientSettings> recipientSettings = recipientDatabase.getRecipientSettings(recipient.getAddress());
|
|
||||||
|
|
||||||
if (recipientSettings.isPresent() && recipientSettings.get().isRegistered()) return Capability.SUPPORTED;
|
|
||||||
else if (recipientSettings.isPresent()) return Capability.UNSUPPORTED;
|
|
||||||
else return Capability.UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NonNull RefreshResult updateContactsDatabase(@NonNull Context context, @NonNull List<Address> activeAddresses, boolean removeMissing) {
|
private static @NonNull RefreshResult updateContactsDatabase(@NonNull Context context, @NonNull List<Address> activeAddresses, boolean removeMissing) {
|
||||||
Optional<AccountHolder> account = getOrCreateAccount(context);
|
Optional<AccountHolder> account = getOrCreateAccount(context);
|
||||||
|
|
||||||
@ -171,9 +148,10 @@ public class DirectoryHelper {
|
|||||||
|
|
||||||
if (!TextUtils.isEmpty(number)) {
|
if (!TextUtils.isEmpty(number)) {
|
||||||
Address address = Address.fromExternal(context, number);
|
Address address = Address.fromExternal(context, number);
|
||||||
|
Recipient recipient = Recipient.from(context, address, true);
|
||||||
String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
|
String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
|
||||||
|
|
||||||
handle.setDisplayName(address, displayName);
|
handle.setDisplayName(recipient, displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user