Add support for GV1->GV2 forced migration.

fork-5.53.8
Greyson Parrelli 2020-11-12 12:32:10 -05:00 zatwierdzone przez GitHub
rodzic 554aa1ddf0
commit 2dace38d43
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
15 zmienionych plików z 117 dodań i 32 usunięć

Wyświetl plik

@ -199,7 +199,7 @@ public class ContactAccessor {
GroupRecord record;
try {
reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint, true);
reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint, true, false);
while ((record = reader.getNext()) != null) {
numberList.add(record.getId().toString());

Wyświetl plik

@ -61,6 +61,7 @@ public class ContactsCursorLoader extends CursorLoader {
public static final int FLAG_INACTIVE_GROUPS = 1 << 3;
public static final int FLAG_SELF = 1 << 4;
public static final int FLAG_BLOCK = 1 << 5;
public static final int FLAG_HIDE_GROUPS_V1 = 1 << 5;
public static final int FLAG_ALL = FLAG_PUSH | FLAG_SMS | FLAG_ACTIVE_GROUPS | FLAG_INACTIVE_GROUPS | FLAG_SELF;
}
@ -267,7 +268,7 @@ public class ContactsCursorLoader extends CursorLoader {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getContext());
MatrixCursor recentConversations = new MatrixCursor(CONTACT_PROJECTION, RECENT_CONVERSATION_MAX);
try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), groupsOnly)) {
try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), groupsOnly, hideGroupsV1(mode))) {
ThreadDatabase.Reader reader = threadDatabase.readerFor(rawConversations);
ThreadRecord threadRecord;
while ((threadRecord = reader.getNext()) != null) {
@ -306,7 +307,7 @@ public class ContactsCursorLoader extends CursorLoader {
private Cursor getGroupsCursor() {
MatrixCursor groupContacts = new MatrixCursor(CONTACT_PROJECTION);
try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(filter, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS))) {
try (GroupDatabase.Reader reader = DatabaseFactory.getGroupDatabase(getContext()).getGroupsFilteredByTitle(filter, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode))) {
GroupDatabase.GroupRecord groupRecord;
while ((groupRecord = reader.getNext()) != null) {
groupContacts.addRow(new Object[] { groupRecord.getRecipientId().serialize(),
@ -412,6 +413,10 @@ public class ContactsCursorLoader extends CursorLoader {
return mode == DisplayMode.FLAG_ACTIVE_GROUPS;
}
private static boolean hideGroupsV1(int mode) {
return flagSet(mode, DisplayMode.FLAG_HIDE_GROUPS_V1);
}
private static boolean flagSet(int mode, int flag) {
return (mode & flag) > 0;
}

Wyświetl plik

@ -3116,6 +3116,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
messageRequestBottomView.setDeleteOnClickListener(v -> onMessageRequestDeleteClicked(viewModel));
messageRequestBottomView.setBlockOnClickListener(v -> onMessageRequestBlockClicked(viewModel));
messageRequestBottomView.setUnblockOnClickListener(v -> onMessageRequestUnblockClicked(viewModel));
messageRequestBottomView.setGroupV1MigrationContinueListener(v -> GroupsV1MigrationInitiationBottomSheetDialogFragment.showForInitiation(getSupportFragmentManager(), recipient.getId()));
viewModel.getRequestReviewDisplayState().observe(this, this::presentRequestReviewBanner);
viewModel.getMessageData().observe(this, this::presentMessageRequestBottomViewTo);

Wyświetl plik

@ -220,7 +220,7 @@ public final class GroupDatabase extends Database {
return noMetadata && noMembers;
}
public Reader getGroupsFilteredByTitle(String constraint, boolean includeInactive) {
public Reader getGroupsFilteredByTitle(String constraint, boolean includeInactive, boolean excludeV1) {
String query;
String[] queryArgs;
@ -232,6 +232,10 @@ public final class GroupDatabase extends Database {
queryArgs = new String[]{"%" + constraint + "%", "1"};
}
if (excludeV1) {
query += " AND " + EXPECTED_V2_ID + " IS NULL";
}
Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, query, queryArgs, null, null, TITLE + " COLLATE NOCASE ASC");
return new Reader(cursor);

Wyświetl plik

@ -93,7 +93,7 @@ public class RecipientDatabase extends Database {
public static final String PHONE = "phone";
public static final String EMAIL = "email";
static final String GROUP_ID = "group_id";
private static final String GROUP_TYPE = "group_type";
static final String GROUP_TYPE = "group_type";
private static final String BLOCKED = "blocked";
private static final String MESSAGE_RINGTONE = "message_ringtone";
private static final String MESSAGE_VIBRATE = "message_vibrate";

Wyświetl plik

@ -545,11 +545,11 @@ public class ThreadDatabase extends Database {
return cursor;
}
public Cursor getRecentConversationList(int limit, boolean includeInactiveGroups) {
return getRecentConversationList(limit, includeInactiveGroups, false);
public Cursor getRecentConversationList(int limit, boolean includeInactiveGroups, boolean hideV1Groups) {
return getRecentConversationList(limit, includeInactiveGroups, false, hideV1Groups);
}
public Cursor getRecentConversationList(int limit, boolean includeInactiveGroups, boolean groupsOnly) {
public Cursor getRecentConversationList(int limit, boolean includeInactiveGroups, boolean groupsOnly, boolean hideV1Groups) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String query = !includeInactiveGroups ? MESSAGE_COUNT + " != 0 AND (" + GroupDatabase.TABLE_NAME + "." + GroupDatabase.ACTIVE + " IS NULL OR " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.ACTIVE + " = 1)"
: MESSAGE_COUNT + " != 0";
@ -558,6 +558,10 @@ public class ThreadDatabase extends Database {
query += " AND " + RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.GROUP_ID + " NOT NULL";
}
if (hideV1Groups) {
query += " AND " + RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.GROUP_TYPE + " != " + RecipientDatabase.GroupType.SIGNAL_V1.getId();
}
return db.rawQuery(createQuery(query, 0, limit, true), null);
}

Wyświetl plik

@ -175,6 +175,10 @@ public final class PushGroupSendJob extends PushSendJob {
throw new MmsException("Message recipient isn't a group!");
}
if (groupRecipient.isPushV1Group() && FeatureFlags.groupsV1ForcedMigration()) {
throw new MmsException("No GV1 messages can be sent anymore!");
}
try {
log(TAG, String.valueOf(message.getSentTimeMillis()), "Sending message: " + messageId);

Wyświetl plik

@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.ringrtc.Camera;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import java.util.ArrayList;
@ -120,7 +121,7 @@ class CameraContactsRepository {
List<Recipient> recipients = new ArrayList<>();
try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(query, false)) {
try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(query, false, FeatureFlags.groupsV1ForcedMigration())) {
GroupDatabase.GroupRecord groupRecord;
while ((groupRecord = reader.getNext()) != null) {
RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupRecord.getId());

Wyświetl plik

@ -86,6 +86,10 @@ final class MessageRequestRepository {
}
}
if (recipient.isPushV1Group() && FeatureFlags.groupsV1ForcedMigration()) {
return MessageRequestState.REQUIRED;
}
if (!RecipientUtil.isMessageRequestAccepted(context, threadId)) {
if (recipient.isGroup()) {
GroupDatabase.MemberLevel memberLevel = DatabaseFactory.getGroupDatabase(context)

Wyświetl plik

@ -197,6 +197,12 @@ public class MessageRequestViewModel extends ViewModel {
} else {
return new MessageData(recipient, MessageClass.GROUP_V2_ADD);
}
} else if (recipient.isPushV1Group() && FeatureFlags.groupsV1ForcedMigration()) {
if (recipient.getParticipants().size() > FeatureFlags.groupLimits().getHardLimit()) {
return new MessageData(recipient, MessageClass.DEPRECATED_GROUP_V1_TOO_LARGE);
} else {
return new MessageData(recipient, MessageClass.DEPRECATED_GROUP_V1);
}
} else if (isLegacyThread(recipient)) {
if (recipient.isGroup()) {
return new MessageData(recipient, MessageClass.LEGACY_GROUP_V1);
@ -289,6 +295,10 @@ public class MessageRequestViewModel extends ViewModel {
LEGACY_INDIVIDUAL,
/** A V1 group conversation that existed pre-message-requests but doesn't have profile sharing enabled */
LEGACY_GROUP_V1,
/** A V1 group conversation that is no longer allowed, because we've forced GV2 on. */
DEPRECATED_GROUP_V1,
/** A V1 group conversation that is no longer allowed, because we've forced GV2 on, but it's also too large to migrate. Nothing we can do. */
DEPRECATED_GROUP_V1_TOO_LARGE,
GROUP_V1,
GROUP_V2_INVITE,
GROUP_V2_ADD,
@ -324,7 +334,7 @@ public class MessageRequestViewModel extends ViewModel {
private final DisplayState displayState;
private MessageDataDisplayStateHolder(@NonNull MessageData messageData, @NonNull DisplayState displayState) {
this.messageData = messageData;
this.messageData = messageData;
this.displayState = displayState;
}
}

Wyświetl plik

@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.HtmlUtil;
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
@ -24,6 +25,7 @@ public class MessageRequestsBottomView extends ConstraintLayout {
private LearnMoreTextView question;
private Button accept;
private Button gv1Continue;
private View block;
private View delete;
private View bigDelete;
@ -32,6 +34,7 @@ public class MessageRequestsBottomView extends ConstraintLayout {
private Group normalButtons;
private Group blockedButtons;
private Group gv1MigrationButtons;
private Group activeGroup;
public MessageRequestsBottomView(Context context) {
@ -52,15 +55,17 @@ public class MessageRequestsBottomView extends ConstraintLayout {
inflate(getContext(), R.layout.message_request_bottom_bar, this);
question = findViewById(R.id.message_request_question);
accept = findViewById(R.id.message_request_accept);
block = findViewById(R.id.message_request_block);
delete = findViewById(R.id.message_request_delete);
bigDelete = findViewById(R.id.message_request_big_delete);
bigUnblock = findViewById(R.id.message_request_big_unblock);
normalButtons = findViewById(R.id.message_request_normal_buttons);
blockedButtons = findViewById(R.id.message_request_blocked_buttons);
busyIndicator = findViewById(R.id.message_request_busy_indicator);
question = findViewById(R.id.message_request_question);
accept = findViewById(R.id.message_request_accept);
block = findViewById(R.id.message_request_block);
delete = findViewById(R.id.message_request_delete);
bigDelete = findViewById(R.id.message_request_big_delete);
bigUnblock = findViewById(R.id.message_request_big_unblock);
gv1Continue = findViewById(R.id.message_request_gv1_migration);
normalButtons = findViewById(R.id.message_request_normal_buttons);
blockedButtons = findViewById(R.id.message_request_blocked_buttons);
gv1MigrationButtons = findViewById(R.id.message_request_gv1_migration_buttons);
busyIndicator = findViewById(R.id.message_request_busy_indicator);
}
public void setMessageData(@NonNull MessageRequestViewModel.MessageData messageData) {
@ -73,52 +78,65 @@ public class MessageRequestsBottomView extends ConstraintLayout {
case BLOCKED_INDIVIDUAL:
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them,
HtmlUtil.bold(recipient.getShortDisplayName(getContext()))), 0));
setActiveInactiveGroups(blockedButtons, normalButtons);
setActiveInactiveGroups(blockedButtons, normalButtons, gv1MigrationButtons);
break;
case BLOCKED_GROUP:
question.setText(R.string.MessageRequestBottomView_unblock_this_group_and_share_your_name_and_photo_with_its_members);
setActiveInactiveGroups(blockedButtons, normalButtons);
setActiveInactiveGroups(blockedButtons, normalButtons, gv1MigrationButtons);
break;
case LEGACY_INDIVIDUAL:
question.setText(getContext().getString(R.string.MessageRequestBottomView_continue_your_conversation_with_s_and_share_your_name_and_photo, recipient.getShortDisplayName(getContext())));
question.setLearnMoreVisible(true);
question.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(getContext(), getContext().getString(R.string.MessageRequestBottomView_legacy_learn_more_url)));
setActiveInactiveGroups(normalButtons, blockedButtons);
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_continue);
break;
case LEGACY_GROUP_V1:
question.setText(R.string.MessageRequestBottomView_continue_your_conversation_with_this_group_and_share_your_name_and_photo);
question.setLearnMoreVisible(true);
question.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(getContext(), getContext().getString(R.string.MessageRequestBottomView_legacy_learn_more_url)));
setActiveInactiveGroups(normalButtons, blockedButtons);
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_continue);
break;
case DEPRECATED_GROUP_V1:
question.setText(R.string.MessageRequestBottomView_upgrade_this_group_to_activate_new_features);
setActiveInactiveGroups(gv1MigrationButtons, normalButtons, blockedButtons);
gv1Continue.setVisibility(VISIBLE);
break;
case DEPRECATED_GROUP_V1_TOO_LARGE:
question.setText(getContext().getString(R.string.MessageRequestBottomView_this_legacy_group_can_no_longer_be_used, FeatureFlags.groupLimits().getHardLimit() - 1));
setActiveInactiveGroups(gv1MigrationButtons, normalButtons, blockedButtons);
gv1Continue.setVisibility(GONE);
break;
case GROUP_V1:
case GROUP_V2_INVITE:
question.setText(R.string.MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
setActiveInactiveGroups(normalButtons, blockedButtons);
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_accept);
break;
case GROUP_V2_ADD:
question.setText(R.string.MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
setActiveInactiveGroups(normalButtons, blockedButtons);
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_accept);
break;
case INDIVIDUAL:
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept,
HtmlUtil.bold(recipient.getShortDisplayName(getContext()))), 0));
setActiveInactiveGroups(normalButtons, blockedButtons);
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_accept);
break;
}
}
private void setActiveInactiveGroups(@NonNull Group activeGroup, @NonNull Group inActiveGroup) {
private void setActiveInactiveGroups(@NonNull Group activeGroup, @NonNull Group... inActiveGroups) {
int initialVisibility = this.activeGroup != null ? this.activeGroup.getVisibility() : VISIBLE;
this.activeGroup = activeGroup;
inActiveGroup.setVisibility(GONE);
for (Group inactive : inActiveGroups) {
inactive.setVisibility(GONE);
}
activeGroup.setVisibility(initialVisibility);
}
@ -153,4 +171,8 @@ public class MessageRequestsBottomView extends ConstraintLayout {
public void setUnblockOnClickListener(OnClickListener unblockOnClickListener) {
bigUnblock.setOnClickListener(unblockOnClickListener);
}
public void setGroupV1MigrationContinueListener(OnClickListener acceptOnClickListener) {
gv1Continue.setOnClickListener(acceptOnClickListener);
}
}

Wyświetl plik

@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.FeatureFlags;
import java.util.LinkedList;
import java.util.List;
@ -41,7 +42,7 @@ public class DirectShareService extends ChooserTargetService {
List<ChooserTarget> results = new LinkedList<>();
ComponentName componentName = new ComponentName(this, ShareActivity.class);
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this);
Cursor cursor = threadDatabase.getRecentConversationList(10, false);
Cursor cursor = threadDatabase.getRecentConversationList(10, false, FeatureFlags.groupsV1ForcedMigration());
try {
ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor);

Wyświetl plik

@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.stickers.StickerLocator;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
@ -98,6 +99,10 @@ public class ShareActivity extends PassphraseRequiredActivity
mode |= DisplayMode.FLAG_SMS;
}
if (FeatureFlags.groupsV1ForcedMigration()) {
mode |= DisplayMode.FLAG_HIDE_GROUPS_V1;
}
getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, mode);
}

Wyświetl plik

@ -58,6 +58,19 @@
app:layout_constraintStart_toEndOf="@+id/message_request_delete"
app:layout_constraintTop_toTopOf="@id/message_request_block" />
<com.google.android.material.button.MaterialButton
android:id="@+id/message_request_gv1_migration"
style="@style/Signal.Widget.Button.Large.Primary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:text="@string/MessageRequestBottomView_continue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/message_request_big_delete"
style="@style/Signal.MessageRequest.Button.Deny"
@ -88,14 +101,15 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:barrierDirection="top"
app:constraint_referenced_ids="message_request_block,message_request_big_delete" />
app:constraint_referenced_ids="message_request_block,message_request_big_delete,message_request_gv1_migration" />
<androidx.constraintlayout.widget.Group
android:id="@+id/message_request_normal_buttons"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="message_request_accept,message_request_delete,message_request_block" />
app:constraint_referenced_ids="message_request_accept,message_request_delete,message_request_block"
tools:visibility="gone"/>
<androidx.constraintlayout.widget.Group
android:id="@+id/message_request_blocked_buttons"
@ -105,6 +119,14 @@
app:constraint_referenced_ids="message_request_big_delete,message_request_big_unblock"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Group
android:id="@+id/message_request_gv1_migration_buttons"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="message_request_gv1_migration"
tools:visibility="visible" />
<ProgressBar
android:id="@+id/message_request_busy_indicator"
style="?android:attr/progressBarStyle"
@ -116,6 +138,6 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_request_question"
tools:visibility="visible" />
tools:visibility="gone" />
</merge>

Wyświetl plik

@ -1192,6 +1192,8 @@
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept">Let %1$s message you and share your name and photo with them? They won\'t know you\'ve seen their message until you accept.</string>
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them">Let %1$s message you and share your name and photo with them? You won\'t receive any messages until you unblock them.</string>
<string name="MessageRequestBottomView_continue_your_conversation_with_this_group_and_share_your_name_and_photo">Continue your conversation with this group and share your name and photo with its members?</string>
<string name="MessageRequestBottomView_upgrade_this_group_to_activate_new_features">Upgrade this group to activate new features like @mentions and admins. Members who have not shared their name or photo in this group will be invited to join.</string>
<string name="MessageRequestBottomView_this_legacy_group_can_no_longer_be_used">This Legacy Group can no longer be used because it is too large. The maximum group size is %1$d.</string>
<string name="MessageRequestBottomView_continue_your_conversation_with_s_and_share_your_name_and_photo">Continue your conversation with %1$s and share your name and photo with them?</string>
<string name="MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group and share your name and photo with its members? They won\'t know you\'ve seen their messages until you accept.</string>
<string name="MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group? They wont know youve seen their messages until you accept.</string>