mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Support for syncing contact colors and block lists
Closes #5638 // FREEBIE
This commit is contained in:
parent
0a569676f7
commit
32f5bd5336
@ -72,7 +72,7 @@ dependencies {
|
||||
compile 'org.whispersystems:jobmanager:1.0.2'
|
||||
compile 'org.whispersystems:libpastelog:1.0.7'
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile 'org.whispersystems:signal-service-android:2.2.0'
|
||||
compile 'org.whispersystems:signal-service-android:2.3.0'
|
||||
compile 'com.h6ah4i.android.compat:mulsellistprefcompat:1.0.0'
|
||||
compile 'com.google.zxing:core:3.2.1'
|
||||
|
||||
@ -130,7 +130,7 @@ dependencyVerification {
|
||||
'org.whispersystems:jobmanager:506f679fc2fcf7bb6d10f00f41d6f6ea0abf75c70dc95b913398661ad538a181',
|
||||
'org.whispersystems:libpastelog:bb331d9a98240fc139101128ba836c1edec3c40e000597cdbb29ebf4cbf34d88',
|
||||
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
|
||||
'org.whispersystems:signal-service-android:96a926b0bfd1df8b66be2b574e8b8d6ef1862f715b0f1a5457a2038b28d3ad1b',
|
||||
'org.whispersystems:signal-service-android:2831fdde52117615a7ec479d76ba9cbcdc51d0845db28723981bd0e9426aadb7',
|
||||
'com.h6ah4i.android.compat:mulsellistprefcompat:47167c5cb796de1a854788e9ff318358e36c8fb88123baaa6e38fb78511dfabe',
|
||||
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||
'cn.carbswang.android:NumberPickerView:18b3c316d62c7c277978a8d4ed57a5b8f4e943762264960f579a8a549c756729',
|
||||
@ -140,7 +140,7 @@ dependencyVerification {
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||
'org.whispersystems:signal-protocol-android:d83cb3d15b667fc2543fa18ce80791c72c053e8ac54fc2941f0429a5944ca691',
|
||||
'org.whispersystems:signal-service-java:7932363fec666fdc0b4b424eeca4bdca235f6bf2f226fb6a6ff742c49fc37087',
|
||||
'org.whispersystems:signal-service-java:f6541d4e4f8bd83f618696db7ff6c78215110ed82de46d19aa541a64ec69226a',
|
||||
'com.google.android.gms:play-services-basement:e1d29b21e02fd2a63e5a31807415cbb17a59568e27e3254181c01ffae10659bf',
|
||||
'org.whispersystems:curve25519-android:d6a3ef3a70622af4c728b7fe5f8fdfc9e6cd39b1d39b2c77e7a2add9d876bc23',
|
||||
'org.whispersystems:signal-protocol-java:d518d52eeb3c44210e0b6c687360848a87afbaee0bdf42e2a8dd9974d54fdb3a',
|
||||
|
@ -95,6 +95,7 @@ import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
||||
@ -566,6 +567,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
protected Void doInBackground(Void... params) {
|
||||
DatabaseFactory.getRecipientPreferenceDatabase(ConversationActivity.this)
|
||||
.setBlocked(recipients, false);
|
||||
|
||||
ApplicationContext.getInstance(ConversationActivity.this)
|
||||
.getJobManager()
|
||||
.add(new MultiDeviceBlockedUpdateJob(ConversationActivity.this));
|
||||
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
|
@ -33,6 +33,8 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||
import org.thoughtcrime.securesms.preferences.AdvancedRingtonePreference;
|
||||
import org.thoughtcrime.securesms.preferences.ColorPreference;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
@ -357,8 +359,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
DatabaseFactory.getRecipientPreferenceDatabase(getActivity())
|
||||
Context context = getActivity();
|
||||
DatabaseFactory.getRecipientPreferenceDatabase(context)
|
||||
.setColor(recipients, selectedColor);
|
||||
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new MultiDeviceContactUpdateJob(context, recipients.getPrimaryRecipient().getRecipientId()));
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
@ -459,8 +466,14 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
DatabaseFactory.getRecipientPreferenceDatabase(getActivity())
|
||||
Context context = getActivity();
|
||||
|
||||
DatabaseFactory.getRecipientPreferenceDatabase(context)
|
||||
.setBlocked(recipients, blocked);
|
||||
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new MultiDeviceBlockedUpdateJob(context));
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
|
@ -66,7 +66,7 @@ public class ContactAccessor {
|
||||
final String[] inProjection = new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME};
|
||||
|
||||
List<String> pushNumbers = TextSecureDirectory.getInstance(context).getActiveNumbers();
|
||||
final Collection<ContactData> lookupData = new ArrayList<ContactData>(pushNumbers.size());
|
||||
final Collection<ContactData> lookupData = new ArrayList<>(pushNumbers.size());
|
||||
|
||||
for (String pushNumber : pushNumbers) {
|
||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(pushNumber));
|
||||
|
@ -11,6 +11,7 @@ import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
@ -80,6 +81,10 @@ public class RecipientPreferenceDatabase extends Database {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public BlockedReader readerForBlocked(Cursor cursor) {
|
||||
return new BlockedReader(context, cursor);
|
||||
}
|
||||
|
||||
public Optional<RecipientsPreferences> getRecipientsPreferences(@NonNull long[] recipients) {
|
||||
Arrays.sort(recipients);
|
||||
|
||||
@ -255,4 +260,28 @@ public class RecipientPreferenceDatabase extends Database {
|
||||
return expireMessages;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BlockedReader {
|
||||
|
||||
private final Context context;
|
||||
private final Cursor cursor;
|
||||
|
||||
public BlockedReader(Context context, Cursor cursor) {
|
||||
this.context = context;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
public @NonNull Recipients getCurrent() {
|
||||
String recipientIds = cursor.getString(cursor.getColumnIndexOrThrow(RECIPIENT_IDS));
|
||||
return RecipientFactory.getRecipientsForIds(context, recipientIds, false);
|
||||
}
|
||||
|
||||
public @Nullable Recipients getNext() {
|
||||
if (!cursor.moveToNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.jobs.CleanPreKeysJob;
|
||||
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
|
||||
import org.thoughtcrime.securesms.jobs.DeliveryReceiptJob;
|
||||
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
|
||||
@ -45,6 +46,7 @@ import dagger.Provides;
|
||||
MultiDeviceContactUpdateJob.class,
|
||||
MultiDeviceGroupUpdateJob.class,
|
||||
MultiDeviceReadUpdateJob.class,
|
||||
MultiDeviceBlockedUpdateJob.class,
|
||||
DeviceListFragment.class,
|
||||
RefreshAttributesJob.class,
|
||||
GcmRefreshJob.class})
|
||||
|
@ -0,0 +1,79 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.BlockedReader;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.dependencies.TextSecureCommunicationModule.TextSecureMessageSenderFactory;
|
||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.whispersystems.jobqueue.JobParameters;
|
||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements InjectableType {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String TAG = MultiDeviceBlockedUpdateJob.class.getSimpleName();
|
||||
|
||||
@Inject transient TextSecureMessageSenderFactory messageSenderFactory;
|
||||
|
||||
public MultiDeviceBlockedUpdateJob(Context context) {
|
||||
super(context, JobParameters.newBuilder()
|
||||
.withRequirement(new NetworkRequirement(context))
|
||||
.withRequirement(new MasterSecretRequirement(context))
|
||||
.withGroupId(MultiDeviceBlockedUpdateJob.class.getSimpleName())
|
||||
.withPersistence()
|
||||
.create());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun(MasterSecret masterSecret)
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
RecipientPreferenceDatabase database = DatabaseFactory.getRecipientPreferenceDatabase(context);
|
||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||
BlockedReader reader = database.readerForBlocked(database.getBlocked());
|
||||
List<String> blocked = new LinkedList<>();
|
||||
|
||||
Recipients recipients;
|
||||
|
||||
while ((recipients = reader.getNext()) != null) {
|
||||
if (recipients.isSingleRecipient()) {
|
||||
blocked.add(recipients.getPrimaryRecipient().getNumber());
|
||||
}
|
||||
}
|
||||
|
||||
messageSender.sendMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(blocked)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetryThrowable(Exception exception) {
|
||||
if (exception instanceof PushNetworkException) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {
|
||||
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
@ -14,6 +15,9 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.dependencies.TextSecureCommunicationModule.TextSecureMessageSenderFactory;
|
||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.whispersystems.jobqueue.JobParameters;
|
||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
@ -43,18 +47,56 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
|
||||
|
||||
@Inject transient TextSecureMessageSenderFactory messageSenderFactory;
|
||||
|
||||
private final long recipientId;
|
||||
|
||||
public MultiDeviceContactUpdateJob(Context context) {
|
||||
this(context, -1);
|
||||
}
|
||||
|
||||
public MultiDeviceContactUpdateJob(Context context, long recipientId) {
|
||||
super(context, JobParameters.newBuilder()
|
||||
.withRequirement(new NetworkRequirement(context))
|
||||
.withRequirement(new MasterSecretRequirement(context))
|
||||
.withGroupId(MultiDeviceContactUpdateJob.class.getSimpleName())
|
||||
.withPersistence()
|
||||
.create());
|
||||
|
||||
this.recipientId = recipientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun(MasterSecret masterSecret)
|
||||
throws IOException, UntrustedIdentityException, NetworkException
|
||||
{
|
||||
if (recipientId <= 0) generateFullContactUpdate();
|
||||
else generateSingleContactUpdate(recipientId);
|
||||
}
|
||||
|
||||
private void generateSingleContactUpdate(long recipientId)
|
||||
throws IOException, UntrustedIdentityException, NetworkException
|
||||
{
|
||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||
File contactDataFile = createTempFile("multidevice-contact-update");
|
||||
|
||||
try {
|
||||
DeviceContactsOutputStream out = new DeviceContactsOutputStream(new FileOutputStream(contactDataFile));
|
||||
Recipient recipient = RecipientFactory.getRecipientForId(context, recipientId, false);
|
||||
|
||||
out.write(new DeviceContact(recipient.getNumber(),
|
||||
Optional.fromNullable(recipient.getName()),
|
||||
getAvatar(recipient.getContactUri()),
|
||||
Optional.fromNullable(recipient.getColor().serialize())));
|
||||
|
||||
out.close();
|
||||
sendUpdate(messageSender, contactDataFile);
|
||||
|
||||
} finally {
|
||||
if (contactDataFile != null) contactDataFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFullContactUpdate()
|
||||
throws IOException, UntrustedIdentityException, NetworkException
|
||||
{
|
||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||
File contactDataFile = createTempFile("multidevice-contact-update");
|
||||
@ -67,8 +109,9 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
|
||||
Uri contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactData.id));
|
||||
String number = contactData.numbers.get(0).number;
|
||||
Optional<String> name = Optional.fromNullable(contactData.name);
|
||||
Optional<String> color = getColor(number);
|
||||
|
||||
out.write(new DeviceContact(number, name, getAvatar(contactUri)));
|
||||
out.write(new DeviceContact(number, name, getAvatar(contactUri), color));
|
||||
}
|
||||
|
||||
out.close();
|
||||
@ -95,6 +138,15 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
|
||||
|
||||
}
|
||||
|
||||
private Optional<String> getColor(String number) {
|
||||
if (!TextUtils.isEmpty(number)) {
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, number, false);
|
||||
return Optional.of(recipients.getColor().serialize());
|
||||
} else {
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUpdate(SignalServiceMessageSender messageSender, File contactsFile)
|
||||
throws IOException, UntrustedIdentityException, NetworkException
|
||||
{
|
||||
|
@ -286,6 +286,12 @@ public class PushDecryptJob extends ContextJob {
|
||||
.getJobManager()
|
||||
.add(new MultiDeviceGroupUpdateJob(getContext()));
|
||||
}
|
||||
|
||||
if (message.isBlockedListRequest()) {
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new MultiDeviceBlockedUpdateJob(getContext()));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSynchronizeReadMessage(@NonNull MasterSecretUnion masterSecret,
|
||||
|
Loading…
Reference in New Issue
Block a user