Remove the Canonical Address Database

This was a holdover from Signal's origins as a pure SMS app.
It causes problems, depends on undefined device specific behavior,
and should no longer be necessary now that we have all the
information we need to E164 all numbers.

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2017-07-26 09:59:15 -07:00
parent e452862813
commit 737810475e
113 changed files with 2029 additions and 2130 deletions

View File

@@ -63,7 +63,11 @@ public class AvatarImageView extends ImageView {
ContactsContract.QuickContact.showQuickContact(getContext(), AvatarImageView.this, recipient.getContactUri(), ContactsContract.QuickContact.MODE_LARGE, null);
} else if (recipient != null) {
final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.putExtra(ContactsContract.Intents.Insert.PHONE, recipient.getNumber());
if (recipient.getAddress().isEmail()) {
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, recipient.getAddress().toEmailString());
} else {
intent.putExtra(ContactsContract.Intents.Insert.PHONE, recipient.getAddress().toPhoneString());
}
intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
getContext().startActivity(intent);
}

View File

@@ -18,31 +18,28 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.contacts.RecipientsAdapter;
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipients.RecipientsModifiedListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
/**
* Panel component combining both an editable field with a button for
@@ -74,26 +71,11 @@ public class PushRecipientsPanel extends RelativeLayout implements RecipientsMod
initialize();
}
public void addRecipient(String name, String number) {
if (name != null) recipientsText.append(name + "< " + number + ">, ");
else recipientsText.append(number + ", ");
}
public void addRecipients(Recipients recipients) {
List<Recipient> recipientList = recipients.getRecipientsList();
Iterator<Recipient> iterator = recipientList.iterator();
while (iterator.hasNext()) {
Recipient recipient = iterator.next();
addRecipient(recipient.getName(), recipient.getNumber());
}
}
public Recipients getRecipients() throws RecipientFormattingException {
String rawText = recipientsText.getText().toString();
Recipients recipients = RecipientFactory.getRecipientsFromString(getContext(), rawText, true);
String rawText = recipientsText.getText().toString();
Recipients recipients = getRecipientsFromString(getContext(), rawText, true);
if (recipients.isEmpty())
if (recipients == null || recipients.isEmpty())
throw new RecipientFormattingException("Recipient List Is Empty!");
return recipients;
@@ -151,7 +133,40 @@ public class PushRecipientsPanel extends RelativeLayout implements RecipientsMod
});
}
@Override public void onModified(Recipients recipients) {
private @Nullable Recipients getRecipientsFromString(Context context, @NonNull String rawText, boolean asynchronous) {
StringTokenizer tokenizer = new StringTokenizer(rawText, ",");
List<Address> addresses = new LinkedList<>();
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken().trim();
if (!TextUtils.isEmpty(token)) {
if (hasBracketedNumber(token)) addresses.add(Address.fromExternal(context, parseBracketedNumber(token)));
else addresses.add(Address.fromExternal(context, token));
}
}
if (addresses.size() == 0) return null;
else return RecipientFactory.getRecipientsFor(context, addresses.toArray(new Address[0]), asynchronous);
}
private boolean hasBracketedNumber(String recipient) {
int openBracketIndex = recipient.indexOf('<');
return (openBracketIndex != -1) &&
(recipient.indexOf('>', openBracketIndex) != -1);
}
private String parseBracketedNumber(String recipient) {
int begin = recipient.indexOf('<');
int end = recipient.indexOf('>', begin);
String value = recipient.substring(begin + 1, end);
return value;
}
@Override
public void onModified(Recipients recipients) {
recipientsText.populate(recipients);
}

View File

@@ -1,176 +0,0 @@
/**
* Copyright (C) 2011 Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.RelativeLayout;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.contacts.RecipientsAdapter;
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipients.RecipientsModifiedListener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Panel component combining both an editable field with a button for
* a list-based contact selector.
*
* @author Moxie Marlinspike
*/
public class SingleRecipientPanel extends RelativeLayout implements RecipientsModifiedListener {
private final String TAG = SingleRecipientPanel.class.getSimpleName();
private RecipientsPanelChangedListener panelChangeListener;
private RecipientsEditor recipientsText;
private View panel;
private static final int RECIPIENTS_MAX_LENGTH = 312;
public SingleRecipientPanel(Context context) {
super(context);
initialize();
}
public SingleRecipientPanel(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public SingleRecipientPanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
public void addRecipient(String name, String number) {
Log.i(TAG, "addRecipient for " + name + "/" + number);
if (name != null) recipientsText.append(name + "< " + number + ">, ");
else recipientsText.append(number + ", ");
}
public void addRecipients(Recipients recipients) {
List<Recipient> recipientList = recipients.getRecipientsList();
Iterator<Recipient> iterator = recipientList.iterator();
while (iterator.hasNext()) {
Recipient recipient = iterator.next();
addRecipient(recipient.getName(), recipient.getNumber());
}
}
public void addContacts(List<ContactAccessor.ContactData> contacts) {
for (ContactAccessor.ContactData contact : contacts) {
for (ContactAccessor.NumberData number : contact.numbers) {
addRecipient(contact.name, number.number);
}
}
}
public Recipients getRecipients() throws RecipientFormattingException {
String rawText = recipientsText.getText().toString();
Recipients recipients = RecipientFactory.getRecipientsFromString(getContext(), rawText, true);
if (recipients.isEmpty())
throw new RecipientFormattingException("Recipient List Is Empty!");
return recipients;
}
public void disable() {
clear();
panel.setVisibility(View.GONE);
}
public void clear() {
recipientsText.setText("");
}
public void setPanelChangeListener(RecipientsPanelChangedListener panelChangeListener) {
this.panelChangeListener = panelChangeListener;
}
private void initialize() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.single_recipient_panel, this, true);
panel = findViewById(R.id.recipients_panel);
initRecipientsEditor();
}
private void initRecipientsEditor() {
Recipients recipients;
recipientsText = (RecipientsEditor)findViewById(R.id.recipients_text);
try {
recipients = getRecipients();
} catch (RecipientFormattingException e) {
recipients = RecipientFactory.getRecipientsFor(getContext(), new LinkedList<Recipient>(), true);
}
recipients.addListener(this);
recipientsText.setAdapter(new RecipientsAdapter(this.getContext()));
recipientsText.populate(recipients);
recipientsText.setOnFocusChangeListener(new FocusChangedListener());
recipientsText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (panelChangeListener != null) {
try {
panelChangeListener.onRecipientsPanelUpdate(getRecipients());
} catch (RecipientFormattingException rfe) {
panelChangeListener.onRecipientsPanelUpdate(null);
}
}
recipientsText.setText("");
}
});
}
@Override public void onModified(Recipients recipients) {
recipientsText.populate(recipients);
}
private class FocusChangedListener implements OnFocusChangeListener {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && (panelChangeListener != null)) {
try {
panelChangeListener.onRecipientsPanelUpdate(getRecipients());
} catch (RecipientFormattingException rfe) {
panelChangeListener.onRecipientsPanelUpdate(null);
}
}
}
}
public interface RecipientsPanelChangedListener {
public void onRecipientsPanelUpdate(Recipients recipients);
}
}

