mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:28:26 +00:00
Support for syncing and checking secure voice support.
// FREEBIE
This commit is contained in:
parent
cf14b0478d
commit
7377e6c7da
12
build.gradle
12
build.gradle
@ -78,7 +78,7 @@ dependencies {
|
||||
compile 'org.whispersystems:jobmanager:0.11.0'
|
||||
compile 'org.whispersystems:libpastelog:1.0.6'
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile 'org.whispersystems:textsecure-android:1.7.2'
|
||||
compile 'org.whispersystems:textsecure-android:1.8.0'
|
||||
compile 'com.h6ah4i.android.compat:mulsellistprefcompat:1.0.0'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
@ -129,23 +129,23 @@ dependencyVerification {
|
||||
'org.whispersystems:jobmanager:ea9cb943c4892fb90c1eea1be30efeb85cefca213d52c788419553b58d0ed70d',
|
||||
'org.whispersystems:libpastelog:550d33c565380d90f4c671e7b8ed5f3a6da55a9fda468373177106b2eb5220b2',
|
||||
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
|
||||
'org.whispersystems:textsecure-android:0bc637dcfd1ef25888f07f05120fe0360c182e012a5151fcf6d96464ba850e8f',
|
||||
'org.whispersystems:textsecure-android:226214454003de852d856509ce9ca90a0865f7ad85a45f7a769916c6362fd4d7',
|
||||
'com.h6ah4i.android.compat:mulsellistprefcompat:47167c5cb796de1a854788e9ff318358e36c8fb88123baaa6e38fb78511dfabe',
|
||||
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||
'org.whispersystems:textsecure-java:97ef37e2ad88c6d7a896680bbab051ea894dc45409bc9b4683f75b55718fbeb5',
|
||||
'org.whispersystems:axolotl-android:40d3db5004a84749a73f68d2f0d01b2ae35a73c54df96d8c6c6723b96efb6fc0',
|
||||
'org.whispersystems:textsecure-java:137ef598a3bb77bf53930f76e3881190d12a91a597c2a17bf48835611fcf2f66',
|
||||
'org.whispersystems:axolotl-java:6daee739b89d8d7101de6d98f77132fee48495c6ea647d880e77def842f999ea',
|
||||
'org.whispersystems:curve25519-android:3c29a4131a69b0d16baaa3d707678deb39602c3a3ffd75805ce7f9db252e5d0d',
|
||||
'com.googlecode.libphonenumber:libphonenumber:eba17eae81dd622ea89a00a3a8c025b2f25d342e0d9644c5b62e16f15687c3ab',
|
||||
'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74',
|
||||
'com.squareup.okhttp:okhttp:89b7f63e2e5b6c410266abc14f50fe52ea8d2d8a57260829e499b1cd9f0e61af',
|
||||
'com.fasterxml.jackson.core:jackson-databind:835097bcdd11f5bc8a08378c70d4c8054dfa4b911691cc2752063c75534d198d',
|
||||
'org.whispersystems:curve25519-java:9ccef8f5aba05d9942336f023c589d6278b4f9135bdc34a7bade1f4e7ad65fa3',
|
||||
'org.whispersystems:axolotl-java:6daee739b89d8d7101de6d98f77132fee48495c6ea647d880e77def842f999ea',
|
||||
'org.whispersystems:curve25519-android:3c29a4131a69b0d16baaa3d707678deb39602c3a3ffd75805ce7f9db252e5d0d',
|
||||
'com.squareup.okio:okio:5e1098bd3fdee4c3347f5ab815b40ba851e4ab1b348c5e49a5b0362f0ce6e978',
|
||||
'com.fasterxml.jackson.core:jackson-annotations:0ca408c24202a7626ec8b861e99d85eca5e38b73311dd6dd12e3e9deecc3fe94',
|
||||
'com.fasterxml.jackson.core:jackson-core:cbf4604784b4de226262845447a1ad3bb38a6728cebe86562e2c5afada8be2c0',
|
||||
'org.whispersystems:curve25519-java:9ccef8f5aba05d9942336f023c589d6278b4f9135bdc34a7bade1f4e7ad65fa3',
|
||||
'com.android.support:support-v4:1e2e4d35ac7fd30db5ce3bc177b92e4d5af86acef2ef93e9221599d733346f56',
|
||||
'com.android.support:support-annotations:7bc07519aa613b186001160403bcfd68260fa82c61cc7e83adeedc9b862b94ae',
|
||||
]
|
||||
|
@ -13,5 +13,5 @@ public interface BindableConversationItem extends Unbindable {
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
boolean groupThread, boolean pushDestination);
|
||||
boolean groupThread);
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.WindowCompat;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
@ -64,19 +63,18 @@ import org.thoughtcrime.securesms.TransportOptions.OnTransportChangedListener;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.components.AnimatingToggle;
|
||||
import org.thoughtcrime.securesms.components.ComposeText;
|
||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||
import org.thoughtcrime.securesms.components.SendButton;
|
||||
import org.thoughtcrime.securesms.components.camera.HidingImageButton;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.AttachmentDrawerListener;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.DrawerState;
|
||||
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
||||
import org.thoughtcrime.securesms.components.camera.HidingImageButton;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.AttachmentDrawerListener;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.crypto.SecurityEvent;
|
||||
@ -86,13 +84,13 @@ import org.thoughtcrime.securesms.database.DraftDatabase.Draft;
|
||||
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
||||
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.MediaTooLargeException;
|
||||
import org.thoughtcrime.securesms.mms.MmsMediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
|
||||
@ -110,10 +108,10 @@ import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper.RegistrationState;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
@ -123,6 +121,7 @@ import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||
import org.whispersystems.libaxolotl.InvalidMessageException;
|
||||
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -606,28 +605,53 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDial(Recipient recipient) {
|
||||
Intent intent = new Intent(this, RedPhoneService.class);
|
||||
intent.setAction(RedPhoneService.ACTION_OUTGOING_CALL);
|
||||
intent.putExtra(RedPhoneService.EXTRA_REMOTE_NUMBER, recipient.getNumber());
|
||||
startService(intent);
|
||||
private void handleDial(final Recipient recipient) {
|
||||
if (recipient == null) return;
|
||||
|
||||
Intent activityIntent = new Intent(this, RedPhone.class);
|
||||
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(activityIntent);
|
||||
new AsyncTask<Recipient, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Recipient... params) {
|
||||
try {
|
||||
Context context = ConversationActivity.this;
|
||||
Recipient recipient = params[0];
|
||||
String e164number = Util.canonicalizeNumber(context, recipient.getNumber());
|
||||
|
||||
// try {
|
||||
// if (recipient == null) return;
|
||||
//
|
||||
// Intent dialIntent = new Intent(Intent.ACTION_DIAL,
|
||||
// Uri.parse("tel:" + recipient.getNumber()));
|
||||
// startActivity(dialIntent);
|
||||
// } catch (ActivityNotFoundException anfe) {
|
||||
// Log.w(TAG, anfe);
|
||||
// Dialogs.showAlertDialog(this,
|
||||
// getString(R.string.ConversationActivity_calls_not_supported),
|
||||
// getString(R.string.ConversationActivity_this_device_does_not_appear_to_support_dial_actions));
|
||||
// }
|
||||
return TextSecureDirectory.getInstance(context).isSecureVoiceSupported(e164number);
|
||||
} catch (InvalidNumberException | NotInDirectoryException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean secureVoiceSupported) {
|
||||
handleDial(recipient, secureVoiceSupported);
|
||||
}
|
||||
}.execute(recipient);
|
||||
}
|
||||
|
||||
private void handleDial(Recipient recipient, boolean secureVoice) {
|
||||
if (secureVoice) {
|
||||
Intent intent = new Intent(this, RedPhoneService.class);
|
||||
intent.setAction(RedPhoneService.ACTION_OUTGOING_CALL);
|
||||
intent.putExtra(RedPhoneService.EXTRA_REMOTE_NUMBER, recipient.getNumber());
|
||||
startService(intent);
|
||||
|
||||
Intent activityIntent = new Intent(this, RedPhone.class);
|
||||
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(activityIntent);
|
||||
} else {
|
||||
try {
|
||||
Intent dialIntent = new Intent(Intent.ACTION_DIAL,
|
||||
Uri.parse("tel:" + recipient.getNumber()));
|
||||
startActivity(dialIntent);
|
||||
} catch (ActivityNotFoundException anfe) {
|
||||
Log.w(TAG, anfe);
|
||||
Dialogs.showAlertDialog(this,
|
||||
getString(R.string.ConversationActivity_calls_not_supported),
|
||||
getString(R.string.ConversationActivity_this_device_does_not_appear_to_support_dial_actions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDisplayGroupRecipients() {
|
||||
@ -664,7 +688,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void handleAddAttachment() {
|
||||
if (this.isMmsEnabled || DirectoryHelper.isPushDestination(this, getRecipients())) {
|
||||
if (this.isMmsEnabled || isEncryptedConversation) {
|
||||
new AlertDialogWrapper.Builder(this).setAdapter(attachmentAdapter, new AttachmentTypeListener())
|
||||
.show();
|
||||
} else {
|
||||
@ -740,8 +764,37 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void initializeSecurity() {
|
||||
boolean isMediaMessage = !recipients.isSingleRecipient() || attachmentManager.isAttachmentPresent();
|
||||
this.isEncryptedConversation = DirectoryHelper.isPushDestination(this, getRecipients());
|
||||
initializeSecurity(false);
|
||||
|
||||
new AsyncTask<Recipients, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Recipients... params) {
|
||||
try {
|
||||
Context context = ConversationActivity.this;
|
||||
Recipients recipients = params[0];
|
||||
RegistrationState registrationState = DirectoryHelper.isTextSecureEnabledRecipient(context, recipients);
|
||||
|
||||
if (registrationState == RegistrationState.NOT_REGISTERED) return false;
|
||||
else if (registrationState == RegistrationState.REGISTERED) return true;
|
||||
else return DirectoryHelper.refreshDirectoryFor(context, recipients) == RegistrationState.REGISTERED;
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (result != isEncryptedConversation) {
|
||||
initializeSecurity(result);
|
||||
}
|
||||
}
|
||||
}.execute(recipients);
|
||||
}
|
||||
|
||||
private void initializeSecurity(boolean encryptedConversation) {
|
||||
boolean isMediaMessage = !recipients.isSingleRecipient() || attachmentManager.isAttachmentPresent();
|
||||
this.isEncryptedConversation = encryptedConversation;
|
||||
|
||||
sendButton.resetAvailableTransports(isMediaMessage);
|
||||
|
||||
|
@ -72,7 +72,6 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
private final MasterSecret masterSecret;
|
||||
private final Locale locale;
|
||||
private final boolean groupThread;
|
||||
private final boolean pushDestination;
|
||||
private final MmsSmsDatabase db;
|
||||
private final LayoutInflater inflater;
|
||||
|
||||
@ -97,15 +96,13 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
@NonNull Locale locale,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
@Nullable Cursor cursor,
|
||||
boolean groupThread,
|
||||
boolean pushDestination)
|
||||
boolean groupThread)
|
||||
{
|
||||
super(context, cursor);
|
||||
this.masterSecret = masterSecret;
|
||||
this.locale = locale;
|
||||
this.clickListener = clickListener;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.db = DatabaseFactory.getMmsSmsDatabase(context);
|
||||
}
|
||||
@ -121,7 +118,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
||||
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
||||
|
||||
viewHolder.getView().bind(masterSecret, messageRecord, locale, batchSelected, groupThread, pushDestination);
|
||||
viewHolder.getView().bind(masterSecret, messageRecord, locale, batchSelected, groupThread);
|
||||
}
|
||||
|
||||
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
|
@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.ProgressDialogAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
@ -136,8 +135,7 @@ public class ConversationFragment extends Fragment
|
||||
private void initializeListAdapter() {
|
||||
if (this.recipients != null && this.threadId != -1) {
|
||||
list.setAdapter(new ConversationAdapter(getActivity(), masterSecret, locale, selectionClickListener, null,
|
||||
(!this.recipients.isSingleRecipient()) || this.recipients.isGroupRecipient(),
|
||||
DirectoryHelper.isPushDestination(getActivity(), this.recipients)));
|
||||
(!this.recipients.isSingleRecipient()) || this.recipients.isGroupRecipient()));
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ public class ConversationItem extends LinearLayout
|
||||
private MasterSecret masterSecret;
|
||||
private Locale locale;
|
||||
private boolean groupThread;
|
||||
private boolean pushDestination;
|
||||
private Recipient recipient;
|
||||
|
||||
private View bodyBubble;
|
||||
@ -171,14 +170,13 @@ public class ConversationItem extends LinearLayout
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
boolean groupThread, boolean pushDestination)
|
||||
boolean groupThread)
|
||||
{
|
||||
this.masterSecret = masterSecret;
|
||||
this.messageRecord = messageRecord;
|
||||
this.locale = locale;
|
||||
this.batchSelected = batchSelected;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
this.recipient = messageRecord.getIndividualRecipient();
|
||||
|
||||
this.recipient.addListener(this);
|
||||
@ -503,7 +501,7 @@ public class ConversationItem extends LinearLayout
|
||||
intent.putExtra(MessageDetailsActivity.MASTER_SECRET_EXTRA, masterSecret);
|
||||
intent.putExtra(MessageDetailsActivity.MESSAGE_ID_EXTRA, messageRecord.getId());
|
||||
intent.putExtra(MessageDetailsActivity.TYPE_EXTRA, messageRecord.isMms() ? MmsSmsDatabase.MMS_TRANSPORT : MmsSmsDatabase.SMS_TRANSPORT);
|
||||
intent.putExtra(MessageDetailsActivity.IS_PUSH_GROUP_EXTRA, groupThread && pushDestination);
|
||||
intent.putExtra(MessageDetailsActivity.IS_PUSH_GROUP_EXTRA, groupThread && messageRecord.isPush());
|
||||
context.startActivity(intent);
|
||||
} else if (!messageRecord.isOutgoing() && messageRecord.isIdentityMismatchFailure()) {
|
||||
handleApproveIdentity();
|
||||
|
@ -56,7 +56,7 @@ public class ConversationUpdateItem extends LinearLayout
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
boolean groupThread, boolean pushDestination)
|
||||
boolean groupThread)
|
||||
{
|
||||
bind(messageRecord, locale);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
@ -174,8 +173,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
||||
toFrom.setText(toFromRes);
|
||||
conversationItem.bind(masterSecret, messageRecord, dynamicLanguage.getCurrentLocale(),
|
||||
new HashSet<MessageRecord>(),
|
||||
recipients != messageRecord.getRecipients(),
|
||||
DirectoryHelper.isPushDestination(this, recipients));
|
||||
recipients != messageRecord.getRecipients());
|
||||
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, masterSecret, messageRecord,
|
||||
recipients, isPushGroup));
|
||||
}
|
||||
|
@ -520,9 +520,9 @@ public class RegistrationProgressActivity extends BaseActionBarActivity {
|
||||
protected Integer doInBackground(Void... params) {
|
||||
try {
|
||||
TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context, e164number, password);
|
||||
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
|
||||
accountManager.verifyAccountWithCode(code, signalingKey, registrationId);
|
||||
accountManager.verifyAccountWithCode(code, signalingKey, registrationId, true);
|
||||
|
||||
return SUCCESS;
|
||||
} catch (ExpectationFailedException e) {
|
||||
|
@ -7,6 +7,7 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.whispersystems.textsecure.api.push.ContactTokenDetails;
|
||||
@ -22,9 +23,10 @@ import java.util.Set;
|
||||
public class TextSecureDirectory {
|
||||
|
||||
private static final int INTRODUCED_CHANGE_FROM_TOKEN_TO_E164_NUMBER = 2;
|
||||
private static final int INTRODUCED_VOICE_COLUMN = 4;
|
||||
|
||||
private static final String DATABASE_NAME = "whisper_directory.db";
|
||||
private static final int DATABASE_VERSION = 3;
|
||||
private static final int DATABASE_VERSION = 4;
|
||||
|
||||
private static final String TABLE_NAME = "directory";
|
||||
private static final String ID = "_id";
|
||||
@ -32,11 +34,14 @@ public class TextSecureDirectory {
|
||||
private static final String REGISTERED = "registered";
|
||||
private static final String RELAY = "relay";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String VOICE = "voice";
|
||||
|
||||
private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY, " +
|
||||
NUMBER + " TEXT UNIQUE, " +
|
||||
REGISTERED + " INTEGER, " +
|
||||
RELAY + " TEXT, " +
|
||||
TIMESTAMP + " INTEGER);";
|
||||
TIMESTAMP + " INTEGER, " +
|
||||
VOICE + " INTEGER);";
|
||||
|
||||
private static final Object instanceLock = new Object();
|
||||
private static volatile TextSecureDirectory instance;
|
||||
@ -86,6 +91,31 @@ public class TextSecureDirectory {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSecureVoiceSupported(String e164number) throws NotInDirectoryException {
|
||||
if (TextUtils.isEmpty(e164number)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = db.query(TABLE_NAME,
|
||||
new String[]{VOICE}, NUMBER + " = ?",
|
||||
new String[] {e164number}, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getInt(0) == 1;
|
||||
} else {
|
||||
throw new NotInDirectoryException();
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getRelay(String e164number) {
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = null;
|
||||
@ -127,6 +157,7 @@ public class TextSecureDirectory {
|
||||
values.put(REGISTERED, 1);
|
||||
values.put(TIMESTAMP, timestamp);
|
||||
values.put(RELAY, token.getRelay());
|
||||
values.put(VOICE, token.isVoice());
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
@ -226,6 +257,10 @@ public class TextSecureDirectory {
|
||||
"supports_sms INTEGER, " +
|
||||
"timestamp INTEGER);");
|
||||
}
|
||||
|
||||
if (oldVersion < INTRODUCED_VOICE_COLUMN) {
|
||||
db.execSQL("ALTER TABLE directory ADD COLUMN voice INTEGER;");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushMediaSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushTextSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
|
||||
import org.thoughtcrime.securesms.push.SecurityEventListener;
|
||||
import org.thoughtcrime.securesms.push.TextSecurePushTrustStore;
|
||||
@ -41,7 +42,8 @@ import dagger.Provides;
|
||||
PushNotificationReceiveJob.class,
|
||||
MultiDeviceContactUpdateJob.class,
|
||||
MultiDeviceGroupUpdateJob.class,
|
||||
DeviceListActivity.DeviceListFragment.class})
|
||||
DeviceListActivity.DeviceListFragment.class,
|
||||
RefreshAttributesJob.class})
|
||||
public class TextSecureCommunicationModule {
|
||||
|
||||
private final Context context;
|
||||
|
@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.jobqueue.JobParameters;
|
||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
||||
import org.whispersystems.textsecure.api.push.exceptions.NetworkFailureException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class RefreshAttributesJob extends ContextJob {
|
||||
|
||||
private static final String TAG = RefreshAttributesJob.class.getSimpleName();
|
||||
|
||||
@Inject TextSecureAccountManager accountManager;
|
||||
|
||||
public RefreshAttributesJob(Context context) {
|
||||
super(context, JobParameters.newBuilder()
|
||||
.withPersistence()
|
||||
.withRequirement(new NetworkRequirement(context))
|
||||
.withWakeLock(true)
|
||||
.create());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdded() {}
|
||||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
String signalingKey = TextSecurePreferences.getSignalingKey(context);
|
||||
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
|
||||
accountManager.setAccountAttributes(signalingKey, registrationId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(Exception e) {
|
||||
return e instanceof NetworkFailureException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {
|
||||
Log.w(TAG, "Failed to update account attributes!");
|
||||
}
|
||||
}
|
@ -203,7 +203,7 @@ public class RegistrationService extends Service {
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_VERIFYING, number));
|
||||
String challenge = waitForChallenge();
|
||||
accountManager.verifyAccountWithCode(challenge, signalingKey, registrationId);
|
||||
accountManager.verifyAccountWithCode(challenge, signalingKey, registrationId, true);
|
||||
|
||||
handleCommonRegistration(accountManager, number, password, signalingKey);
|
||||
markAsVerified(number, password, signalingKey);
|
||||
|
@ -8,13 +8,13 @@ import android.content.OperationApplicationException;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
||||
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.push.TextSecureCommunicationFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
@ -28,6 +28,11 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DirectoryHelper {
|
||||
|
||||
public enum RegistrationState {
|
||||
REGISTERED, NOT_REGISTERED, UNKNOWN
|
||||
}
|
||||
|
||||
private static final String TAG = DirectoryHelper.class.getSimpleName();
|
||||
|
||||
public static void refreshDirectory(final Context context) throws IOException {
|
||||
@ -72,38 +77,65 @@ public class DirectoryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPushDestination(Context context, Recipients recipients) {
|
||||
public static RegistrationState refreshDirectoryFor(Context context, Recipients recipients)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
|
||||
TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context);
|
||||
String number = Util.canonicalizeNumber(context, recipients.getPrimaryRecipient().getNumber());
|
||||
|
||||
Optional<ContactTokenDetails> details = accountManager.getContact(number);
|
||||
|
||||
if (details.isPresent()) {
|
||||
directory.setNumber(details.get(), true);
|
||||
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context));
|
||||
return RegistrationState.REGISTERED;
|
||||
} else {
|
||||
ContactTokenDetails absent = new ContactTokenDetails();
|
||||
absent.setNumber(number);
|
||||
directory.setNumber(absent, false);
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
}
|
||||
|
||||
public static RegistrationState isTextSecureEnabledRecipient(Context context, Recipients recipients) {
|
||||
try {
|
||||
if (recipients == null) {
|
||||
return false;
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
return false;
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
|
||||
if (!recipients.isSingleRecipient()) {
|
||||
return false;
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
|
||||
if (recipients.isGroupRecipient()) {
|
||||
return true;
|
||||
return RegistrationState.REGISTERED;
|
||||
}
|
||||
|
||||
final String number = recipients.getPrimaryRecipient().getNumber();
|
||||
|
||||
if (number == null) {
|
||||
return false;
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
}
|
||||
|
||||
final String e164number = Util.canonicalizeNumber(context, number);
|
||||
|
||||
return TextSecureDirectory.getInstance(context).isActiveNumber(e164number);
|
||||
return TextSecureDirectory.getInstance(context).isActiveNumber(e164number) ?
|
||||
RegistrationState.REGISTERED : RegistrationState.NOT_REGISTERED;
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
return RegistrationState.NOT_REGISTERED;
|
||||
} catch (NotInDirectoryException e) {
|
||||
return false;
|
||||
return RegistrationState.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,8 +160,4 @@ public class DirectoryHelper {
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
public static interface DirectoryUpdateFinishedListener {
|
||||
public void onUpdateFinished();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user