diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 819179fb66..9fdb84a489 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -615,11 +615,6 @@
-
-
-
-
-
diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java
index ccef1114d2..3bf81018ac 100644
--- a/src/org/thoughtcrime/securesms/ApplicationContext.java
+++ b/src/org/thoughtcrime/securesms/ApplicationContext.java
@@ -75,7 +75,6 @@ import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.recipients.Recipient;
-import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
import org.thoughtcrime.securesms.service.KeyCachingService;
@@ -353,7 +352,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
private void initializePeriodicTasks() {
RotateSignedPreKeyListener.schedule(this);
- DirectoryRefreshListener.schedule(this);
LocalBackupListener.schedule(this);
RotateSenderCertificateListener.schedule(this);
BackgroundPollWorker.schedule(this); // Session
diff --git a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
index 6b6f7554ef..e408709009 100644
--- a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
+++ b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
@@ -16,24 +16,17 @@
*/
package org.thoughtcrime.securesms;
-import android.content.Context;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import org.thoughtcrime.securesms.components.ContactFilterToolbar;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
-import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ViewUtil;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-
import network.loki.messenger.R;
/**
@@ -109,44 +102,11 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
}
@Override
- public void onRefresh() {
- new RefreshDirectoryTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getApplicationContext());
- }
+ public void onRefresh() { }
@Override
public void onContactSelected(String number) {}
@Override
public void onContactDeselected(String number) {}
-
- private static class RefreshDirectoryTask extends AsyncTask {
-
- private final WeakReference activity;
-
- private RefreshDirectoryTask(ContactSelectionActivity activity) {
- this.activity = new WeakReference<>(activity);
- }
-
- @Override
- protected Void doInBackground(Context... params) {
-
- try {
- DirectoryHelper.refreshDirectory(params[0], true);
- } catch (IOException e) {
- Log.w(TAG, e);
- }
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- ContactSelectionActivity activity = this.activity.get();
-
- if (activity != null && !activity.isFinishing()) {
- activity.toolbar.clear();
- activity.contactsFragment.resetQueryFilter();
- }
- }
- }
}
diff --git a/src/org/thoughtcrime/securesms/ContactSelectionListFragment.java b/src/org/thoughtcrime/securesms/ContactSelectionListFragment.java
index c4878b861c..c95359516f 100644
--- a/src/org/thoughtcrime/securesms/ContactSelectionListFragment.java
+++ b/src/org/thoughtcrime/securesms/ContactSelectionListFragment.java
@@ -17,7 +17,6 @@
package org.thoughtcrime.securesms;
-import android.Manifest;
import android.annotation.SuppressLint;
import android.database.Cursor;
import android.os.AsyncTask;
@@ -44,14 +43,11 @@ import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
-import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
-import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.ViewUtil;
-import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -259,12 +255,6 @@ public class ContactSelectionListFragment extends Fragment
@Override
protected Boolean doInBackground(Void... voids) {
- try {
- DirectoryHelper.refreshDirectory(getContext(), false);
- return true;
- } catch (IOException e) {
- Log.w(TAG, e);
- }
return false;
}
diff --git a/src/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java b/src/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java
index 67b50b639c..ad9bfcb85e 100644
--- a/src/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java
+++ b/src/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java
@@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.PushDecryptJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.logging.Log;
@@ -250,12 +249,6 @@ public class DatabaseUpgradeActivity extends BaseActivity {
scheduleMessagesInPushDatabase(context);;
}
- if (params[0] < CONTACTS_ACCOUNT_VERSION) {
- ApplicationContext.getInstance(getApplicationContext())
- .getJobManager()
- .add(new DirectoryRefreshJob(false));
- }
-
if (params[0] < MEDIA_DOWNLOAD_CONTROLS_VERSION) {
schedulePendingIncomingParts(context);
}
@@ -264,15 +257,6 @@ public class DatabaseUpgradeActivity extends BaseActivity {
ApplicationContext.getInstance(getApplicationContext())
.getJobManager()
.add(new RefreshAttributesJob());
- ApplicationContext.getInstance(getApplicationContext())
- .getJobManager()
- .add(new DirectoryRefreshJob(false));
- }
-
- if (params[0] < PROFILES) {
- ApplicationContext.getInstance(getApplicationContext())
- .getJobManager()
- .add(new DirectoryRefreshJob(false));
}
if (params[0] < SCREENSHOTS) {
diff --git a/src/org/thoughtcrime/securesms/RegistrationActivity.java b/src/org/thoughtcrime/securesms/RegistrationActivity.java
index ff09e7ed93..6f5ba224be 100644
--- a/src/org/thoughtcrime/securesms/RegistrationActivity.java
+++ b/src/org/thoughtcrime/securesms/RegistrationActivity.java
@@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.database.NoExternalStorageException;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.RotateCertificateJob;
import org.thoughtcrime.securesms.lock.RegistrationLockReminders;
import org.thoughtcrime.securesms.logging.Log;
@@ -57,7 +56,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.push.AccountManagerFactory;
import org.thoughtcrime.securesms.registration.CaptchaActivity;
-import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
import org.thoughtcrime.securesms.util.BackupUtil;
import org.thoughtcrime.securesms.util.DateUtils;
@@ -648,10 +646,8 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
}
private void handleSuccessfulRegistration() {
- ApplicationContext.getInstance(RegistrationActivity.this).getJobManager().add(new DirectoryRefreshJob(false));
ApplicationContext.getInstance(RegistrationActivity.this).getJobManager().add(new RotateCertificateJob(RegistrationActivity.this));
- DirectoryRefreshListener.schedule(RegistrationActivity.this);
RotateSignedPreKeyListener.schedule(RegistrationActivity.this);
Intent nextIntent = getIntent().getParcelableExtra("next_intent");
diff --git a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java
index 724d9aafa6..5e66a9b12c 100644
--- a/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java
+++ b/src/org/thoughtcrime/securesms/contacts/ContactAccessor.java
@@ -16,31 +16,19 @@
*/
package org.thoughtcrime.securesms.contacts;
-import android.content.ContentResolver;
import android.content.Context;
-import android.database.Cursor;
-import android.database.MergeCursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.PhoneLookup;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
+
+import network.loki.messenger.R;
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
@@ -58,91 +46,14 @@ import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
public class ContactAccessor {
- public static final String PUSH_COLUMN = "push";
-
private static final ContactAccessor instance = new ContactAccessor();
public static synchronized ContactAccessor getInstance() {
return instance;
}
- public Set getAllContactsWithNumbers(Context context) {
- Set results = new HashSet<>();
-
- try (Cursor cursor = context.getContentResolver().query(Phone.CONTENT_URI, new String[] {Phone.NUMBER}, null ,null, null)) {
- while (cursor != null && cursor.moveToNext()) {
- if (!TextUtils.isEmpty(cursor.getString(0))) {
- results.add(Address.fromExternal(context, cursor.getString(0)));
- }
- }
- }
-
- return results;
- }
-
- public Cursor getAllSystemContacts(Context context) {
- return context.getContentResolver().query(Phone.CONTENT_URI, new String[] {Phone.NUMBER, Phone.DISPLAY_NAME, Phone.LABEL, Phone.PHOTO_URI, Phone._ID, Phone.LOOKUP_KEY}, null, null, null);
- }
-
- public boolean isSystemContact(Context context, String number) {
- Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
- String[] projection = new String[]{PhoneLookup.DISPLAY_NAME, PhoneLookup.LOOKUP_KEY,
- PhoneLookup._ID, PhoneLookup.NUMBER};
- Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
-
- try {
- if (cursor != null && cursor.moveToFirst()) {
- return true;
- }
- } finally {
- if (cursor != null) cursor.close();
- }
-
- return false;
- }
-
- public Collection getContactsWithPush(Context context) {
- final ContentResolver resolver = context.getContentResolver();
- final String[] inProjection = new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME};
-
- final List registeredAddresses = DatabaseFactory.getRecipientDatabase(context).getRegistered();
- final Collection lookupData = new ArrayList<>(registeredAddresses.size());
-
- for (Address registeredAddress : registeredAddresses) {
- Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(registeredAddress.serialize()));
- Cursor lookupCursor = resolver.query(uri, inProjection, null, null, null);
-
- try {
- if (lookupCursor != null && lookupCursor.moveToFirst()) {
- final ContactData contactData = new ContactData(lookupCursor.getLong(0), lookupCursor.getString(1));
- contactData.numbers.add(new NumberData("TextSecure", registeredAddress.serialize()));
- lookupData.add(contactData);
- }
- } finally {
- if (lookupCursor != null)
- lookupCursor.close();
- }
- }
-
- return lookupData;
- }
-
public String getNameFromContact(Context context, Uri uri) {
- Cursor cursor = null;
-
- try {
- cursor = context.getContentResolver().query(uri, new String[] {Contacts.DISPLAY_NAME},
- null, null, null);
-
- if (cursor != null && cursor.moveToFirst())
- return cursor.getString(0);
-
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
- return null;
+ return "Anonymous";
}
public ContactData getContactData(Context context, Uri uri) {
@@ -150,47 +61,11 @@ public class ContactAccessor {
}
private ContactData getContactData(Context context, String displayName, long id) {
- ContactData contactData = new ContactData(id, displayName);
- Cursor numberCursor = null;
-
- try {
- numberCursor = context.getContentResolver().query(Phone.CONTENT_URI, null,
- Phone.CONTACT_ID + " = ?",
- new String[] {contactData.id + ""}, null);
-
- while (numberCursor != null && numberCursor.moveToNext()) {
- int type = numberCursor.getInt(numberCursor.getColumnIndexOrThrow(Phone.TYPE));
- String label = numberCursor.getString(numberCursor.getColumnIndexOrThrow(Phone.LABEL));
- String number = numberCursor.getString(numberCursor.getColumnIndexOrThrow(Phone.NUMBER));
- String typeLabel = Phone.getTypeLabel(context.getResources(), type, label).toString();
-
- contactData.numbers.add(new NumberData(typeLabel, number));
- }
- } finally {
- if (numberCursor != null)
- numberCursor.close();
- }
-
- return contactData;
+ return new ContactData(id, displayName);
}
public List getNumbersForThreadSearchFilter(Context context, String constraint) {
LinkedList numberList = new LinkedList<>();
- Cursor cursor = null;
-
- try {
- cursor = context.getContentResolver().query(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI,
- Uri.encode(constraint)),
- null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- numberList.add(cursor.getString(cursor.getColumnIndexOrThrow(Phone.NUMBER)));
- }
-
- } finally {
- if (cursor != null)
- cursor.close();
- }
GroupDatabase.Reader reader = null;
GroupRecord record;
@@ -216,7 +91,7 @@ public class ContactAccessor {
}
public CharSequence phoneTypeToString(Context mContext, int type, CharSequence label) {
- return Phone.getTypeLabel(mContext.getResources(), type, label);
+ return label;
}
public static class NumberData implements Parcelable {
@@ -294,82 +169,4 @@ public class ContactAccessor {
}
}
- /***
- * If the code below looks shitty to you, that's because it was taken
- * directly from the Android source, where shitty code is all you get.
- */
-
- public Cursor getCursorForRecipientFilter(CharSequence constraint,
- ContentResolver mContentResolver)
- {
- final String SORT_ORDER = Contacts.TIMES_CONTACTED + " DESC," +
- Contacts.DISPLAY_NAME + "," +
- Contacts.Data.IS_SUPER_PRIMARY + " DESC," +
- Phone.TYPE;
-
- final String[] PROJECTION_PHONE = {
- Phone._ID, // 0
- Phone.CONTACT_ID, // 1
- Phone.TYPE, // 2
- Phone.NUMBER, // 3
- Phone.LABEL, // 4
- Phone.DISPLAY_NAME, // 5
- };
-
- String phone = "";
- String cons = null;
-
- if (constraint != null) {
- cons = constraint.toString();
-
- if (RecipientsAdapter.usefulAsDigits(cons)) {
- phone = PhoneNumberUtils.convertKeypadLettersToDigits(cons);
- if (phone.equals(cons) && !PhoneNumberUtils.isWellFormedSmsAddress(phone)) {
- phone = "";
- } else {
- phone = phone.trim();
- }
- }
- }
- Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(cons));
- String selection = String.format("%s=%s OR %s=%s OR %s=%s",
- Phone.TYPE,
- Phone.TYPE_MOBILE,
- Phone.TYPE,
- Phone.TYPE_WORK_MOBILE,
- Phone.TYPE,
- Phone.TYPE_MMS);
-
- Cursor phoneCursor = mContentResolver.query(uri,
- PROJECTION_PHONE,
- null,
- null,
- SORT_ORDER);
-
- if (phone.length() > 0) {
- ArrayList result = new ArrayList();
- result.add(Integer.valueOf(-1)); // ID
- result.add(Long.valueOf(-1)); // CONTACT_ID
- result.add(Integer.valueOf(Phone.TYPE_CUSTOM)); // TYPE
- result.add(phone); // NUMBER
-
- /*
- * The "\u00A0" keeps Phone.getDisplayLabel() from deciding
- * to display the default label ("Home") next to the transformation
- * of the letters into numbers.
- */
- result.add("\u00A0"); // LABEL
- result.add(cons); // NAME
-
- ArrayList wrap = new ArrayList();
- wrap.add(result);
-
- ArrayListCursor translated = new ArrayListCursor(PROJECTION_PHONE, wrap);
-
- return new MergeCursor(new Cursor[] { translated, phoneCursor });
- } else {
- return phoneCursor;
- }
- }
-
}
diff --git a/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java b/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java
index 50f3408b90..430d580cc7 100644
--- a/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java
+++ b/src/org/thoughtcrime/securesms/contacts/RecipientsAdapter.java
@@ -17,9 +17,6 @@
package org.thoughtcrime.securesms.contacts;
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.recipients.RecipientsFormatter;
-
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
@@ -31,6 +28,10 @@ import android.view.View;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
+import org.thoughtcrime.securesms.recipients.RecipientsFormatter;
+
+import network.loki.messenger.R;
+
/**
* This adapter is used to filter contacts on both name and number.
*/
@@ -118,7 +119,7 @@ public class RecipientsAdapter extends ResourceCursorAdapter {
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
- return mContactAccessor.getCursorForRecipientFilter( constraint, mContentResolver );
+ return null;
}
/**
diff --git a/src/org/thoughtcrime/securesms/contactshare/SharedContactDetailsActivity.java b/src/org/thoughtcrime/securesms/contactshare/SharedContactDetailsActivity.java
index 942192248d..a41e9d9538 100644
--- a/src/org/thoughtcrime/securesms/contactshare/SharedContactDetailsActivity.java
+++ b/src/org/thoughtcrime/securesms/contactshare/SharedContactDetailsActivity.java
@@ -20,11 +20,8 @@ import android.widget.TextView;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
-import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
-import network.loki.messenger.R;
import org.thoughtcrime.securesms.database.RecipientDatabase;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -41,7 +38,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import static org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.*;
+import network.loki.messenger.R;
+
+import static org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
public class SharedContactDetailsActivity extends PassphraseRequiredActionBarActivity implements RecipientModifiedListener {
@@ -246,14 +245,4 @@ public class SharedContactDetailsActivity extends PassphraseRequiredActionBarAct
engageContainerView.setVisibility(View.GONE);
}
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == CODE_ADD_EDIT_CONTACT && contact != null) {
- ApplicationContext.getInstance(getApplicationContext())
- .getJobManager()
- .add(new DirectoryRefreshJob(false));
- }
- }
}
diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java
index 8cb1f03570..9e38a84767 100644
--- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java
@@ -211,7 +211,6 @@ import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.Dialogs;
-import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.ExpirationUtil;
@@ -348,8 +347,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private int distributionType;
private boolean archived;
private boolean isSecureText;
- private boolean isDefaultSms = true;
- private boolean isMmsEnabled = true;
+ private boolean isDefaultSms = false;
+ private boolean isMmsEnabled = false;
private boolean isSecurityInitialized = false;
private int expandedKeyboardHeight = 0;
private int collapsedKeyboardHeight = Integer.MAX_VALUE;
@@ -1478,41 +1477,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
new AsyncTask() {
@Override
protected boolean[] doInBackground(Recipient... params) {
- Context context = ConversationActivity.this;
- Recipient recipient = params[0];
- Log.i(TAG, "Resolving registered state...");
- RegisteredState registeredState;
-
- if (recipient.isPushGroupRecipient()) {
- Log.i(TAG, "Push group recipient...");
- registeredState = RegisteredState.REGISTERED;
- } else if (recipient.isResolving()) {
- Log.i(TAG, "Talking to DB directly.");
- registeredState = DatabaseFactory.getRecipientDatabase(ConversationActivity.this).isRegistered(recipient.getAddress());
- } else {
- Log.i(TAG, "Checking through resolved recipient");
- registeredState = recipient.resolve().getRegistered();
- }
-
- // Loki - Override the flag below
- registeredState = RegisteredState.REGISTERED;
-
- Log.i(TAG, "Resolved registered state: " + registeredState);
// Loki - Override the flag below
boolean signalEnabled = true; // TextSecurePreferences.isPushRegistered(context);
- if (registeredState == RegisteredState.UNKNOWN) {
- try {
- Log.i(TAG, "Refreshing directory for user: " + recipient.getAddress().serialize());
- registeredState = DirectoryHelper.refreshDirectoryFor(context, recipient);
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
- Log.i(TAG, "Returning registered state...");
- return new boolean[] {registeredState == RegisteredState.REGISTERED && signalEnabled,
- Util.isDefaultSmsProvider(context)};
+ return new boolean[] { signalEnabled, false};
}
@Override
diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java
index f89f0578de..cb3b53f007 100644
--- a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java
+++ b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java
@@ -77,7 +77,6 @@ import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
@@ -1076,17 +1075,6 @@ public class ConversationFragment extends Fragment
}
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == CODE_ADD_EDIT_CONTACT && getContext() != null) {
- ApplicationContext.getInstance(getContext().getApplicationContext())
- .getJobManager()
- .add(new DirectoryRefreshJob(false));
- }
- }
-
private class ActionModeCallback implements ActionMode.Callback {
private int statusBarColor;
diff --git a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
index 4957ebd72d..da6e221978 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java
@@ -8,7 +8,6 @@ import org.thoughtcrime.securesms.jobs.AttachmentUploadJob;
import org.thoughtcrime.securesms.jobs.AvatarDownloadJob;
import org.thoughtcrime.securesms.jobs.CleanPreKeysJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.LocalBackupJob;
import org.thoughtcrime.securesms.jobs.MmsDownloadJob;
import org.thoughtcrime.securesms.jobs.MmsReceiveJob;
@@ -57,7 +56,6 @@ public class WorkManagerFactoryMappings {
put(AvatarDownloadJob.class.getName(), AvatarDownloadJob.KEY);
put(CleanPreKeysJob.class.getName(), CleanPreKeysJob.KEY);
put(CreateSignedPreKeyJob.class.getName(), CreateSignedPreKeyJob.KEY);
- put(DirectoryRefreshJob.class.getName(), DirectoryRefreshJob.KEY);
put(LocalBackupJob.class.getName(), LocalBackupJob.KEY);
put(MmsDownloadJob.class.getName(), MmsDownloadJob.KEY);
put(MmsReceiveJob.class.getName(), MmsReceiveJob.KEY);
diff --git a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java b/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
deleted file mode 100644
index 24d4e7d48b..0000000000
--- a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.thoughtcrime.securesms.jobs;
-
-import android.app.Application;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import org.thoughtcrime.securesms.database.Address;
-import org.thoughtcrime.securesms.jobmanager.Data;
-import org.thoughtcrime.securesms.jobmanager.Job;
-import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
-import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.recipients.Recipient;
-import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
-
-import java.io.IOException;
-
-public class DirectoryRefreshJob extends BaseJob {
-
- public static final String KEY = "DirectoryRefreshJob";
-
- private static final String TAG = DirectoryRefreshJob.class.getSimpleName();
-
- private static final String KEY_ADDRESS = "address";
- private static final String KEY_NOTIFY_OF_NEW_USERS = "notify_of_new_users";
-
- @Nullable private Recipient recipient;
- private boolean notifyOfNewUsers;
-
- public DirectoryRefreshJob(boolean notifyOfNewUsers) {
- this(null, notifyOfNewUsers);
- }
-
- public DirectoryRefreshJob(@Nullable Recipient recipient,
- boolean notifyOfNewUsers)
- {
- this(new Job.Parameters.Builder()
- .setQueue("DirectoryRefreshJob")
- .addConstraint(NetworkConstraint.KEY)
- .setMaxAttempts(10)
- .build(),
- recipient,
- notifyOfNewUsers);
- }
-
- private DirectoryRefreshJob(@NonNull Job.Parameters parameters, @Nullable Recipient recipient, boolean notifyOfNewUsers) {
- super(parameters);
-
- this.recipient = recipient;
- this.notifyOfNewUsers = notifyOfNewUsers;
- }
-
- @Override
- public @NonNull Data serialize() {
- return new Data.Builder().putString(KEY_ADDRESS, recipient != null ? recipient.getAddress().serialize() : null)
- .putBoolean(KEY_NOTIFY_OF_NEW_USERS, notifyOfNewUsers)
- .build();
- }
-
- @Override
- public @NonNull String getFactoryKey() {
- return KEY;
- }
-
- @Override
- public void onRun() throws IOException {
- Log.i(TAG, "DirectoryRefreshJob.onRun()");
-
-// if (recipient == null) {
-// DirectoryHelper.refreshDirectory(context, notifyOfNewUsers);
-// } else {
-// DirectoryHelper.refreshDirectoryFor(context, recipient);
-// }
- }
-
- @Override
- public boolean onShouldRetry(@NonNull Exception exception) {
- if (exception instanceof PushNetworkException) return true;
- return false;
- }
-
- @Override
- public void onCanceled() {}
-
- public static final class Factory implements Job.Factory {
-
- private final Application application;
-
- public Factory(@NonNull Application application) {
- this.application = application;
- }
-
- @Override
- public @NonNull DirectoryRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) {
- String serializedAddress = data.getString(KEY_ADDRESS);
- Address address = serializedAddress != null ? Address.fromSerialized(serializedAddress) : null;
- Recipient recipient = address != null ? Recipient.from(application, address, true) : null;
- boolean notifyOfNewUsers = data.getBoolean(KEY_NOTIFY_OF_NEW_USERS);
-
- return new DirectoryRefreshJob(parameters, recipient, notifyOfNewUsers);
- }
- }
-}
diff --git a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
index 3a375a6169..5300f461fd 100644
--- a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
+++ b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java
@@ -31,7 +31,6 @@ public final class JobManagerFactories {
put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory());
put(CleanPreKeysJob.KEY, new CleanPreKeysJob.Factory());
put(CreateSignedPreKeyJob.KEY, new CreateSignedPreKeyJob.Factory());
- put(DirectoryRefreshJob.KEY, new DirectoryRefreshJob.Factory(application));
put(LocalBackupJob.KEY, new LocalBackupJob.Factory());
put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory());
put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory());
diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
index 088a426e96..1447b5bafd 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
@@ -224,7 +224,6 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
if (messageId >= 0) {
database.markAsPendingInsecureSmsFallback(messageId);
notifyMediaMessageDeliveryFailed(context, messageId);
- ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(false));
}
} catch (UntrustedIdentityException uie) {
warn(TAG, "Failure", uie);
diff --git a/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java b/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java
index f9dbfeea25..053ab5d79e 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.jobs;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
-import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
@@ -32,7 +31,6 @@ public abstract class PushReceivedJob extends BaseJob {
if (!isActiveNumber(recipient)) {
DatabaseFactory.getRecipientDatabase(context).setRegistered(recipient, RecipientDatabase.RegisteredState.REGISTERED);
- ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(recipient, false));
}
}
diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
index 6d44fc9b5c..5ce7dd3442 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
@@ -165,7 +165,6 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
if (messageId >= 0) {
database.markAsPendingInsecureSmsFallback(record.getId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId());
- ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(false));
}
} catch (UntrustedIdentityException e) {
warn(TAG, "Failure", e);
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt
index d9147fbfdd..0c3e290556 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt
@@ -12,7 +12,9 @@ import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_linked_devices.*
import network.loki.messenger.R
+import nl.komponents.kovenant.Kovenant
import nl.komponents.kovenant.functional.bind
+import nl.komponents.kovenant.task
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.successUi
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
@@ -24,8 +26,8 @@ import org.thoughtcrime.securesms.loki.signAndSendDeviceLinkMessage
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.api.DeviceLink
-import org.whispersystems.signalservice.loki.api.LokiAPI
import org.whispersystems.signalservice.loki.api.LokiFileServerAPI
+import org.whispersystems.signalservice.loki.utilities.createContext
import java.util.*
import kotlin.concurrent.schedule
@@ -145,7 +147,11 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager
}
override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) {
- LokiFileServerAPI.shared.addDeviceLink(deviceLink).bind(LokiAPI.sharedWorkContext) {
+ val context = Kovenant.createContext("Multi-device")
+ LokiFileServerAPI.shared.addDeviceLink(deviceLink)
+ task(context) {
+ 1
+ }.bind {
signAndSendDeviceLinkMessage(this, deviceLink)
}.successUi {
LoaderManager.getInstance(this).restartLoader(0, null, this)
diff --git a/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java b/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java
deleted file mode 100644
index 8abacdca4d..0000000000
--- a/src/org/thoughtcrime/securesms/service/DirectoryRefreshListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.thoughtcrime.securesms.service;
-
-
-import android.content.Context;
-import android.content.Intent;
-
-import org.thoughtcrime.securesms.ApplicationContext;
-import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-
-import java.util.concurrent.TimeUnit;
-
-public class DirectoryRefreshListener extends PersistentAlarmManagerListener {
-
- private static final long INTERVAL = TimeUnit.HOURS.toMillis(12);
-
- @Override
- protected long getNextScheduledExecutionTime(Context context) {
- return TextSecurePreferences.getDirectoryRefreshTime(context);
- }
-
- @Override
- protected long onAlarm(Context context, long scheduledTime) {
- if (scheduledTime != 0 && TextSecurePreferences.isPushRegistered(context)) {
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new DirectoryRefreshJob(true));
- }
-
- long newTime = System.currentTimeMillis() + INTERVAL;
- TextSecurePreferences.setDirectoryRefreshTime(context, newTime);
-
- return newTime;
- }
-
- public static void schedule(Context context) {
- new DirectoryRefreshListener().onReceive(context, new Intent());
- }
-}
diff --git a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java
deleted file mode 100644
index 7b0fa1c712..0000000000
--- a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java
+++ /dev/null
@@ -1,520 +0,0 @@
-package org.thoughtcrime.securesms.util;
-
-import android.Manifest;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.SuppressLint;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.OperationApplicationException;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.provider.ContactsContract;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import org.thoughtcrime.securesms.logging.Log;
-
-import com.annimon.stream.Collectors;
-import com.annimon.stream.Stream;
-
-import org.thoughtcrime.securesms.ApplicationContext;
-import network.loki.messenger.BuildConfig;
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.contacts.ContactAccessor;
-import org.thoughtcrime.securesms.crypto.SessionUtil;
-import org.thoughtcrime.securesms.database.Address;
-import org.thoughtcrime.securesms.database.DatabaseFactory;
-import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
-import org.thoughtcrime.securesms.database.RecipientDatabase;
-import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
-import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
-import org.thoughtcrime.securesms.notifications.MessageNotifier;
-import org.thoughtcrime.securesms.notifications.NotificationChannels;
-import org.thoughtcrime.securesms.permissions.Permissions;
-import org.thoughtcrime.securesms.push.AccountManagerFactory;
-import org.thoughtcrime.securesms.push.IasTrustStore;
-import org.thoughtcrime.securesms.recipients.Recipient;
-import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
-import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
-import org.whispersystems.libsignal.util.guava.Optional;
-import org.whispersystems.signalservice.api.SignalServiceAccountManager;
-import org.whispersystems.signalservice.api.push.ContactTokenDetails;
-import org.whispersystems.signalservice.api.push.TrustStore;
-import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
-import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
-import org.whispersystems.signalservice.internal.contacts.crypto.Quote;
-import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException;
-import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException;
-
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-public class DirectoryHelper {
-
- private static final String TAG = DirectoryHelper.class.getSimpleName();
-
- private static final int CONTACT_DISCOVERY_BATCH_SIZE = 2048;
-
- public static void refreshDirectory(@NonNull Context context, boolean notifyOfNewUsers)
- throws IOException
- {
- if (TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) return;
- if (!Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) return;
-
- List newlyActiveUsers = refreshDirectory(context, AccountManagerFactory.createManager(context));
-
- if (TextSecurePreferences.isMultiDevice(context)) {
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new MultiDeviceContactUpdateJob(context));
- }
-
- if (notifyOfNewUsers) notifyNewUsers(context, newlyActiveUsers);
- }
-
- @SuppressLint("CheckResult")
- private static @NonNull List refreshDirectory(@NonNull Context context, @NonNull SignalServiceAccountManager accountManager)
- throws IOException
- {
- if (TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) {
- return Collections.emptyList();
- }
-
- if (!Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) {
- return Collections.emptyList();
- }
-
- RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
- Stream eligibleRecipientDatabaseContactNumbers = Stream.of(recipientDatabase.getAllAddresses()).filter(Address::isPhone).map(Address::toPhoneString);
- Stream eligibleSystemDatabaseContactNumbers = Stream.of(ContactAccessor.getInstance().getAllContactsWithNumbers(context)).map(Address::serialize);
- Set eligibleContactNumbers = Stream.concat(eligibleRecipientDatabaseContactNumbers, eligibleSystemDatabaseContactNumbers).collect(Collectors.toSet());
-
- Future legacyRequest = getLegacyDirectoryResult(context, accountManager, recipientDatabase, eligibleContactNumbers);
- List>> contactServiceRequest = getContactServiceDirectoryResult(context, accountManager, eligibleContactNumbers);
-
- try {
- DirectoryResult legacyResult = legacyRequest.get();
- Optional> contactServiceResult = executeAndMergeContactDiscoveryRequests(accountManager, contactServiceRequest);
-
- if (!contactServiceResult.isPresent()) {
- Log.i(TAG, "[Batch] New contact discovery service failed, so we're skipping the comparison.");
- return legacyResult.getNewlyActiveAddresses();
- }
-
- if (legacyResult.getNumbers().size() == contactServiceResult.get().size() && legacyResult.getNumbers().containsAll(contactServiceResult.get())) {
- Log.i(TAG, "[Batch] New contact discovery service request matched existing results.");
- accountManager.reportContactDiscoveryServiceMatch();
- } else {
- Log.w(TAG, "[Batch] New contact discovery service request did NOT match existing results.");
- accountManager.reportContactDiscoveryServiceMismatch();
- }
-
- return legacyResult.getNewlyActiveAddresses();
-
- } catch (InterruptedException e) {
- throw new IOException("[Batch] Operation was interrupted.", e);
- } catch (ExecutionException e) {
- if (e.getCause() instanceof IOException) {
- throw (IOException) e.getCause();
- } else {
- Log.e(TAG, "[Batch] Experienced an unexpected exception.", e);
- throw new AssertionError(e);
- }
- }
- }
-
- public static RegisteredState refreshDirectoryFor(@NonNull Context context,
- @NonNull Recipient recipient)
- throws IOException
- {
- RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
- SignalServiceAccountManager accountManager = AccountManagerFactory.createManager(context);
-
- Future legacyRequest = getLegacyRegisteredState(context, accountManager, recipientDatabase, recipient);
- List>> contactServiceRequest = getContactServiceDirectoryResult(context, accountManager, Collections.singleton(recipient.getAddress().serialize()));
-
- try {
- RegisteredState legacyState = legacyRequest.get();
- Optional> contactServiceResult = executeAndMergeContactDiscoveryRequests(accountManager, contactServiceRequest);
-
- if (!contactServiceResult.isPresent()) {
- Log.i(TAG, "[Singular] New contact discovery service failed, so we're skipping the comparison.");
- return legacyState;
- }
-
- RegisteredState contactServiceState = contactServiceResult.get().size() == 1 ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
-
- if (legacyState == contactServiceState) {
- Log.i(TAG, "[Singular] New contact discovery service request matched existing results.");
- accountManager.reportContactDiscoveryServiceMatch();
- } else {
- Log.w(TAG, "[Singular] New contact discovery service request did NOT match existing results.");
- accountManager.reportContactDiscoveryServiceMismatch();
- }
-
- return legacyState;
-
- } catch (InterruptedException e) {
- throw new IOException("[Singular] Operation was interrupted.", e);
- } catch (ExecutionException e) {
- if (e.getCause() instanceof IOException) {
- throw (IOException) e.getCause();
- } else {
- Log.e(TAG, "[Singular] Experienced an unexpected exception.", e);
- throw new AssertionError(e);
- }
- }
- }
-
- private static void updateContactsDatabase(@NonNull Context context, @NonNull List activeAddresses, boolean removeMissing) {
- Optional account = getOrCreateAccount(context);
-
- if (account.isPresent()) {
- try {
- DatabaseFactory.getContactsDatabase(context).removeDeletedRawContacts(account.get().getAccount());
- DatabaseFactory.getContactsDatabase(context).setRegisteredUsers(account.get().getAccount(), activeAddresses, removeMissing);
-
- Cursor cursor = ContactAccessor.getInstance().getAllSystemContacts(context);
- RecipientDatabase.BulkOperationsHandle handle = DatabaseFactory.getRecipientDatabase(context).resetAllSystemContactInfo();
-
- try {
- while (cursor != null && cursor.moveToNext()) {
- String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
-
- if (!TextUtils.isEmpty(number)) {
- Address address = Address.fromExternal(context, number);
- String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
- String contactPhotoUri = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
- String contactLabel = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LABEL));
- Uri contactUri = ContactsContract.Contacts.getLookupUri(cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone._ID)),
- cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY)));
-
- handle.setSystemContactInfo(address, displayName, contactPhotoUri, contactLabel, contactUri.toString());
- }
- }
- } finally {
- handle.finish();
- }
-
- if (NotificationChannels.supported()) {
- try (RecipientDatabase.RecipientReader recipients = DatabaseFactory.getRecipientDatabase(context).getRecipientsWithNotificationChannels()) {
- Recipient recipient;
- while ((recipient = recipients.getNext()) != null) {
- NotificationChannels.updateContactChannelName(context, recipient);
- }
- }
- }
- } catch (RemoteException | OperationApplicationException e) {
- Log.w(TAG, "Failed to update contacts.", e);
- }
- }
- }
-
- private static void notifyNewUsers(@NonNull Context context,
- @NonNull List newUsers)
- {
- if (!TextSecurePreferences.isNewContactsNotificationEnabled(context)) return;
-
- for (Address newUser: newUsers) {
- if (!SessionUtil.hasSession(context, newUser) && !Util.isOwnNumber(context, newUser)) {
- IncomingJoinedMessage message = new IncomingJoinedMessage(newUser);
- Optional insertResult = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message);
-
- if (insertResult.isPresent()) {
- int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
- if (hour >= 9 && hour < 23) {
- MessageNotifier.updateNotification(context, insertResult.get().getThreadId(), true);
- } else {
- MessageNotifier.updateNotification(context, insertResult.get().getThreadId(), false);
- }
- }
- }
- }
- }
-
- private static Optional getOrCreateAccount(Context context) {
- AccountManager accountManager = AccountManager.get(context);
- Account[] accounts = accountManager.getAccountsByType("org.thoughtcrime.securesms");
-
- Optional account;
-
- if (accounts.length == 0) account = createAccount(context);
- else account = Optional.of(new AccountHolder(accounts[0], false));
-
- if (account.isPresent() && !ContentResolver.getSyncAutomatically(account.get().getAccount(), ContactsContract.AUTHORITY)) {
- ContentResolver.setSyncAutomatically(account.get().getAccount(), ContactsContract.AUTHORITY, true);
- }
-
- return account;
- }
-
- private static Optional createAccount(Context context) {
- AccountManager accountManager = AccountManager.get(context);
- Account account = new Account(context.getString(R.string.app_name), "org.thoughtcrime.securesms");
-
- if (accountManager.addAccountExplicitly(account, null, null)) {
- Log.i(TAG, "Created new account...");
- ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1);
- return Optional.of(new AccountHolder(account, true));
- } else {
- Log.w(TAG, "Failed to create account!");
- return Optional.absent();
- }
- }
-
- private static Future getLegacyDirectoryResult(@NonNull Context context,
- @NonNull SignalServiceAccountManager accountManager,
- @NonNull RecipientDatabase recipientDatabase,
- @NonNull Set eligibleContactNumbers)
- {
- return SignalExecutors.UNBOUNDED.submit(() -> {
- List activeTokens = accountManager.getContacts(eligibleContactNumbers);
-
- if (activeTokens != null) {
- List activeAddresses = new LinkedList<>();
- List inactiveAddresses = new LinkedList<>();
-
- Set inactiveContactNumbers = new HashSet<>(eligibleContactNumbers);
-
- for (ContactTokenDetails activeToken : activeTokens) {
- activeAddresses.add(Address.fromSerialized(activeToken.getNumber()));
- inactiveContactNumbers.remove(activeToken.getNumber());
- }
-
- for (String inactiveContactNumber : inactiveContactNumbers) {
- inactiveAddresses.add(Address.fromSerialized(inactiveContactNumber));
- }
-
- Set currentActiveAddresses = new HashSet<>(recipientDatabase.getRegistered());
- Set contactAddresses = new HashSet<>(recipientDatabase.getSystemContacts());
- List newlyActiveAddresses = Stream.of(activeAddresses)
- .filter(address -> !currentActiveAddresses.contains(address))
- .filter(contactAddresses::contains)
- .toList();
-
- recipientDatabase.setRegistered(activeAddresses, inactiveAddresses);
- updateContactsDatabase(context, activeAddresses, true);
-
- Set activeContactNumbers = Stream.of(activeAddresses).map(Address::serialize).collect(Collectors.toSet());
-
- if (TextSecurePreferences.hasSuccessfullyRetrievedDirectory(context)) {
- return new DirectoryResult(activeContactNumbers, newlyActiveAddresses);
- } else {
- TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
- return new DirectoryResult(activeContactNumbers);
- }
- }
- return new DirectoryResult(Collections.emptySet(), Collections.emptyList());
- });
- }
-
- private static Future getLegacyRegisteredState(@NonNull Context context,
- @NonNull SignalServiceAccountManager accountManager,
- @NonNull RecipientDatabase recipientDatabase,
- @NonNull Recipient recipient)
- {
- return SignalExecutors.UNBOUNDED.submit(() -> {
- boolean activeUser = recipient.resolve().getRegistered() == RegisteredState.REGISTERED;
- boolean systemContact = recipient.isSystemContact();
- String number = recipient.getAddress().serialize();
- Optional details = accountManager.getContact(number);
-
- if (details.isPresent()) {
- recipientDatabase.setRegistered(recipient, RegisteredState.REGISTERED);
-
- if (Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) {
- updateContactsDatabase(context, Util.asList(recipient.getAddress()), false);
- }
-
- if (!activeUser && TextSecurePreferences.isMultiDevice(context)) {
- ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context));
- }
-
- if (!activeUser && systemContact && !TextSecurePreferences.getNeedsSqlCipherMigration(context)) {
- notifyNewUsers(context, Collections.singletonList(recipient.getAddress()));
- }
-
- return RegisteredState.REGISTERED;
- } else {
- recipientDatabase.setRegistered(recipient, RegisteredState.NOT_REGISTERED);
- return RegisteredState.NOT_REGISTERED;
- }
- });
- }
-
- private static List>> getContactServiceDirectoryResult(@NonNull Context context,
- @NonNull SignalServiceAccountManager accountManager,
- @NonNull Set eligibleContactNumbers)
- {
- Set sanitizedNumbers = sanitizeNumbers(eligibleContactNumbers);
- List> batches = splitIntoBatches(sanitizedNumbers, CONTACT_DISCOVERY_BATCH_SIZE);
- List>> futures = new ArrayList<>(batches.size());
- KeyStore iasKeyStore = getIasKeyStore(context);
-
- for (Set batch : batches) {
- Future> future = SignalExecutors.UNBOUNDED.submit(() -> {
- return new HashSet<>(accountManager.getRegisteredUsers(iasKeyStore, batch, BuildConfig.MRENCLAVE));
- });
- futures.add(future);
- }
- return futures;
- }
-
- private static Set sanitizeNumbers(@NonNull Set numbers) {
- return Stream.of(numbers).filter(number -> {
- try {
- return number.startsWith("+") && number.length() > 1 && Long.parseLong(number.substring(1)) > 0;
- } catch (NumberFormatException e) {
- return false;
- }
- }).collect(Collectors.toSet());
- }
-
- private static List> splitIntoBatches(@NonNull Set numbers, int batchSize) {
- List numberList = new ArrayList<>(numbers);
- List> batches = new LinkedList<>();
-
- for (int i = 0; i < numberList.size(); i += batchSize) {
- List batch = numberList.subList(i, Math.min(numberList.size(), i + batchSize));
- batches.add(new HashSet<>(batch));
- }
-
- return batches;
- }
-
- private static Optional> executeAndMergeContactDiscoveryRequests(@NonNull SignalServiceAccountManager accountManager, @NonNull List>> futures) {
- Set results = new HashSet<>();
- try {
- for (Future> future : futures) {
- results.addAll(future.get());
- }
- } catch (InterruptedException e) {
- Log.w(TAG, "Contact discovery batch was interrupted.", e);
- accountManager.reportContactDiscoveryServiceUnexpectedError(buildErrorReason(e));
- return Optional.absent();
- } catch (ExecutionException e) {
- if (isAttestationError(e.getCause())) {
- Log.w(TAG, "Failed during attestation.", e);
- accountManager.reportContactDiscoveryServiceAttestationError(buildErrorReason(e.getCause()));
- return Optional.absent();
- } else if (e.getCause() instanceof PushNetworkException) {
- Log.w(TAG, "Failed due to poor network.", e);
- return Optional.absent();
- } else if (e.getCause() instanceof NonSuccessfulResponseCodeException) {
- Log.w(TAG, "Failed due to non successful response code.", e);
- return Optional.absent();
- } else {
- Log.w(TAG, "Failed for an unknown reason.", e);
- accountManager.reportContactDiscoveryServiceUnexpectedError(buildErrorReason(e.getCause()));
- return Optional.absent();
- }
- }
-
- return Optional.of(results);
- }
-
- private static boolean isAttestationError(Throwable e) {
- return e instanceof CertificateException ||
- e instanceof SignatureException ||
- e instanceof UnauthenticatedQuoteException ||
- e instanceof UnauthenticatedResponseException ||
- e instanceof Quote.InvalidQuoteFormatException;
- }
-
- private static KeyStore getIasKeyStore(@NonNull Context context) {
- try {
- TrustStore contactTrustStore = new IasTrustStore(context);
-
- KeyStore keyStore = KeyStore.getInstance("BKS");
- keyStore.load(contactTrustStore.getKeyStoreInputStream(), contactTrustStore.getKeyStorePassword().toCharArray());
-
- return keyStore;
- } catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-
- private static String buildErrorReason(@Nullable Throwable t) {
- if (t == null) {
- return "null";
- }
-
- String rawString = android.util.Log.getStackTraceString(t);
- List lines = Arrays.asList(rawString.split("\\n"));
-
- String errorString;
-
- if (lines.size() > 1) {
- errorString = t.getClass().getName() + "\n" + Util.join(lines.subList(1, lines.size()), "\n");
- } else {
- errorString = t.getClass().getName();
- }
-
- if (errorString.length() > 1000) {
- return errorString.substring(0, 1000);
- } else {
- return errorString;
- }
- }
-
- private static class DirectoryResult {
-
- private final Set numbers;
- private final List newlyActiveAddresses;
-
- DirectoryResult(@NonNull Set numbers) {
- this(numbers, Collections.emptyList());
- }
-
- DirectoryResult(@NonNull Set numbers, @NonNull List newlyActiveAddresses) {
- this.numbers = numbers;
- this.newlyActiveAddresses = newlyActiveAddresses;
- }
-
- Set getNumbers() {
- return numbers;
- }
-
- List getNewlyActiveAddresses() {
- return newlyActiveAddresses;
- }
- }
-
- private static class AccountHolder {
-
- private final boolean fresh;
- private final Account account;
-
- private AccountHolder(Account account, boolean fresh) {
- this.fresh = fresh;
- this.account = account;
- }
-
- @SuppressWarnings("unused")
- public boolean isFresh() {
- return fresh;
- }
-
- public Account getAccount() {
- return account;
- }
-
- }
-
-}