View File

@@ -46,7 +46,7 @@ public class UntrustedSendDialog extends AlertDialog.Builder implements DialogIn
protected Void doInBackground(Void... params) {
synchronized (SESSION_LOCK) {
for (IdentityRecord identityRecord : untrustedRecords) {
identityDatabase.setApproval(identityRecord.getRecipientId(), true);
identityDatabase.setApproval(identityRecord.getAddress(), true);
}
}

View File

@@ -45,7 +45,7 @@ public class UnverifiedSendDialog extends AlertDialog.Builder implements DialogI
protected Void doInBackground(Void... params) {
synchronized (SESSION_LOCK) {
for (IdentityRecord identityRecord : untrustedRecords) {
identityDatabase.setVerified(identityRecord.getRecipientId(),
identityDatabase.setVerified(identityRecord.getAddress(),
identityRecord.getIdentityKey(),
IdentityDatabase.VerifiedStatus.DEFAULT);
}

View File

@@ -120,7 +120,7 @@ public class WebRtcCallScreen extends FrameLayout implements Recipient.Recipient
String introduction = String.format(getContext().getString(R.string.WebRtcCallScreen_new_safety_numbers), name, name);
SpannableString spannableString = new SpannableString(introduction + " " + getContext().getString(R.string.WebRtcCallScreen_you_may_wish_to_verify_this_contact));
spannableString.setSpan(new VerifySpan(getContext(), personInfo.getRecipientId(), untrustedIdentity),
spannableString.setSpan(new VerifySpan(getContext(), personInfo.getAddress(), untrustedIdentity),
introduction.length()+1, spannableString.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -302,7 +302,7 @@ public class WebRtcCallScreen extends FrameLayout implements Recipient.Recipient
}.execute();
this.name.setText(recipient.getName());
this.phoneNumber.setText(recipient.getNumber());
this.phoneNumber.setText(recipient.getAddress().serialize());
}
private void setCard(Recipient recipient, String status) {