diff --git a/res/drawable-hdpi/ic_favorite_grey600_24dp.png b/res/drawable-hdpi/ic_favorite_grey600_24dp.png
new file mode 100644
index 0000000000..2bdad7d3f1
Binary files /dev/null and b/res/drawable-hdpi/ic_favorite_grey600_24dp.png differ
diff --git a/res/drawable-mdpi/ic_favorite_grey600_24dp.png b/res/drawable-mdpi/ic_favorite_grey600_24dp.png
new file mode 100644
index 0000000000..63f13a33b4
Binary files /dev/null and b/res/drawable-mdpi/ic_favorite_grey600_24dp.png differ
diff --git a/res/drawable-xhdpi/ic_favorite_grey600_24dp.png b/res/drawable-xhdpi/ic_favorite_grey600_24dp.png
new file mode 100644
index 0000000000..c4ad1cb303
Binary files /dev/null and b/res/drawable-xhdpi/ic_favorite_grey600_24dp.png differ
diff --git a/res/drawable-xxhdpi/ic_favorite_grey600_24dp.png b/res/drawable-xxhdpi/ic_favorite_grey600_24dp.png
new file mode 100644
index 0000000000..11f108dad1
Binary files /dev/null and b/res/drawable-xxhdpi/ic_favorite_grey600_24dp.png differ
diff --git a/res/drawable-xxxhdpi/ic_favorite_grey600_24dp.png b/res/drawable-xxxhdpi/ic_favorite_grey600_24dp.png
new file mode 100644
index 0000000000..e8ee60e7e6
Binary files /dev/null and b/res/drawable-xxxhdpi/ic_favorite_grey600_24dp.png differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a8c0053050..db0cd9c708 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -291,6 +291,7 @@
%s called you
Called %s
Missed call from %s
+ %s is on Signal, say hey!
@@ -447,6 +448,7 @@
Called you
Missed call
Media message
+ %s is on Signal, say hey!
You do not have an identity key.
diff --git a/res/xml/syncadapter.xml b/res/xml/syncadapter.xml
index 67a058349f..7804e40217 100644
--- a/res/xml/syncadapter.xml
+++ b/res/xml/syncadapter.xml
@@ -3,6 +3,6 @@
android:contentAuthority="com.android.contacts"
android:accountType="org.thoughtcrime.securesms"
android:userVisible="true"
- android:supportsUploading="false"
+ android:supportsUploading="true"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true"/>
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
index ff7f43d078..8517f6e275 100644
--- a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
+++ b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
@@ -61,6 +61,7 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
protected ContactSelectionListFragment contactsFragment;
+ private MasterSecret masterSecret;
private Toolbar toolbar;
private EditText searchText;
private AnimatingToggle toggle;
@@ -79,6 +80,7 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
@Override
protected void onCreate(Bundle icicle, MasterSecret masterSecret) {
setContentView(R.layout.contact_selection_activity);
+ this.masterSecret = masterSecret;
initializeToolbar();
initializeResources();
@@ -216,16 +218,19 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
private static class RefreshDirectoryTask extends AsyncTask {
private final WeakReference activity;
+ private final MasterSecret masterSecret;
private RefreshDirectoryTask(ContactSelectionActivity activity) {
- this.activity = new WeakReference<>(activity);
+ this.activity = new WeakReference<>(activity);
+ this.masterSecret = activity.masterSecret;
}
@Override
protected Void doInBackground(Context... params) {
+
try {
- DirectoryHelper.refreshDirectory(params[0]);
+ DirectoryHelper.refreshDirectory(params[0], masterSecret);
} catch (IOException e) {
Log.w(TAG, e);
}
diff --git a/src/org/thoughtcrime/securesms/ConversationAdapter.java b/src/org/thoughtcrime/securesms/ConversationAdapter.java
index 9a2b599ed9..23d7fa5e34 100644
--- a/src/org/thoughtcrime/securesms/ConversationAdapter.java
+++ b/src/org/thoughtcrime/securesms/ConversationAdapter.java
@@ -158,13 +158,17 @@ public class ConversationAdapter
@Override
public int getItemViewType(@NonNull Cursor cursor) {
- long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID));
- String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
+ long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID));
+ String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
- if (messageRecord.isGroupAction() || messageRecord.isCallLog()) return MESSAGE_TYPE_UPDATE;
- else if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING;
- else return MESSAGE_TYPE_INCOMING;
+ if (messageRecord.isGroupAction() || messageRecord.isCallLog() || messageRecord.isJoined()) {
+ return MESSAGE_TYPE_UPDATE;
+ } else if (messageRecord.isOutgoing()) {
+ return MESSAGE_TYPE_OUTGOING;
+ } else {
+ return MESSAGE_TYPE_INCOMING;
+ }
}
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
diff --git a/src/org/thoughtcrime/securesms/ConversationUpdateItem.java b/src/org/thoughtcrime/securesms/ConversationUpdateItem.java
index c31b8b68a3..39fa1d82d3 100644
--- a/src/org/thoughtcrime/securesms/ConversationUpdateItem.java
+++ b/src/org/thoughtcrime/securesms/ConversationUpdateItem.java
@@ -70,7 +70,8 @@ public class ConversationUpdateItem extends LinearLayout
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
- else throw new AssertionError("Neither group no log.");
+ else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
+ else throw new AssertionError("Neither group nor log nor joined.");
}
private void setCallRecord(MessageRecord messageRecord) {
@@ -99,6 +100,12 @@ public class ConversationUpdateItem extends LinearLayout
date.setVisibility(View.GONE);
}
+ private void setJoinedRecord(MessageRecord messageRecord) {
+ icon.setImageResource(R.drawable.ic_favorite_grey600_24dp);
+ body.setText(messageRecord.getDisplayBody());
+ date.setVisibility(View.GONE);
+ }
+
@Override
public void onModified(Recipients recipients) {
onModified(recipients.getPrimaryRecipient());
diff --git a/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java b/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java
index 24b59ef62f..b9cc8a17d8 100644
--- a/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java
+++ b/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java
@@ -32,14 +32,18 @@ import android.provider.ContactsContract.RawContacts;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Pair;
import org.thoughtcrime.securesms.R;
import org.whispersystems.libaxolotl.util.guava.Optional;
+import org.whispersystems.textsecure.api.util.InvalidNumberException;
+import org.whispersystems.textsecure.api.util.PhoneNumberFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -70,11 +74,14 @@ public class ContactsDatabase {
this.context = context;
}
- public synchronized boolean setRegisteredUsers(Account account, List e164numbers)
+ public synchronized @NonNull List setRegisteredUsers(@NonNull Account account,
+ @NonNull String localNumber,
+ @NonNull List e164numbers)
throws RemoteException, OperationApplicationException
{
Map currentContacts = new HashMap<>();
Set registeredNumbers = new HashSet<>(e164numbers);
+ List addedNumbers = new LinkedList<>();
ArrayList operations = new ArrayList<>();
Uri currentContactsUri = RawContacts.CONTENT_URI.buildUpon()
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
@@ -86,7 +93,16 @@ public class ContactsDatabase {
cursor = context.getContentResolver().query(currentContactsUri, new String[] {BaseColumns._ID, RawContacts.SYNC1}, null, null, null);
while (cursor != null && cursor.moveToNext()) {
- currentContacts.put(cursor.getString(1), cursor.getLong(0));
+ String currentNumber;
+
+ try {
+ currentNumber = PhoneNumberFormatter.formatNumber(cursor.getString(1), localNumber);
+ } catch (InvalidNumberException e) {
+ Log.w(TAG, e);
+ currentNumber = cursor.getString(1);
+ }
+
+ currentContacts.put(currentNumber, cursor.getLong(0));
}
} finally {
if (cursor != null)
@@ -95,10 +111,11 @@ public class ContactsDatabase {
for (String number : e164numbers) {
if (!currentContacts.containsKey(number)) {
- Optional> systemContactInfo = getSystemContactInfo(number);
+ Optional systemContactInfo = getSystemContactInfo(number);
if (systemContactInfo.isPresent()) {
- addTextSecureRawContact(operations, account, systemContactInfo.get().first, systemContactInfo.get().second);
+ addedNumbers.add(number);
+ addTextSecureRawContact(operations, account, systemContactInfo.get().number, systemContactInfo.get().id);
}
}
}
@@ -111,14 +128,15 @@ public class ContactsDatabase {
if (!operations.isEmpty()) {
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
- return true;
- } else {
- return false;
}
+
+ return addedNumbers;
}
private void addTextSecureRawContact(List operations,
- Account account, String e164number, long aggregateId)
+ Account account,
+ String e164number,
+ long aggregateId)
{
int index = operations.size();
Uri dataUri = ContactsContract.Data.CONTENT_URI.buildUpon()
@@ -254,10 +272,11 @@ public class ContactsDatabase {
return newNumberCursor;
}
- private Optional> getSystemContactInfo(String e164number) {
+ private Optional getSystemContactInfo(String e164number) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(e164number));
String[] projection = {ContactsContract.PhoneLookup.NUMBER,
- ContactsContract.PhoneLookup._ID};
+ ContactsContract.PhoneLookup._ID,
+ ContactsContract.PhoneLookup.DISPLAY_NAME};
Cursor numberCursor = null;
Cursor idCursor = null;
@@ -272,7 +291,9 @@ public class ContactsDatabase {
null);
if (idCursor != null && idCursor.moveToNext()) {
- return Optional.of(new Pair<>(numberCursor.getString(0), idCursor.getLong(0)));
+ return Optional.of(new SystemContactInfo(numberCursor.getString(2),
+ numberCursor.getString(0),
+ idCursor.getLong(0)));
}
}
} finally {
@@ -381,4 +402,16 @@ public class ContactsDatabase {
return null;
}
}
+
+ private static class SystemContactInfo {
+ private final String name;
+ private final String number;
+ private final long id;
+
+ private SystemContactInfo(String name, String number, long id) {
+ this.name = name;
+ this.number = number;
+ this.id = id;
+ }
+ }
}
diff --git a/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java b/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java
index 996c8fc86d..383248b85c 100644
--- a/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java
+++ b/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java
@@ -8,6 +8,7 @@ import android.content.SyncResult;
import android.os.Bundle;
import android.util.Log;
+import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import java.io.IOException;
@@ -25,7 +26,7 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
ContentProviderClient provider, SyncResult syncResult)
{
try {
- DirectoryHelper.refreshDirectory(getContext());
+ DirectoryHelper.refreshDirectory(getContext(), KeyCachingService.getMasterSecret(getContext()));
} catch (IOException e) {
Log.w(TAG, e);
}
diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
index fcb24c6660..b089b8019b 100644
--- a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
+++ b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
@@ -22,6 +22,7 @@ public interface MmsSmsColumns {
protected static final long INCOMING_CALL_TYPE = 1;
protected static final long OUTGOING_CALL_TYPE = 2;
protected static final long MISSED_CALL_TYPE = 3;
+ protected static final long JOINED_TYPE = 4;
protected static final long BASE_INBOX_TYPE = 20;
protected static final long BASE_OUTBOX_TYPE = 21;
@@ -114,6 +115,10 @@ public interface MmsSmsColumns {
return (type & BASE_TYPE_MASK) == BASE_INBOX_TYPE;
}
+ public static boolean isJoinedType(long type) {
+ return (type & BASE_TYPE_MASK) == JOINED_TYPE;
+ }
+
public static boolean isSecureType(long type) {
return (type & SECURE_MESSAGE_BIT) != 0;
}
diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
index fcdd44b1d8..0f17ebab66 100644
--- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
@@ -384,7 +384,9 @@ public class SmsDatabase extends MessagingDatabase {
}
protected Pair insertMessageInbox(IncomingTextMessage message, long type) {
- if (message.isPreKeyBundle()) {
+ if (message.isJoined()) {
+ type = (type & (Types.TOTAL_MASK - Types.BASE_TYPE_MASK)) | Types.JOINED_TYPE;
+ } else if (message.isPreKeyBundle()) {
type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
} else if (message.isSecureMessage()) {
type |= Types.SECURE_MESSAGE_BIT;
diff --git a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java
index 67c13ff8a4..c473438828 100644
--- a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java
@@ -99,6 +99,10 @@ public abstract class DisplayRecord {
return SmsDatabase.Types.isCallLog(type);
}
+ public boolean isJoined() {
+ return SmsDatabase.Types.isJoinedType(type);
+ }
+
public boolean isIncomingCall() {
return SmsDatabase.Types.isIncomingCall(type);
}
diff --git a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
index 69b7d1f7a3..5093d66161 100644
--- a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
@@ -121,6 +121,8 @@ public abstract class MessageRecord extends DisplayRecord {
return emphasisAdded(context.getString(R.string.MessageRecord_called_s, getIndividualRecipient().toShortString()));
} else if (isMissedCall()) {
return emphasisAdded(context.getString(R.string.MessageRecord_missed_call_from, getIndividualRecipient().toShortString()));
+ } else if (isJoined()) {
+ return emphasisAdded(context.getString(R.string.MessageRecord_s_is_on_signal_say_hey, getIndividualRecipient().toShortString()));
} else if (getBody().getBody().length() > MAX_DISPLAY_LENGTH) {
return new SpannableString(getBody().getBody().substring(0, MAX_DISPLAY_LENGTH));
}
diff --git a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
index 96223e04df..539167646b 100644
--- a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
@@ -90,6 +90,8 @@ public class ThreadRecord extends DisplayRecord {
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_called_you));
} else if (SmsDatabase.Types.isMissedCall(type)) {
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_missed_call));
+ } else if (SmsDatabase.Types.isJoinedType(type)) {
+ return emphasisAdded(context.getString(R.string.ThreadRecord_s_is_on_signal_say_hey, getRecipients().getPrimaryRecipient().toShortString()));
} else {
if (TextUtils.isEmpty(getBody().getBody())) {
return new SpannableString(emphasisAdded(context.getString(R.string.ThreadRecord_media_message)));
diff --git a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java b/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
index bb80d3361f..dbadaf0a9c 100644
--- a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.os.PowerManager;
import org.thoughtcrime.securesms.crypto.SecurityEvent;
+import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@@ -30,7 +31,7 @@ public class DirectoryRefreshJob extends ContextJob {
try {
wakeLock.acquire();
- DirectoryHelper.refreshDirectory(context);
+ DirectoryHelper.refreshDirectory(context, KeyCachingService.getMasterSecret(context));
SecurityEvent.broadcastSecurityUpdateEvent(context);
} finally {
if (wakeLock.isHeld()) wakeLock.release();
diff --git a/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java b/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java
index 03e633a58f..9e70ce8cd9 100644
--- a/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java
+++ b/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java
@@ -14,6 +14,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class DirectoryRefreshListener extends BroadcastReceiver {
+ private static final String TAG = DirectoryRefreshListener.class.getSimpleName();
+
private static final String REFRESH_EVENT = "org.whispersystems.whisperpush.DIRECTORY_REFRESH";
private static final String BOOT_EVENT = "android.intent.action.BOOT_COMPLETED";
@@ -51,7 +53,7 @@ public class DirectoryRefreshListener extends BroadcastReceiver {
time = System.currentTimeMillis() + INTERVAL;
}
- Log.w("DirectoryRefreshListener", "Scheduling for: " + time);
+ Log.w(TAG, "Scheduling for: " + time);
alarmManager.cancel(pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
diff --git a/src/org/thoughtcrime/securesms/sms/IncomingJoinedMessage.java b/src/org/thoughtcrime/securesms/sms/IncomingJoinedMessage.java
new file mode 100644
index 0000000000..993f80ffdb
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/sms/IncomingJoinedMessage.java
@@ -0,0 +1,22 @@
+package org.thoughtcrime.securesms.sms;
+
+import org.whispersystems.libaxolotl.util.guava.Optional;
+import org.whispersystems.textsecure.api.messages.TextSecureGroup;
+
+public class IncomingJoinedMessage extends IncomingTextMessage {
+
+ public IncomingJoinedMessage(String sender) {
+ super(sender, 1, System.currentTimeMillis(), null, Optional.absent());
+ }
+
+ @Override
+ public boolean isJoined() {
+ return true;
+ }
+
+ @Override
+ public boolean isSecureMessage() {
+ return true;
+ }
+
+}
diff --git a/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java b/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java
index 7c399fd600..5339f6d68f 100644
--- a/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java
+++ b/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java
@@ -188,6 +188,10 @@ public class IncomingTextMessage implements Parcelable {
return false;
}
+ public boolean isJoined() {
+ return false;
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java
index 496415d73a..4a0b97e559 100644
--- a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java
+++ b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java
@@ -7,17 +7,25 @@ import android.content.Context;
import android.content.OperationApplicationException;
import android.os.RemoteException;
import android.provider.ContactsContract;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
+import android.util.Pair;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.R;
+import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.NotInDirectoryException;
import org.thoughtcrime.securesms.database.TextSecureDirectory;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
+import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
+import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
+import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
+import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability;
import org.whispersystems.libaxolotl.util.guava.Optional;
import org.whispersystems.textsecure.api.TextSecureAccountManager;
@@ -59,13 +67,29 @@ public class DirectoryHelper {
private static final String TAG = DirectoryHelper.class.getSimpleName();
- public static void refreshDirectory(final Context context) throws IOException {
- refreshDirectory(context,
- TextSecureCommunicationFactory.createManager(context),
- TextSecurePreferences.getLocalNumber(context));
+ public static void refreshDirectory(@NonNull Context context, @Nullable MasterSecret masterSecret)
+ throws IOException
+ {
+ List newUsers = refreshDirectory(context,
+ TextSecureCommunicationFactory.createManager(context),
+ TextSecurePreferences.getLocalNumber(context));
+
+ if (!newUsers.isEmpty() && TextSecurePreferences.isMultiDevice(context)) {
+ ApplicationContext.getInstance(context)
+ .getJobManager()
+ .add(new MultiDeviceContactUpdateJob(context));
+ }
+
+ for (String newUser : newUsers) {
+ IncomingJoinedMessage message = new IncomingJoinedMessage(newUser);
+ Pair smsAndThreadId = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message);
+ MessageNotifier.updateNotification(context, masterSecret, smsAndThreadId.second);
+ }
}
- public static void refreshDirectory(final Context context, final TextSecureAccountManager accountManager, final String localNumber)
+ public static @NonNull List refreshDirectory(@NonNull Context context,
+ @NonNull TextSecureAccountManager accountManager,
+ @NonNull String localNumber)
throws IOException
{
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
@@ -89,19 +113,15 @@ public class DirectoryHelper {
}
try {
- boolean modified = DatabaseFactory.getContactsDatabase(context)
- .setRegisteredUsers(account.get(), e164numbers);
-
- if (modified && TextSecurePreferences.isMultiDevice(context)) {
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new MultiDeviceContactUpdateJob(context));
- }
+ return DatabaseFactory.getContactsDatabase(context)
+ .setRegisteredUsers(account.get(), localNumber, e164numbers);
} catch (RemoteException | OperationApplicationException e) {
Log.w(TAG, e);
}
}
}
+
+ return new LinkedList<>();
}
public static UserCapabilities refreshDirectoryFor(Context context, Recipients recipients)
@@ -173,8 +193,16 @@ public class DirectoryHelper {
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType("org.thoughtcrime.securesms");
- if (accounts.length == 0) return createAccount(context);
- else return Optional.of(accounts[0]);
+ Optional account;
+
+ if (accounts.length == 0) account = createAccount(context);
+ else account = Optional.of(accounts[0]);
+
+ if (account.isPresent() && !ContentResolver.getSyncAutomatically(account.get(), ContactsContract.AUTHORITY)) {
+ ContentResolver.setSyncAutomatically(account.get(), ContactsContract.AUTHORITY, true);
+ }
+
+ return account;
}
private static Optional createAccount(Context context) {