Switch MMS groups to use the group database infrastructure

Eliminate the concept of 'Recipients' (plural). There is now just
a 'Recipient', which contains an Address that is either an individual
or a group ID.

MMS groups now exist as part of the group database, just like push
groups.

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2017-08-01 08:56:00 -07:00
parent 81682e0302
commit 375207f073
106 changed files with 1587 additions and 2192 deletions

View File

@@ -41,8 +41,9 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.preferences.AdvancedRingtonePreference;
import org.thoughtcrime.securesms.preferences.ColorPreference;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
@@ -53,11 +54,11 @@ import org.whispersystems.libsignal.util.guava.Optional;
import java.util.concurrent.ExecutionException;
public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActivity implements Recipients.RecipientsModifiedListener
public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActivity implements RecipientModifiedListener
{
private static final String TAG = RecipientPreferenceActivity.class.getSimpleName();
public static final String ADDRESSES_EXTRA = "recipient_addresses";
public static final String ADDRESS_EXTRA = "recipient_address";
public static final String CAN_HAVE_SAFETY_NUMBER_EXTRA = "can_have_safety_number";
private static final String PREFERENCE_MUTED = "pref_key_recipient_mute";
@@ -86,16 +87,16 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
public void onCreate(Bundle instanceState, @NonNull MasterSecret masterSecret) {
setContentView(R.layout.recipient_preference_activity);
Address[] addresses = Address.fromParcelable(getIntent().getParcelableArrayExtra(ADDRESSES_EXTRA));
Recipients recipients = RecipientFactory.getRecipientsFor(this, addresses, true);
Address address = getIntent().getParcelableExtra(ADDRESS_EXTRA);
Recipient recipient = RecipientFactory.getRecipientFor(this, address, true);
initializeToolbar();
initializeReceivers();
setHeader(recipients);
recipients.addListener(this);
setHeader(recipient);
recipient.addListener(this);
Bundle bundle = new Bundle();
bundle.putParcelableArray(ADDRESSES_EXTRA, addresses);
bundle.putParcelable(ADDRESS_EXTRA, address);
initFragment(R.id.preference_fragment, new RecipientPreferenceFragment(), masterSecret, null, bundle);
}
@@ -149,9 +150,9 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
this.staleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Recipients recipients = RecipientFactory.getRecipientsFor(context, Address.fromParcelable(getIntent().getParcelableArrayExtra(ADDRESSES_EXTRA)), true);
recipients.addListener(RecipientPreferenceActivity.this);
onModified(recipients);
Recipient recipient = RecipientFactory.getRecipientFor(context, (Address)getIntent().getParcelableExtra(ADDRESS_EXTRA), true);
recipient.addListener(RecipientPreferenceActivity.this);
onModified(recipient);
}
};
@@ -162,37 +163,37 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
registerReceiver(staleReceiver, staleFilter);
}
private void setHeader(Recipients recipients) {
this.avatar.setAvatar(recipients, true);
this.title.setText(recipients.toShortString());
this.toolbar.setBackgroundColor(recipients.getColor().toActionBarColor(this));
private void setHeader(Recipient recipient) {
this.avatar.setAvatar(recipient, true);
this.title.setText(recipient.toShortString());
this.toolbar.setBackgroundColor(recipient.getColor().toActionBarColor(this));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(recipients.getColor().toStatusBarColor(this));
getWindow().setStatusBarColor(recipient.getColor().toStatusBarColor(this));
}
if (recipients.isBlocked()) this.blockedIndicator.setVisibility(View.VISIBLE);
else this.blockedIndicator.setVisibility(View.GONE);
if (recipient.isBlocked()) this.blockedIndicator.setVisibility(View.VISIBLE);
else this.blockedIndicator.setVisibility(View.GONE);
}
@Override
public void onModified(final Recipients recipients) {
public void onModified(final Recipient recipient) {
title.post(new Runnable() {
@Override
public void run() {
setHeader(recipients);
setHeader(recipient);
}
});
}
public static class RecipientPreferenceFragment
extends PreferenceFragment
implements Recipients.RecipientsModifiedListener
implements RecipientModifiedListener
{
private final Handler handler = new Handler();
private Recipients recipients;
private Recipient recipient;
private BroadcastReceiver staleReceiver;
private MasterSecret masterSecret;
private boolean canHaveSafetyNumber;
@@ -223,29 +224,29 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
@Override
public void onResume() {
super.onResume();
setSummaries(recipients);
setSummaries(recipient);
}
@Override
public void onDestroy() {
super.onDestroy();
this.recipients.removeListener(this);
this.recipient.removeListener(this);
getActivity().unregisterReceiver(staleReceiver);
}
private void initializeRecipients() {
this.recipients = RecipientFactory.getRecipientsFor(getActivity(),
Address.fromParcelable(getArguments().getParcelableArray(ADDRESSES_EXTRA)),
true);
this.recipient = RecipientFactory.getRecipientFor(getActivity(),
(Address)getArguments().getParcelable(ADDRESS_EXTRA),
true);
this.recipients.addListener(this);
this.recipient.addListener(this);
this.staleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
recipients.removeListener(RecipientPreferenceFragment.this);
recipients = RecipientFactory.getRecipientsFor(getActivity(), Address.fromParcelable(getArguments().getParcelableArray(ADDRESSES_EXTRA)), true);
onModified(recipients);
recipient.removeListener(RecipientPreferenceFragment.this);
recipient = RecipientFactory.getRecipientFor(getActivity(), (Address)getArguments().getParcelable(ADDRESS_EXTRA), true);
onModified(recipient);
}
};
@@ -256,7 +257,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
getActivity().registerReceiver(staleReceiver, intentFilter);
}
private void setSummaries(Recipients recipients) {
private void setSummaries(Recipient recipient) {
CheckBoxPreference mutePreference = (CheckBoxPreference) this.findPreference(PREFERENCE_MUTED);
AdvancedRingtonePreference ringtonePreference = (AdvancedRingtonePreference) this.findPreference(PREFERENCE_TONE);
ListPreference vibratePreference = (ListPreference) this.findPreference(PREFERENCE_VIBRATE);
@@ -264,9 +265,9 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
Preference blockPreference = this.findPreference(PREFERENCE_BLOCK);
final Preference identityPreference = this.findPreference(PREFERENCE_IDENTITY);
mutePreference.setChecked(recipients.isMuted());
mutePreference.setChecked(recipient.isMuted());
final Uri toneUri = recipients.getRingtone();
final Uri toneUri = recipient.getRingtone();
if (toneUri == null) {
ringtonePreference.setSummary(R.string.preferences__default);
@@ -283,10 +284,10 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
}
}
if (recipients.getVibrate() == VibrateState.DEFAULT) {
if (recipient.getVibrate() == VibrateState.DEFAULT) {
vibratePreference.setSummary(R.string.preferences__default);
vibratePreference.setValueIndex(0);
} else if (recipients.getVibrate() == VibrateState.ENABLED) {
} else if (recipient.getVibrate() == VibrateState.ENABLED) {
vibratePreference.setSummary(R.string.RecipientPreferenceActivity_enabled);
vibratePreference.setValueIndex(1);
} else {
@@ -294,18 +295,18 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
vibratePreference.setValueIndex(2);
}
if (!recipients.isSingleRecipient() || recipients.isGroupRecipient()) {
if (recipient.isGroupRecipient()) {
if (colorPreference != null) getPreferenceScreen().removePreference(colorPreference);
if (blockPreference != null) getPreferenceScreen().removePreference(blockPreference);
if (identityPreference != null) getPreferenceScreen().removePreference(identityPreference);
} else {
colorPreference.setChoices(MaterialColors.CONVERSATION_PALETTE.asConversationColorArray(getActivity()));
colorPreference.setValue(recipients.getColor().toActionBarColor(getActivity()));
colorPreference.setValue(recipient.getColor().toActionBarColor(getActivity()));
if (recipients.isBlocked()) blockPreference.setTitle(R.string.RecipientPreferenceActivity_unblock);
if (recipient.isBlocked()) blockPreference.setTitle(R.string.RecipientPreferenceActivity_unblock);
else blockPreference.setTitle(R.string.RecipientPreferenceActivity_block);
IdentityUtil.getRemoteIdentityKey(getActivity(), recipients.getPrimaryRecipient()).addListener(new ListenableFuture.Listener<Optional<IdentityRecord>>() {
IdentityUtil.getRemoteIdentityKey(getActivity(), recipient).addListener(new ListenableFuture.Listener<Optional<IdentityRecord>>() {
@Override
public void onSuccess(Optional<IdentityRecord> result) {
if (result.isPresent()) {
@@ -328,11 +329,11 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
}
@Override
public void onModified(final Recipients recipients) {
public void onModified(final Recipient recipient) {
handler.post(new Runnable() {
@Override
public void run() {
setSummaries(recipients);
setSummaries(recipient);
}
});
}
@@ -350,13 +351,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
uri = Uri.parse(value);
}
recipients.setRingtone(uri);
recipient.setRingtone(uri);
new AsyncTask<Uri, Void, Void>() {
@Override
protected Void doInBackground(Uri... params) {
DatabaseFactory.getRecipientPreferenceDatabase(getActivity())
.setRingtone(recipients, params[0]);
.setRingtone(recipient, params[0]);
return null;
}
}.execute(uri);
@@ -371,13 +372,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
int value = Integer.parseInt((String) newValue);
final VibrateState vibrateState = VibrateState.fromId(value);
recipients.setVibrate(vibrateState);
recipient.setVibrate(vibrateState);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getRecipientPreferenceDatabase(getActivity())
.setVibrate(recipients, vibrateState);
.setVibrate(recipient, vibrateState);
return null;
}
}.execute();
@@ -392,26 +393,26 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
public boolean onPreferenceChange(Preference preference, Object newValue) {
final int value = (Integer) newValue;
final MaterialColor selectedColor = MaterialColors.CONVERSATION_PALETTE.getByColor(getActivity(), value);
final MaterialColor currentColor = recipients.getColor();
final MaterialColor currentColor = recipient.getColor();
if (selectedColor == null) return true;
if (preference.isEnabled() && !currentColor.equals(selectedColor)) {
recipients.setColor(selectedColor);
recipient.setColor(selectedColor);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Context context = getActivity();
DatabaseFactory.getRecipientPreferenceDatabase(context)
.setColor(recipients, selectedColor);
.setColor(recipient, selectedColor);
if (DirectoryHelper.getUserCapabilities(context, recipients)
if (DirectoryHelper.getUserCapabilities(context, recipient)
.getTextCapability() == DirectoryHelper.UserCapabilities.Capability.SUPPORTED)
{
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MultiDeviceContactUpdateJob(context, recipients.getPrimaryRecipient().getAddress()));
.add(new MultiDeviceContactUpdateJob(context, recipient.getAddress()));
}
return null;
}
@@ -424,8 +425,8 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
private class MuteClickedListener implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(Preference preference) {
if (recipients.isMuted()) handleUnmute();
else handleMute();
if (recipient.isMuted()) handleUnmute();
else handleMute();
return true;
}
@@ -434,25 +435,25 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
MuteDialog.show(getActivity(), new MuteDialog.MuteSelectionListener() {
@Override
public void onMuted(long until) {
setMuted(recipients, until);
setMuted(recipient, until);
}
});
setSummaries(recipients);
setSummaries(recipient);
}
private void handleUnmute() {
setMuted(recipients, 0);
setMuted(recipient, 0);
}
private void setMuted(final Recipients recipients, final long until) {
recipients.setMuted(until);
private void setMuted(final Recipient recipient, final long until) {
recipient.setMuted(until);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getRecipientPreferenceDatabase(getActivity())
.setMuted(recipients, until);
.setMuted(recipient, until);
return null;
}
}.execute();
@@ -471,7 +472,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
@Override
public boolean onPreferenceClick(Preference preference) {
Intent verifyIdentityIntent = new Intent(getActivity(), VerifyIdentityActivity.class);
verifyIdentityIntent.putExtra(VerifyIdentityActivity.ADDRESS_EXTRA, recipients.getPrimaryRecipient().getAddress());
verifyIdentityIntent.putExtra(VerifyIdentityActivity.ADDRESS_EXTRA, recipient.getAddress());
verifyIdentityIntent.putExtra(VerifyIdentityActivity.IDENTITY_EXTRA, new IdentityKeyParcelable(identityKey.getIdentityKey()));
verifyIdentityIntent.putExtra(VerifyIdentityActivity.VERIFIED_EXTRA, identityKey.getVerifiedStatus() == IdentityDatabase.VerifiedStatus.VERIFIED);
startActivity(verifyIdentityIntent);
@@ -483,8 +484,8 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
private class BlockClickedListener implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(Preference preference) {
if (recipients.isBlocked()) handleUnblock();
else handleBlock();
if (recipient.isBlocked()) handleUnblock();
else handleBlock();
return true;
}
@@ -498,7 +499,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
.setPositiveButton(R.string.RecipientPreferenceActivity_block, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
setBlocked(recipients, true);
setBlocked(recipient, true);
}
}).show();
}
@@ -512,13 +513,13 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
setBlocked(recipients, false);
setBlocked(recipient, false);
}
}).show();
}
private void setBlocked(final Recipients recipients, final boolean blocked) {
recipients.setBlocked(blocked);
private void setBlocked(final Recipient recipient, final boolean blocked) {
recipient.setBlocked(blocked);
new AsyncTask<Void, Void, Void>() {
@Override
@@ -526,7 +527,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
Context context = getActivity();
DatabaseFactory.getRecipientPreferenceDatabase(context)
.setBlocked(recipients, blocked);
.setBlocked(recipient, blocked);
ApplicationContext.getInstance(context)
.getJobManager()