diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsHelper.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsHelper.kt index 9d952f08e8..82b487a32b 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsHelper.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsHelper.kt @@ -17,7 +17,6 @@ object MmsHelper { recipient: Recipient = Recipient.UNKNOWN, body: String = "body", sentTimeMillis: Long = System.currentTimeMillis(), - subscriptionId: Int = -1, expiresIn: Long = 0, viewOnce: Boolean = false, distributionType: Int = ThreadTable.DistributionTypes.DEFAULT, @@ -32,7 +31,6 @@ object MmsHelper { recipient = recipient, body = body, timestamp = sentTimeMillis, - subscriptionId = subscriptionId, expiresIn = expiresIn, viewOnce = viewOnce, distributionType = distributionType, diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java index 98a1e31e12..5daf39db0d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java +++ b/app/src/main/java/org/thoughtcrime/securesms/AppInitialization.java @@ -6,7 +6,6 @@ import androidx.annotation.NonNull; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.insights.InsightsOptOut; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobs.EmojiSearchIndexDownloadJob; import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob; @@ -30,7 +29,6 @@ public final class AppInitialization { public static void onFirstEverAppLaunch(@NonNull Context context) { Log.i(TAG, "onFirstEverAppLaunch()"); - InsightsOptOut.userRequestedOptOut(context); TextSecurePreferences.setAppMigrationVersion(context, ApplicationMigrations.CURRENT_VERSION); TextSecurePreferences.setJobManagerVersion(context, JobManager.CURRENT_VERSION); TextSecurePreferences.setLastVersionCode(context, Util.getCanonicalVersionCode()); @@ -71,7 +69,6 @@ public final class AppInitialization { public static void onRepairFirstEverAppLaunch(@NonNull Context context) { Log.w(TAG, "onRepairFirstEverAppLaunch()"); - InsightsOptOut.userRequestedOptOut(context); TextSecurePreferences.setAppMigrationVersion(context, ApplicationMigrations.CURRENT_VERSION); TextSecurePreferences.setJobManagerVersion(context, JobManager.CURRENT_VERSION); TextSecurePreferences.setLastVersionCode(context, Util.getCanonicalVersionCode()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java b/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java index 0d310ad11b..23d0c4156b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/InviteActivity.java @@ -254,13 +254,8 @@ public class InviteActivity extends PassphraseRequiredActivity implements Contac for (SelectedContact contact : contacts) { RecipientId recipientId = contact.getOrCreateRecipientId(context); Recipient recipient = Recipient.resolved(recipientId); - int subscriptionId = recipient.getDefaultSubscriptionId().orElse(-1); - MessageSender.send(context, OutgoingMessage.sms(recipient, message, subscriptionId), -1L, MessageSender.SendType.SMS, null, null); - - if (recipient.getContactUri() != null) { - SignalDatabase.recipients().setHasSentInvite(recipient.getId()); - } + MessageSender.send(context, OutgoingMessage.sms(recipient, message), -1L, MessageSender.SendType.SMS, null, null); } return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/MainNavigator.java b/app/src/main/java/org/thoughtcrime/securesms/MainNavigator.java index fea48a4a8c..0d7e28c24e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MainNavigator.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MainNavigator.java @@ -11,7 +11,6 @@ import org.signal.core.util.concurrent.LifecycleDisposable; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.conversation.ConversationIntents; import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity; -import org.thoughtcrime.securesms.insights.InsightsLauncher; import org.thoughtcrime.securesms.recipients.RecipientId; import io.reactivex.rxjava3.disposables.Disposable; @@ -78,10 +77,6 @@ public class MainNavigator { activity.startActivity(intent); } - public void goToInsights() { - InsightsLauncher.showInsightsDashboard(activity.getSupportFragmentManager()); - } - private @NonNull FragmentManager getFragmentManager() { return activity.getSupportFragmentManager(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/FirstInviteReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/FirstInviteReminder.java deleted file mode 100644 index 5c1e6859d5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/FirstInviteReminder.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; - -public final class FirstInviteReminder extends Reminder { - - private final int percentIncrease; - - public FirstInviteReminder(final int percentIncrease) { - super(R.string.FirstInviteReminder__title, NO_RESOURCE); - this.percentIncrease = percentIncrease; - - addAction(new Action(R.string.InsightsReminder__invite, R.id.reminder_action_invite)); - addAction(new Action(R.string.InsightsReminder__view_insights, R.id.reminder_action_view_insights)); - } - - @Override - public @NonNull CharSequence getText(@NonNull Context context) { - return context.getString(R.string.FirstInviteReminder__description, percentIncrease); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SecondInviteReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SecondInviteReminder.java deleted file mode 100644 index fb6a7af35b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/SecondInviteReminder.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.recipients.Recipient; - -public final class SecondInviteReminder extends Reminder { - - private final Recipient recipient; - private final int progress; - - public SecondInviteReminder(final @NonNull Context context, - final @NonNull Recipient recipient, - final int percent) - { - super(R.string.SecondInviteReminder__title, NO_RESOURCE); - this.recipient = recipient; - - this.progress = percent; - - addAction(new Action(R.string.InsightsReminder__invite, R.id.reminder_action_invite)); - addAction(new Action(R.string.InsightsReminder__view_insights, R.id.reminder_action_view_insights)); - } - - @Override - public @NonNull CharSequence getText(@NonNull Context context) { - return context.getString(R.string.SecondInviteReminder__description, recipient.getDisplayName(context)); - } - - @Override - public int getProgress() { - return progress; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt index 12e6961597..ff1cbbcf85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt @@ -573,7 +573,7 @@ open class ContactSearchAdapter( } private fun isSmsContact(model: T): Boolean { - return (getRecipient(model).isForceSmsSelection || getRecipient(model).isUnregistered) && !getRecipient(model).isDistributionList + return getRecipient(model).isUnregistered && !getRecipient(model).isDistributionList } private fun isNotRegistered(model: T): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java index 4c6d892036..3b55dfbdf6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java @@ -184,10 +184,7 @@ import org.thoughtcrime.securesms.groups.ui.LeaveGroupDialog; import org.thoughtcrime.securesms.groups.ui.invitesandrequests.ManagePendingAndRequestingMembersActivity; import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationInitiationBottomSheetDialogFragment; import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationSuggestionsDialog; -import org.thoughtcrime.securesms.insights.InsightsLauncher; import org.thoughtcrime.securesms.invites.InviteActions; -import org.thoughtcrime.securesms.invites.InviteReminderModel; -import org.thoughtcrime.securesms.invites.InviteReminderRepository; import org.thoughtcrime.securesms.jobs.ForceUpdateGroupV2Job; import org.thoughtcrime.securesms.jobs.GroupV1MigrationJob; import org.thoughtcrime.securesms.jobs.GroupV2UpdateSelfProfileKeyJob; @@ -437,7 +434,6 @@ public class ConversationParentFragment extends Fragment private ConversationSearchViewModel searchViewModel; private ConversationStickerViewModel stickerViewModel; private ConversationViewModel viewModel; - private InviteReminderModel inviteReminderModel; private ConversationGroupViewModel groupViewModel; private MentionsPickerViewModel mentionsViewModel; private InlineQueryViewModel inlineQueryViewModel; @@ -1364,8 +1360,7 @@ public class ConversationParentFragment extends Fragment if (paymentsValues.getPaymentsAvailability().isSendAllowed() && !recipient.get().isSelf() && !recipient.get().isGroup() && - recipient.get().isRegistered() && - !recipient.get().isForceSmsSelection()) + recipient.get().isRegistered()) { attachmentKeyboardStub.get().filterAttachmentKeyboardButtons(null); } else { @@ -1425,16 +1420,11 @@ public class ConversationParentFragment extends Fragment sendButton.disableTransportType(MessageSendType.TransportType.SIGNAL); } - if (!recipient.get().isPushGroup() && recipient.get().isForceSmsSelection() && smsEnabled) { + if (isPushAvailable || isPushGroupConversation() || recipient.get().isServiceIdOnly() || recipient.get().isReleaseNotes() || !smsEnabled) { + sendButton.setDefaultTransport(MessageSendType.TransportType.SIGNAL); + } else { sendButton.setDefaultTransport(MessageSendType.TransportType.SMS); viewModel.insertSmsExportUpdateEvent(recipient.get()); - } else { - if (isPushAvailable || isPushGroupConversation() || recipient.get().isServiceIdOnly() || recipient.get().isReleaseNotes() || !smsEnabled) { - sendButton.setDefaultTransport(MessageSendType.TransportType.SIGNAL); - } else { - sendButton.setDefaultTransport(MessageSendType.TransportType.SMS); - viewModel.insertSmsExportUpdateEvent(recipient.get()); - } } calculateCharactersRemaining(); @@ -1710,12 +1700,9 @@ public class ConversationParentFragment extends Fragment private void onSecurityUpdated() { Log.i(TAG, "onSecurityUpdated()"); updateReminders(); - updateDefaultSubscriptionId(recipient.get().getDefaultSubscriptionId()); } private void initializeInsightObserver() { - inviteReminderModel = new InviteReminderModel(requireContext(), new InviteReminderRepository(requireContext())); - inviteReminderModel.loadReminder(recipient, this::updateReminders); } protected void updateReminders() { @@ -1724,7 +1711,6 @@ public class ConversationParentFragment extends Fragment return; } - Optional inviteReminder = inviteReminderModel.getReminder(); Integer actionableRequestingMembers = groupViewModel.getActionableRequestingMembers().getValue(); List gv1MigrationSuggestions = groupViewModel.getGroupV1MigrationSuggestions().getValue(); @@ -1740,11 +1726,8 @@ public class ConversationParentFragment extends Fragment } else if (SignalStore.account().isRegistered() && TextSecurePreferences.isShowInviteReminders(context) && !viewModel.isPushAvailable() && - inviteReminder.isPresent() && !recipient.get().isGroup()) { reminderView.get().setOnActionClickListener(this::handleReminderAction); - reminderView.get().setOnDismissListener(() -> inviteReminderModel.dismissReminder()); - reminderView.get().showReminder(inviteReminder.get()); } else if (actionableRequestingMembers != null && actionableRequestingMembers > 0) { reminderView.get().showReminder(new PendingGroupJoinRequestsReminder(actionableRequestingMembers)); reminderView.get().setOnActionClickListener(id -> { @@ -1785,8 +1768,6 @@ public class ConversationParentFragment extends Fragment if (reminderActionId == R.id.reminder_action_invite) { handleInviteLink(); reminderView.get().requestDismiss(); - } else if (reminderActionId == R.id.reminder_action_view_insights) { - InsightsLauncher.showInsightsDashboard(getChildFragmentManager()); } else if (reminderActionId == R.id.reminder_action_update_now) { PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext()); } else if (reminderActionId == R.id.reminder_action_re_register) { @@ -1958,8 +1939,6 @@ public class ConversationParentFragment extends Fragment composeText.setMessageSendType(newMessageSendType); updateSendButtonColor(newMessageSendType); - - if (manuallySelected) recordTransportPreference(newMessageSendType); }); titleView.setOnStoryRingClickListener(v -> handleStoryRingClick()); @@ -2461,7 +2440,6 @@ public class ConversationParentFragment extends Fragment titleView.setVerified(identityRecords.isVerified() && !recipient.isSelf()); setBlockedUserState(recipient, viewModel.getConversationStateSnapshot().getSecurityInfo()); updateReminders(); - updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId()); updatePaymentsAvailable(); updateSendButtonColor(sendButton.getSelectedSendType()); @@ -2904,7 +2882,6 @@ public class ConversationParentFragment extends Fragment result.getBody(), Collections.emptyList(), System.currentTimeMillis(), - -1, expiresIn, result.isViewOnce(), distributionType, @@ -3033,7 +3010,6 @@ public class ConversationParentFragment extends Fragment OutgoingMessage.buildMessage(slideDeck, body), slideDeck.asAttachments(), System.currentTimeMillis(), - sendType.getSimSubscriptionIdOr(-1), expiresIn, viewOnce, distributionType, @@ -3126,7 +3102,7 @@ public class ConversationParentFragment extends Fragment } ApplicationDependencies.getTypingStatusSender().onTypingStopped(thread); } else { - message = OutgoingMessage.sms(recipient.get(), messageBody, sendType.getSimSubscriptionIdOr(-1)); + message = OutgoingMessage.sms(recipient.get(), messageBody); } Permissions.with(this) @@ -3246,23 +3222,6 @@ public class ConversationParentFragment extends Fragment } } - private void recordTransportPreference(MessageSendType sendType) { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - RecipientTable recipientTable = SignalDatabase.recipients(); - - recipientTable.setDefaultSubscriptionId(recipient.getId(), sendType.getSimSubscriptionIdOr(-1)); - - if (!recipient.resolve().isPushGroup()) { - recipientTable.setForceSmsSelection(recipient.getId(), recipient.get().getRegistered() == RegisteredState.REGISTERED && sendType.usesSmsTransport()); - } - - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - @Override public void onRecorderPermissionRequired() { Permissions.with(this) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/keyboard/AttachmentKeyboardFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/keyboard/AttachmentKeyboardFragment.kt index 094c459a12..f386ce1f6e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/keyboard/AttachmentKeyboardFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/keyboard/AttachmentKeyboardFragment.kt @@ -104,8 +104,7 @@ class AttachmentKeyboardFragment : LoggingFragment(R.layout.attachment_keyboard_ if (paymentsValues.paymentsAvailability.isSendAllowed && !recipient.isSelf && !recipient.isGroup && - recipient.isRegistered && - !recipient.isForceSmsSelection + recipient.isRegistered ) { attachmentKeyboardView.filterAttachmentKeyboardButtons(null) } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index 43578c6073..de92d57abd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -138,7 +138,6 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.ReminderUpdateEvent; import org.thoughtcrime.securesms.exporter.flow.SmsExportDialogs; import org.thoughtcrime.securesms.groups.SelectionLimits; -import org.thoughtcrime.securesms.insights.InsightsLauncher; import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.lock.v2.CreateSvrPinActivity; @@ -472,10 +471,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode itemAnimator.disable(); SpoilerAnnotation.resetRevealedSpoilers(); - if (Util.isDefaultSmsProvider(requireContext())) { - InsightsLauncher.showInsightsModal(requireContext(), requireFragmentManager()); - } - if ((!requireCallback().getSearchToolbar().resolved() || !(requireCallback().getSearchToolbar().get().getVisibility() == View.VISIBLE)) && list.getAdapter() != defaultAdapter) { setAdapter(defaultAdapter); } @@ -561,7 +556,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode @Override public void onPrepareOptionsMenu(Menu menu) { - menu.findItem(R.id.menu_insights).setVisible(Util.isDefaultSmsProvider(requireContext())); menu.findItem(R.id.menu_clear_passphrase).setVisible(!TextSecurePreferences.isPasswordDisabled(requireContext())); ConversationFilterRequest request = viewModel.getConversationFilterRequest(); @@ -592,9 +586,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode } else if (itemId == R.id.menu_invite) { handleInvite(); return true; - } else if (itemId == R.id.menu_insights) { - handleInsights(); - return true; } else if (itemId == R.id.menu_notification_profile) { handleNotificationProfile(); return true; @@ -1143,10 +1134,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode getNavigator().goToInvite(); } - private void handleInsights() { - getNavigator().goToInsights(); - } - private void handleNotificationProfile() { NotificationProfileSelectionFragment.show(getParentFragmentManager()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index b1417a8495..ab3922399e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -112,7 +112,6 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.SessionSwitchove import org.thoughtcrime.securesms.database.model.databaseprotos.ThreadMergeEvent import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange -import org.thoughtcrime.securesms.insights.InsightsConstants import org.thoughtcrime.securesms.jobs.OptimizeMessageSearchIndexJob import org.thoughtcrime.securesms.jobs.ThreadUpdateJob import org.thoughtcrime.securesms.jobs.TrimThreadJob @@ -1084,10 +1083,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat if (unread && editedMessage == null) { threads.incrementUnread(threadId, 1, 0) } - - if (message.subscriptionId != -1) { - recipients.setDefaultSubscriptionId(message.authorId, message.subscriptionId) - } } id @@ -2507,7 +2502,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat body = body, attachments = attachments, timestamp = timestamp, - subscriptionId = subscriptionId, expiresIn = expiresIn, viewOnce = viewOnce, distributionType = distributionType, @@ -3712,15 +3706,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat .readToSingleInt() } - fun getInsecureMessageSentCount(threadId: Long): Int { - return readableDatabase - .select("COUNT(*)") - .from(TABLE_NAME) - .where("$THREAD_ID = ? AND $outgoingInsecureMessageClause AND $DATE_SENT > ?", threadId, (System.currentTimeMillis() - InsightsConstants.PERIOD_IN_MILLIS)) - .run() - .readToSingleInt() - } - fun getSecureMessageCount(threadId: Long): Int { return readableDatabase .select("COUNT(*)") @@ -3739,14 +3724,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat .readToSingleInt() } - fun getInsecureMessageCountForInsights(): Int { - return getMessageCountForRecipientsAndType(outgoingInsecureMessageClause) - } - - fun getSecureMessageCountForInsights(): Int { - return getMessageCountForRecipientsAndType(outgoingSecureMessageClause) - } - private fun hasSmsExportMessage(threadId: Long): Boolean { return readableDatabase .exists(TABLE_NAME) @@ -3754,15 +3731,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat .run() } - private fun getMessageCountForRecipientsAndType(typeClause: String): Int { - return readableDatabase - .select("COUNT(*)") - .from(TABLE_NAME) - .where("$typeClause AND $DATE_SENT > ?", (System.currentTimeMillis() - InsightsConstants.PERIOD_IN_MILLIS)) - .run() - .readToSingleInt() - } - private val outgoingInsecureMessageClause = "($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_TYPE} AND NOT ($TYPE & ${MessageTypes.SECURE_MESSAGE_BIT})" private val outgoingSecureMessageClause = "($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_TYPE} AND ($TYPE & ${MessageTypes.SECURE_MESSAGE_BIT or MessageTypes.PUSH_MESSAGE_BIT})" diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt index 813a9267f1..704c8d7393 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt @@ -285,8 +285,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da CALL_VIBRATE, MUTE_UNTIL, AVATAR_COLOR, - SEEN_INVITE_REMINDER, - DEFAULT_SUBSCRIPTION_ID, MESSAGE_EXPIRATION_TIME, REGISTERED, PROFILE_KEY, @@ -305,7 +303,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da LAST_PROFILE_FETCH, NOTIFICATION_CHANNEL, UNIDENTIFIED_ACCESS_MODE, - FORCE_SMS_SELECTION, CAPABILITIES, STORAGE_SERVICE_ID, MENTION_SETTING, @@ -396,21 +393,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da """ ) - private val INSIGHTS_INVITEE_LIST = - """ - SELECT $TABLE_NAME.$ID - FROM $TABLE_NAME INNER JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} - WHERE - $TABLE_NAME.$GROUP_ID IS NULL AND - $TABLE_NAME.$REGISTERED = ${RegisteredState.NOT_REGISTERED.id} AND - $TABLE_NAME.$SEEN_INVITE_REMINDER < ${InsightsBannerTier.TIER_TWO.id} AND - ${ThreadTable.TABLE_NAME}.${ThreadTable.HAS_SENT} AND - ${ThreadTable.TABLE_NAME}.${ThreadTable.DATE} > ? AND - ${ThreadTable.TABLE_NAME}.${ThreadTable.ACTIVE} = 1 AND - $TABLE_NAME.$HIDDEN = 0 - ORDER BY ${ThreadTable.TABLE_NAME}.${ThreadTable.DATE} DESC LIMIT 50 - """ - /** Used as a placeholder recipient for self during migrations when self isn't yet available. */ private val PLACEHOLDER_SELF_ID = -2L } @@ -1348,24 +1330,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da } } - fun setDefaultSubscriptionId(id: RecipientId, defaultSubscriptionId: Int) { - val values = ContentValues().apply { - put(DEFAULT_SUBSCRIPTION_ID, defaultSubscriptionId) - } - if (update(id, values)) { - ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id) - } - } - - fun setForceSmsSelection(id: RecipientId, forceSmsSelection: Boolean) { - val contentValues = ContentValues(1).apply { - put(FORCE_SMS_SELECTION, if (forceSmsSelection) 1 else 0) - } - if (update(id, contentValues)) { - ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id) - } - } - fun setBlocked(id: RecipientId, blocked: Boolean) { val values = ContentValues().apply { put(BLOCKED, if (blocked) 1 else 0) @@ -1452,29 +1416,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da StorageSyncHelper.scheduleSyncForDataChange() } - fun setSeenFirstInviteReminder(id: RecipientId) { - setInsightsBannerTier(id, InsightsBannerTier.TIER_ONE) - } - - fun setSeenSecondInviteReminder(id: RecipientId) { - setInsightsBannerTier(id, InsightsBannerTier.TIER_TWO) - } - - fun setHasSentInvite(id: RecipientId) { - setSeenSecondInviteReminder(id) - } - - private fun setInsightsBannerTier(id: RecipientId, insightsBannerTier: InsightsBannerTier) { - val query = "$ID = ? AND $SEEN_INVITE_REMINDER < ?" - val args = arrayOf(id.serialize(), insightsBannerTier.toString()) - val values = ContentValues(1).apply { - put(SEEN_INVITE_REMINDER, insightsBannerTier.id) - } - - writableDatabase.update(TABLE_NAME, values, query, args) - ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id) - } - fun setExpireMessages(id: RecipientId, expiration: Int) { val values = ContentValues(1).apply { put(MESSAGE_EXPIRATION_TIME, expiration) @@ -3096,19 +3037,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da return operations } - fun getUninvitedRecipientsForInsights(): List { - val results: MutableList = LinkedList() - val args = arrayOf((System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31)).toString()) - - readableDatabase.rawQuery(INSIGHTS_INVITEE_LIST, args).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - results.add(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ID)))) - } - } - - return results - } - fun getRegistered(): List { val results: MutableList = LinkedList() @@ -3899,8 +3827,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da CHAT_COLORS to Optional.ofNullable(primaryRecord.chatColors).or(Optional.ofNullable(secondaryRecord.chatColors)).map { colors: ChatColors? -> colors!!.serialize().toByteArray() }.orElse(null), AVATAR_COLOR to primaryRecord.avatarColor.serialize(), CUSTOM_CHAT_COLORS_ID to Optional.ofNullable(primaryRecord.chatColors).or(Optional.ofNullable(secondaryRecord.chatColors)).map { colors: ChatColors? -> colors!!.id.longValue }.orElse(null), - SEEN_INVITE_REMINDER to secondaryRecord.insightsBannerTier.id, - DEFAULT_SUBSCRIPTION_ID to secondaryRecord.getDefaultSubscriptionId().orElse(-1), MESSAGE_EXPIRATION_TIME to if (primaryRecord.expireMessages > 0) primaryRecord.expireMessages else secondaryRecord.expireMessages, REGISTERED to RegisteredState.REGISTERED.id, SYSTEM_GIVEN_NAME to secondaryRecord.systemProfileName.givenName, @@ -4246,7 +4172,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da callVibrateState = VibrateState.fromId(cursor.requireInt(CALL_VIBRATE)), messageRingtone = Util.uri(cursor.requireString(MESSAGE_RINGTONE)), callRingtone = Util.uri(cursor.requireString(CALL_RINGTONE)), - defaultSubscriptionId = cursor.requireInt(DEFAULT_SUBSCRIPTION_ID), expireMessages = cursor.requireInt(MESSAGE_EXPIRATION_TIME), registered = RegisteredState.fromId(cursor.requireInt(REGISTERED)), profileKey = profileKey, @@ -4263,9 +4188,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da lastProfileFetch = cursor.requireLong(LAST_PROFILE_FETCH), notificationChannel = cursor.requireString(NOTIFICATION_CHANNEL), unidentifiedAccessMode = UnidentifiedAccessMode.fromMode(cursor.requireInt(UNIDENTIFIED_ACCESS_MODE)), - forceSmsSelection = cursor.requireBoolean(FORCE_SMS_SELECTION), capabilities = readCapabilities(cursor), - insightsBannerTier = InsightsBannerTier.fromId(cursor.requireInt(SEEN_INVITE_REMINDER)), storageId = Base64.decodeNullableOrThrow(cursor.requireString(STORAGE_SERVICE_ID)), mentionSetting = MentionSetting.fromId(cursor.requireInt(MENTION_SETTING)), wallpaper = chatWallpaper, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt index 7cafb8cfda..ae190c8379 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt @@ -8,7 +8,6 @@ import org.thoughtcrime.securesms.conversation.colors.AvatarColor import org.thoughtcrime.securesms.conversation.colors.ChatColors import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus import org.thoughtcrime.securesms.database.RecipientTable -import org.thoughtcrime.securesms.database.RecipientTable.InsightsBannerTier import org.thoughtcrime.securesms.database.RecipientTable.MentionSetting import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState import org.thoughtcrime.securesms.database.RecipientTable.UnidentifiedAccessMode @@ -22,7 +21,6 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper import org.whispersystems.signalservice.api.push.ServiceId import org.whispersystems.signalservice.api.push.ServiceId.ACI import org.whispersystems.signalservice.api.push.ServiceId.PNI -import java.util.Optional /** * Database model for [RecipientTable]. @@ -43,7 +41,6 @@ data class RecipientRecord( val callVibrateState: VibrateState, val messageRingtone: Uri?, val callRingtone: Uri?, - private val defaultSubscriptionId: Int, val expireMessages: Int, val registered: RegisteredState, val profileKey: ByteArray?, @@ -63,10 +60,7 @@ data class RecipientRecord( val lastProfileFetch: Long, val notificationChannel: String?, val unidentifiedAccessMode: UnidentifiedAccessMode, - @get:JvmName("isForceSmsSelection") - val forceSmsSelection: Boolean, val capabilities: Capabilities, - val insightsBannerTier: InsightsBannerTier, val storageId: ByteArray?, val mentionSetting: MentionSetting, val wallpaper: ChatWallpaper?, @@ -85,10 +79,6 @@ data class RecipientRecord( val callLinkRoomId: CallLinkRoomId? ) { - fun getDefaultSubscriptionId(): Optional { - return if (defaultSubscriptionId != -1) Optional.of(defaultSubscriptionId) else Optional.empty() - } - fun e164Only(): Boolean { return this.e164 != null && this.aci == null } diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsAnimatorSetFactory.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsAnimatorSetFactory.java deleted file mode 100644 index a46499ef47..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsAnimatorSetFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ValueAnimator; -import android.view.animation.DecelerateInterpolator; - -import androidx.annotation.Nullable; - -import com.annimon.stream.Stream; - -final class InsightsAnimatorSetFactory { - private static final int PROGRESS_ANIMATION_DURATION = 800; - private static final int DETAILS_ANIMATION_DURATION = 200; - private static final int PERCENT_SECURE_ANIMATION_DURATION = 400; - private static final int LOTTIE_ANIMATION_DURATION = 1500; - private static final int ANIMATION_START_DELAY = PROGRESS_ANIMATION_DURATION - DETAILS_ANIMATION_DURATION; - private static final float PERCENT_SECURE_MAX_SCALE = 1.3f; - - private InsightsAnimatorSetFactory() { - } - - static AnimatorSet create(int insecurePercent, - @Nullable final UpdateListener progressUpdateListener, - @Nullable final UpdateListener detailsUpdateListener, - @Nullable final UpdateListener percentSecureListener, - @Nullable final UpdateListener lottieListener) - { - final int securePercent = 100 - insecurePercent; - final AnimatorSet animatorSet = new AnimatorSet(); - final ValueAnimator[] animators = Stream.of(createProgressAnimator(securePercent, progressUpdateListener), - createDetailsAnimator(detailsUpdateListener), - createPercentSecureAnimator(percentSecureListener), - createLottieAnimator(lottieListener)) - .filter(a -> a != null) - .toArray(ValueAnimator[]::new); - - animatorSet.setInterpolator(new DecelerateInterpolator()); - animatorSet.playTogether(animators); - - return animatorSet; - } - - private static @Nullable Animator createProgressAnimator(int securePercent, @Nullable UpdateListener updateListener) { - if (updateListener == null) return null; - - final ValueAnimator progressAnimator = ValueAnimator.ofFloat(0, securePercent / 100f); - - progressAnimator.setDuration(PROGRESS_ANIMATION_DURATION); - progressAnimator.addUpdateListener(animation -> updateListener.onUpdate((float) animation.getAnimatedValue())); - - return progressAnimator; - } - - private static @Nullable Animator createDetailsAnimator(@Nullable UpdateListener updateListener) { - if (updateListener == null) return null; - - final ValueAnimator detailsAnimator = ValueAnimator.ofFloat(0, 1f); - - detailsAnimator.setDuration(DETAILS_ANIMATION_DURATION); - detailsAnimator.setStartDelay(ANIMATION_START_DELAY); - detailsAnimator.addUpdateListener(animation -> updateListener.onUpdate((float) animation.getAnimatedValue())); - - return detailsAnimator; - } - - private static @Nullable Animator createPercentSecureAnimator(@Nullable UpdateListener updateListener) { - if (updateListener == null) return null; - - final ValueAnimator percentSecureAnimator = ValueAnimator.ofFloat(1f, PERCENT_SECURE_MAX_SCALE, 1f); - - percentSecureAnimator.setStartDelay(ANIMATION_START_DELAY); - percentSecureAnimator.setDuration(PERCENT_SECURE_ANIMATION_DURATION); - percentSecureAnimator.addUpdateListener(animation -> updateListener.onUpdate((float) animation.getAnimatedValue())); - - return percentSecureAnimator; - } - - private static @Nullable Animator createLottieAnimator(@Nullable UpdateListener updateListener) { - if (updateListener == null) return null; - - final ValueAnimator lottieAnimator = ValueAnimator.ofFloat(0, 1f); - - lottieAnimator.setStartDelay(ANIMATION_START_DELAY); - lottieAnimator.setDuration(LOTTIE_ANIMATION_DURATION); - lottieAnimator.addUpdateListener(animation -> updateListener.onUpdate((float) animation.getAnimatedValue())); - - return lottieAnimator; - } - - interface UpdateListener { - void onUpdate(float value); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsConstants.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsConstants.java deleted file mode 100644 index 40435b33d5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsConstants.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import java.util.concurrent.TimeUnit; - -public final class InsightsConstants { - - public static final long PERIOD_IN_DAYS = 7L; - public static final long PERIOD_IN_MILLIS = TimeUnit.DAYS.toMillis(PERIOD_IN_DAYS); - - private InsightsConstants() { - } - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardDialogFragment.java deleted file mode 100644 index bcabaeb806..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardDialogFragment.java +++ /dev/null @@ -1,271 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.RecyclerView; - -import com.airbnb.lottie.LottieAnimationView; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.thoughtcrime.securesms.NewConversationActivity; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.ArcProgressBar; -import org.thoughtcrime.securesms.components.AvatarImageView; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.ThemeUtil; - -import java.util.List; - -public final class InsightsDashboardDialogFragment extends DialogFragment { - - private TextView securePercentage; - private ArcProgressBar progress; - private View progressContainer; - private TextView tagline; - private TextView encryptedMessages; - private TextView title; - private TextView description; - private RecyclerView insecureRecipients; - private TextView locallyGenerated; - private AvatarImageView avatarImageView; - private InsightsInsecureRecipientsAdapter adapter; - private LottieAnimationView lottieAnimationView; - private AnimatorSet animatorSet; - private Button startAConversation; - private Toolbar toolbar; - private InsightsDashboardViewModel viewModel; - - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - requireFragmentManager().beginTransaction() - .detach(this) - .attach(this) - .commit(); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (ThemeUtil.isDarkTheme(requireActivity())) { - setStyle(STYLE_NO_FRAME, R.style.TextSecure_DarkTheme); - } else { - setStyle(STYLE_NO_FRAME, R.style.TextSecure_LightTheme); - } - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.insights_dashboard, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - securePercentage = view.findViewById(R.id.insights_dashboard_percent_secure); - progress = view.findViewById(R.id.insights_dashboard_progress); - progressContainer = view.findViewById(R.id.insights_dashboard_percent_container); - encryptedMessages = view.findViewById(R.id.insights_dashboard_encrypted_messages); - tagline = view.findViewById(R.id.insights_dashboard_tagline); - title = view.findViewById(R.id.insights_dashboard_make_signal_secure); - description = view.findViewById(R.id.insights_dashboard_invite_your_contacts); - insecureRecipients = view.findViewById(R.id.insights_dashboard_recycler); - locallyGenerated = view.findViewById(R.id.insights_dashboard_this_stat_was_generated_locally); - avatarImageView = view.findViewById(R.id.insights_dashboard_avatar); - startAConversation = view.findViewById(R.id.insights_dashboard_start_a_conversation); - lottieAnimationView = view.findViewById(R.id.insights_dashboard_lottie_animation); - toolbar = view.findViewById(R.id.insights_dashboard_toolbar); - - setupStartAConversation(); - setDashboardDetailsAlpha(0f); - setNotEnoughDataAlpha(0f); - setupToolbar(); - setupRecycler(); - initializeViewModel(); - } - - private void setupStartAConversation() { - startAConversation.setOnClickListener(v -> startActivity(new Intent(requireActivity(), NewConversationActivity.class))); - } - - private void setDashboardDetailsAlpha(float alpha) { - tagline.setAlpha(alpha); - title.setAlpha(alpha); - description.setAlpha(alpha); - insecureRecipients.setAlpha(alpha); - locallyGenerated.setAlpha(alpha); - encryptedMessages.setAlpha(alpha); - } - - private void setupToolbar() { - toolbar.setNavigationOnClickListener(v -> dismiss()); - } - - private void setupRecycler() { - adapter = new InsightsInsecureRecipientsAdapter(this::handleInviteRecipient); - insecureRecipients.setAdapter(adapter); - } - - private void initializeViewModel() { - final InsightsDashboardViewModel.Repository repository = new InsightsRepository(requireContext()); - final InsightsDashboardViewModel.Factory factory = new InsightsDashboardViewModel.Factory(repository); - - viewModel = new ViewModelProvider(this, factory).get(InsightsDashboardViewModel.class); - - viewModel.getState().observe(getViewLifecycleOwner(), state -> { - updateInsecurePercent(state.getData()); - updateInsecureRecipients(state.getInsecureRecipients()); - updateUserAvatar(state.getUserAvatar()); - }); - } - - private void updateInsecurePercent(@Nullable InsightsData insightsData) { - if (insightsData == null) return; - - if (insightsData.hasEnoughData()) { - setTitleAndDescriptionText(insightsData.getPercentInsecure()); - animateProgress(insightsData.getPercentInsecure()); - } else { - setNotEnoughDataText(); - animateNotEnoughData(); - } - } - - private void animateProgress(int insecurePercent) { - startAConversation.setVisibility(View.GONE); - if (animatorSet == null) { - animatorSet = InsightsAnimatorSetFactory.create(insecurePercent, - this::setProgressPercentage, - this::setDashboardDetailsAlpha, - this::setPercentSecureScale, - insecurePercent == 0 ? this::setLottieProgress : null); - - if (insecurePercent == 0) { - animatorSet.addListener(new ToolbarBackgroundColorAnimationListener()); - } - - animatorSet.start(); - } - } - - private void setProgressPercentage(float percent) { - securePercentage.setText(String.valueOf(Math.round(percent * 100))); - progress.setProgress(percent); - } - - private void setPercentSecureScale(float scale) { - progressContainer.setScaleX(scale); - progressContainer.setScaleY(scale); - } - - private void setLottieProgress(float progress) { - lottieAnimationView.setProgress(progress); - } - - private void setTitleAndDescriptionText(int insecurePercent) { - startAConversation.setVisibility(View.GONE); - progressContainer.setVisibility(View.VISIBLE); - insecureRecipients.setVisibility(View.VISIBLE); - encryptedMessages.setText(R.string.InsightsDashboardFragment__encrypted_messages); - tagline.setText(getString(R.string.InsightsDashboardFragment__signal_protocol_automatically_protected, 100 - insecurePercent, InsightsConstants.PERIOD_IN_DAYS)); - - if (insecurePercent == 0) { - lottieAnimationView.setVisibility(View.VISIBLE); - title.setVisibility(View.GONE); - description.setVisibility(View.GONE); - } else { - lottieAnimationView.setVisibility(View.GONE); - title.setText(R.string.InsightsDashboardFragment__spread_the_word); - description.setText(R.string.InsightsDashboardFragment__invite_your_contacts); - title.setVisibility(View.VISIBLE); - description.setVisibility(View.VISIBLE); - } - } - - private void setNotEnoughDataText() { - startAConversation.setVisibility(View.VISIBLE); - progressContainer.setVisibility(View.INVISIBLE); - insecureRecipients.setVisibility(View.GONE); - encryptedMessages.setText(R.string.InsightsDashboardFragment__not_enough_data); - tagline.setText(getString(R.string.InsightsDashboardFragment__your_insights_percentage_is_calculated_based_on, InsightsConstants.PERIOD_IN_DAYS)); - } - - private void animateNotEnoughData() { - if (animatorSet == null) { - animatorSet = InsightsAnimatorSetFactory.create(0, null, this::setNotEnoughDataAlpha, null, null); - animatorSet.start(); - } - } - - private void setNotEnoughDataAlpha(float alpha) { - encryptedMessages.setAlpha(alpha); - tagline.setAlpha(alpha); - startAConversation.setAlpha(alpha); - } - - private void updateInsecureRecipients(@NonNull List recipients) { - adapter.updateData(recipients); - } - - private void updateUserAvatar(@Nullable InsightsUserAvatar userAvatar) { - if (userAvatar == null) avatarImageView.setImageDrawable(null); - else userAvatar.load(avatarImageView); - } - - private void handleInviteRecipient(final @NonNull Recipient recipient) { - new MaterialAlertDialogBuilder(requireContext()) - .setTitle(getResources().getQuantityString(R.plurals.InviteActivity_send_sms_invites, 1, 1)) - .setMessage(getString(R.string.InviteActivity_lets_switch_to_signal, getString(R.string.install_url))) - .setPositiveButton(R.string.InsightsDashboardFragment__send, (dialog, which) -> viewModel.sendSmsInvite(recipient)) - .setNegativeButton(R.string.InsightsDashboardFragment__cancel, (dialog, which) -> dialog.dismiss()) - .show(); - } - - @Override - public void onDestroyView() { - if (animatorSet != null) { - animatorSet.cancel(); - animatorSet = null; - } - - super.onDestroyView(); - } - - private final class ToolbarBackgroundColorAnimationListener implements Animator.AnimatorListener { - - @Override - public void onAnimationStart(Animator animation) { - toolbar.setBackgroundResource(R.color.transparent); - } - - @Override - public void onAnimationEnd(Animator animation) { - toolbar.setBackgroundColor(ThemeUtil.getThemedColor(requireContext(), android.R.attr.windowBackground)); - } - - @Override - public void onAnimationCancel(Animator animation) { - toolbar.setBackgroundColor(ThemeUtil.getThemedColor(requireContext(), android.R.attr.windowBackground)); - } - - @Override - public void onAnimationRepeat(Animator animation) { - - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardState.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardState.java deleted file mode 100644 index f97933342c..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardState.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.thoughtcrime.securesms.recipients.Recipient; - -import java.util.Collections; -import java.util.List; - -final class InsightsDashboardState { - - private final List insecureRecipients; - private final InsightsData insightsData; - private final InsightsUserAvatar userAvatar; - - private InsightsDashboardState(@NonNull Builder builder) { - this.insecureRecipients = builder.insecureRecipients; - this.insightsData = builder.insightsData; - this.userAvatar = builder.userAvatar; - } - - static @NonNull InsightsDashboardState.Builder builder() { - return new InsightsDashboardState.Builder(); - } - - @NonNull InsightsDashboardState.Builder buildUpon() { - return builder().withData(insightsData).withUserAvatar(userAvatar).withInsecureRecipients(insecureRecipients); - } - - @NonNull List getInsecureRecipients() { - return insecureRecipients; - } - - @Nullable InsightsUserAvatar getUserAvatar() { - return userAvatar; - } - - @Nullable InsightsData getData() { - return insightsData; - } - - static final class Builder { - private List insecureRecipients = Collections.emptyList(); - private InsightsUserAvatar userAvatar; - private InsightsData insightsData; - - private Builder() { - } - - @NonNull Builder withInsecureRecipients(@NonNull List insecureRecipients) { - this.insecureRecipients = insecureRecipients; - return this; - } - - @NonNull Builder withData(@NonNull InsightsData insightsData) { - this.insightsData = insightsData; - return this; - } - - @NonNull Builder withUserAvatar(@NonNull InsightsUserAvatar userAvatar) { - this.userAvatar = userAvatar; - return this; - } - - @NonNull InsightsDashboardState build() { - return new InsightsDashboardState(this); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardViewModel.java deleted file mode 100644 index af604a9cde..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsDashboardViewModel.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.core.util.Consumer; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import org.thoughtcrime.securesms.recipients.Recipient; - -import java.util.List; - -final class InsightsDashboardViewModel extends ViewModel { - - private final MutableLiveData internalState = new MutableLiveData<>(InsightsDashboardState.builder().build()); - private final Repository repository; - - private InsightsDashboardViewModel(@NonNull Repository repository) { - this.repository = repository; - - repository.getInsightsData(data -> internalState.setValue(getNewState(b -> b.withData(data)))); - repository.getUserAvatar(avatar -> internalState.setValue(getNewState(b -> b.withUserAvatar(avatar)))); - updateInsecureRecipients(); - } - - private void updateInsecureRecipients() { - repository.getInsecureRecipients(recipients -> internalState.setValue(getNewState(b -> b.withInsecureRecipients(recipients)))); - } - - @MainThread - private InsightsDashboardState getNewState(Consumer builderConsumer) { - InsightsDashboardState.Builder builder = internalState.getValue().buildUpon(); - builderConsumer.accept(builder); - return builder.build(); - } - - @NonNull LiveData getState() { - return internalState; - } - - public void sendSmsInvite(@NonNull Recipient recipient) { - repository.sendSmsInvite(recipient, this::updateInsecureRecipients); - } - - interface Repository { - void getInsightsData(@NonNull Consumer insightsDataConsumer); - void getInsecureRecipients(@NonNull Consumer> insecureRecipientsConsumer); - void getUserAvatar(@NonNull Consumer userAvatarConsumer); - void sendSmsInvite(@NonNull Recipient recipient, Runnable onSmsMessageSent); - } - - final static class Factory implements ViewModelProvider.Factory { - - private final Repository repository; - - Factory(@NonNull Repository repository) { - this.repository = repository; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new InsightsDashboardViewModel(repository); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsData.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsData.java deleted file mode 100644 index 5fb4b5da32..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsData.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -final class InsightsData { - private final boolean hasEnoughData; - private final int percentInsecure; - - InsightsData(boolean hasEnoughData, int percentInsecure) { - this.hasEnoughData = hasEnoughData; - this.percentInsecure = percentInsecure; - } - - public boolean hasEnoughData() { - return hasEnoughData; - } - - public int getPercentInsecure() { - return percentInsecure; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsInsecureRecipientsAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsInsecureRecipientsAdapter.java deleted file mode 100644 index d36e0be26a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsInsecureRecipientsAdapter.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.core.util.Consumer; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.RecyclerView; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.AvatarImageView; -import org.thoughtcrime.securesms.mms.GlideApp; -import org.thoughtcrime.securesms.recipients.Recipient; - -import java.util.Collections; -import java.util.List; - -final class InsightsInsecureRecipientsAdapter extends RecyclerView.Adapter { - - private List data = Collections.emptyList(); - - private final Consumer onInviteClickedConsumer; - - InsightsInsecureRecipientsAdapter(Consumer onInviteClickedConsumer) { - this.onInviteClickedConsumer = onInviteClickedConsumer; - } - - public void updateData(List recipients) { - List oldData = data; - data = recipients; - - DiffUtil.calculateDiff(new DiffCallback(oldData, data)).dispatchUpdatesTo(this); - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.insights_dashboard_adapter_item, parent, false), this::handleInviteClicked); - } - - private void handleInviteClicked(@NonNull Integer position) { - onInviteClickedConsumer.accept(data.get(position)); - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - holder.bind(data.get(position)); - } - - @Override - public int getItemCount() { - return data.size(); - } - - static final class ViewHolder extends RecyclerView.ViewHolder { - - private AvatarImageView avatarImageView; - private TextView displayName; - - private ViewHolder(@NonNull View itemView, Consumer onInviteClicked) { - super(itemView); - - avatarImageView = itemView.findViewById(R.id.recipient_avatar); - displayName = itemView.findViewById(R.id.recipient_display_name); - - Button invite = itemView.findViewById(R.id.recipient_invite); - invite.setOnClickListener(v -> { - int adapterPosition = getAdapterPosition(); - - if (adapterPosition == RecyclerView.NO_POSITION) return; - - onInviteClicked.accept(adapterPosition); - }); - } - - private void bind(@NonNull Recipient recipient) { - displayName.setText(recipient.getDisplayName(itemView.getContext())); - avatarImageView.setAvatar(GlideApp.with(itemView), recipient, false); - } - } - - private static class DiffCallback extends DiffUtil.Callback { - - private final List oldData; - private final List newData; - - private DiffCallback(@NonNull List oldData, - @NonNull List newData) - { - this.oldData = oldData; - this.newData = newData; - } - - @Override - public int getOldListSize() { - return oldData.size(); - } - - @Override - public int getNewListSize() { - return newData.size(); - } - - @Override - public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { - return oldData.get(oldItemPosition).getId() == newData.get(newItemPosition).getId(); - } - - @Override - public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { - return oldData.get(oldItemPosition).equals(newData.get(newItemPosition)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsLauncher.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsLauncher.java deleted file mode 100644 index e5de5fee4d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsLauncher.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -public final class InsightsLauncher { - - private static final String MODAL_TAG = "modal.fragment"; - - public static void showInsightsModal(@NonNull Context context, @NonNull FragmentManager fragmentManager) { - if (InsightsOptOut.userHasOptedOut(context)) return; - - final Fragment fragment = fragmentManager.findFragmentByTag(MODAL_TAG); - - if (fragment == null) new InsightsModalDialogFragment().show(fragmentManager, MODAL_TAG); - } - - public static void showInsightsDashboard(@NonNull FragmentManager fragmentManager) { - new InsightsDashboardDialogFragment().show(fragmentManager, null); - } - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalDialogFragment.java deleted file mode 100644 index 5249498477..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalDialogFragment.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.animation.AnimatorSet; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.components.ArcProgressBar; -import org.thoughtcrime.securesms.components.AvatarImageView; - -public final class InsightsModalDialogFragment extends DialogFragment { - - private ArcProgressBar progress; - private TextView securePercentage; - private AvatarImageView avatarImageView; - private AnimatorSet animatorSet; - private View progressContainer; - - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - requireFragmentManager().beginTransaction() - .detach(this) - .attach(this) - .commit(); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setStyle(STYLE_NO_FRAME, R.style.Theme_Signal_Insights_Modal); - } - - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - Dialog dialog = super.onCreateDialog(savedInstanceState); - dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); - return dialog; - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.insights_modal, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - View close = view.findViewById(R.id.insights_modal_close); - Button viewInsights = view.findViewById(R.id.insights_modal_view_insights); - - progress = view.findViewById(R.id.insights_modal_progress); - securePercentage = view.findViewById(R.id.insights_modal_percent_secure); - avatarImageView = view.findViewById(R.id.insights_modal_avatar); - progressContainer = view.findViewById(R.id.insights_modal_percent_container); - - close.setOnClickListener(v -> dismiss()); - viewInsights.setOnClickListener(v -> openInsightsAndDismiss()); - - initializeViewModel(); - } - - private void initializeViewModel() { - final InsightsModalViewModel.Repository repository = new InsightsRepository(requireContext()); - final InsightsModalViewModel.Factory factory = new InsightsModalViewModel.Factory(repository); - final InsightsModalViewModel viewModel = new ViewModelProvider(this, factory).get(InsightsModalViewModel.class); - - viewModel.getState().observe(getViewLifecycleOwner(), state -> { - updateInsecurePercent(state.getData()); - updateUserAvatar(state.getUserAvatar()); - }); - } - - private void updateInsecurePercent(@Nullable InsightsData insightsData) { - if (insightsData == null) return; - - if (animatorSet == null) { - animatorSet = InsightsAnimatorSetFactory.create(insightsData.getPercentInsecure(), this::setProgressPercentage, null, this::setPercentSecureScale, null); - animatorSet.start(); - } - } - - private void setProgressPercentage(float percent) { - securePercentage.setText(String.valueOf(Math.round(percent * 100))); - progress.setProgress(percent); - } - - private void setPercentSecureScale(float scale) { - progressContainer.setScaleX(scale); - progressContainer.setScaleY(scale); - } - - private void updateUserAvatar(@Nullable InsightsUserAvatar userAvatar) { - if (userAvatar == null) avatarImageView.setImageDrawable(null); - else userAvatar.load(avatarImageView); - } - - @Override - public void onDismiss(@NonNull DialogInterface dialog) { - super.onDismiss(dialog); - InsightsOptOut.userRequestedOptOut(requireContext()); - } - - private void openInsightsAndDismiss() { - InsightsLauncher.showInsightsDashboard(requireFragmentManager()); - dismiss(); - } - - @Override - public void onDestroyView() { - if (animatorSet != null) { - animatorSet.cancel(); - animatorSet = null; - } - - super.onDestroyView(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalState.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalState.java deleted file mode 100644 index 8ce6542628..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalState.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -final class InsightsModalState { - - private final InsightsData insightsData; - private final InsightsUserAvatar userAvatar; - - private InsightsModalState(@NonNull Builder builder) { - this.insightsData = builder.insightsData; - this.userAvatar = builder.userAvatar; - } - - static @NonNull InsightsModalState.Builder builder() { - return new InsightsModalState.Builder(); - } - - @NonNull InsightsModalState.Builder buildUpon() { - return builder().withUserAvatar(userAvatar).withData(insightsData); - } - - @Nullable InsightsUserAvatar getUserAvatar() { - return userAvatar; - } - - @Nullable InsightsData getData() { - return insightsData; - } - - static final class Builder { - private InsightsData insightsData; - private InsightsUserAvatar userAvatar; - - private Builder() { - } - - @NonNull Builder withData(@NonNull InsightsData insightsData) { - this.insightsData = insightsData; - return this; - } - - @NonNull Builder withUserAvatar(@NonNull InsightsUserAvatar userAvatar) { - this.userAvatar = userAvatar; - return this; - } - - @NonNull InsightsModalState build() { - return new InsightsModalState(this); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalViewModel.java deleted file mode 100644 index ad80c40847..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsModalViewModel.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.core.util.Consumer; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -final class InsightsModalViewModel extends ViewModel { - - private final MutableLiveData internalState = new MutableLiveData<>(InsightsModalState.builder().build()); - - private InsightsModalViewModel(@NonNull Repository repository) { - repository.getInsightsData(data -> internalState.setValue(getNewState(b -> b.withData(data)))); - repository.getUserAvatar(avatar -> internalState.setValue(getNewState(b -> b.withUserAvatar(avatar)))); - } - - @MainThread - private InsightsModalState getNewState(Consumer builderConsumer) { - InsightsModalState.Builder builder = internalState.getValue().buildUpon(); - builderConsumer.accept(builder); - return builder.build(); - } - - @NonNull LiveData getState() { - return internalState; - } - - interface Repository { - void getInsightsData(Consumer insecurePercentConsumer); - void getUserAvatar(@NonNull Consumer userAvatarConsumer); - } - - final static class Factory implements ViewModelProvider.Factory { - - private final Repository repository; - - Factory(@NonNull Repository repository) { - this.repository = repository; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new InsightsModalViewModel(repository); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsOptOut.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsOptOut.java deleted file mode 100644 index c3d90f227f..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsOptOut.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -public final class InsightsOptOut { - private static final String INSIGHTS_OPT_OUT_PREFERENCE = "insights.opt.out"; - - private InsightsOptOut() { - } - - static boolean userHasOptedOut(@NonNull Context context) { - return TextSecurePreferences.getBooleanPreference(context, INSIGHTS_OPT_OUT_PREFERENCE, false); - } - - public static void userRequestedOptOut(@NonNull Context context) { - TextSecurePreferences.setBooleanPreference(context, INSIGHTS_OPT_OUT_PREFERENCE, true); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java deleted file mode 100644 index e6ef34e8b3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsRepository.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.core.util.Consumer; - -import com.annimon.stream.Stream; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto; -import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto; -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.RecipientTable; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.mms.OutgoingMessage; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.util.Util; -import org.signal.core.util.concurrent.SimpleTask; - -import java.util.List; -import java.util.Optional; - -public class InsightsRepository implements InsightsDashboardViewModel.Repository, InsightsModalViewModel.Repository { - - private final Context context; - - public InsightsRepository(Context context) { - this.context = context.getApplicationContext(); - } - - @Override - public void getInsightsData(@NonNull Consumer insightsDataConsumer) { - SimpleTask.run(() -> { - MessageTable messageTable = SignalDatabase.messages(); - int insecure = messageTable.getInsecureMessageCountForInsights(); - int secure = messageTable.getSecureMessageCountForInsights(); - - if (insecure + secure == 0) { - return new InsightsData(false, 0); - } else { - return new InsightsData(true, Util.clamp((int) Math.ceil((insecure * 100f) / (insecure + secure)), 0, 100)); - } - }, insightsDataConsumer::accept); - } - - @Override - public void getInsecureRecipients(@NonNull Consumer> insecureRecipientsConsumer) { - SimpleTask.run(() -> { - RecipientTable recipientTable = SignalDatabase.recipients(); - List unregisteredRecipients = recipientTable.getUninvitedRecipientsForInsights(); - - return Stream.of(unregisteredRecipients) - .map(Recipient::resolved) - .toList(); - }, - insecureRecipientsConsumer::accept); - } - - @Override - public void getUserAvatar(@NonNull Consumer avatarConsumer) { - SimpleTask.run(() -> { - Recipient self = Recipient.self().resolve(); - String name = Optional.of(self.getDisplayName(context)).orElse(""); - - return new InsightsUserAvatar(new ProfileContactPhoto(self), - self.getAvatarColor(), - new GeneratedContactPhoto(name, R.drawable.ic_profile_outline_40)); - }, avatarConsumer::accept); - } - - @Override - public void sendSmsInvite(@NonNull Recipient recipient, Runnable onSmsMessageSent) { - SimpleTask.run(() -> { - Recipient resolved = recipient.resolve(); - int subscriptionId = resolved.getDefaultSubscriptionId().orElse(-1); - String message = context.getString(R.string.InviteActivity_lets_switch_to_signal, context.getString(R.string.install_url)); - - MessageSender.send(context, OutgoingMessage.sms(resolved, message, subscriptionId), -1L, MessageSender.SendType.SMS, null, null); - - RecipientTable database = SignalDatabase.recipients(); - database.setHasSentInvite(recipient.getId()); - - return null; - }, v -> onSmsMessageSent.run()); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsUserAvatar.java b/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsUserAvatar.java deleted file mode 100644 index 763e457612..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/insights/InsightsUserAvatar.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.thoughtcrime.securesms.insights; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.widget.ImageView; - -import androidx.annotation.NonNull; - -import com.bumptech.glide.load.engine.DiskCacheStrategy; - -import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; -import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto; -import org.thoughtcrime.securesms.conversation.colors.AvatarColor; -import org.thoughtcrime.securesms.mms.GlideApp; - -class InsightsUserAvatar { - private final ProfileContactPhoto profileContactPhoto; - private final AvatarColor fallbackColor; - private final FallbackContactPhoto fallbackContactPhoto; - - InsightsUserAvatar(@NonNull ProfileContactPhoto profileContactPhoto, @NonNull AvatarColor fallbackColor, @NonNull FallbackContactPhoto fallbackContactPhoto) { - this.profileContactPhoto = profileContactPhoto; - this.fallbackColor = fallbackColor; - this.fallbackContactPhoto = fallbackContactPhoto; - } - - private Drawable fallbackDrawable(@NonNull Context context) { - return fallbackContactPhoto.asDrawable(context, fallbackColor); - } - - void load(ImageView into) { - GlideApp.with(into) - .load(profileContactPhoto) - .error(fallbackDrawable(into.getContext())) - .circleCrop() - .diskCacheStrategy(DiskCacheStrategy.ALL) - .into(into); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java deleted file mode 100644 index d78759cd0b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderModel.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.thoughtcrime.securesms.invites; - -import android.content.Context; - -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.annotation.WorkerThread; - -import org.thoughtcrime.securesms.components.reminder.FirstInviteReminder; -import org.thoughtcrime.securesms.components.reminder.Reminder; -import org.thoughtcrime.securesms.components.reminder.SecondInviteReminder; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.database.ThreadTable; -import org.thoughtcrime.securesms.recipients.LiveRecipient; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.signal.core.util.concurrent.SimpleTask; - -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; - -public final class InviteReminderModel { - - private static final int FIRST_INVITE_REMINDER_MESSAGE_THRESHOLD = 10; - private static final int SECOND_INVITE_REMINDER_MESSAGE_THRESHOLD = 500; - - private final Context context; - private final Repository repository; - private final AtomicReference reminderInfo = new AtomicReference<>(); - - public InviteReminderModel(@NonNull Context context, @NonNull Repository repository) { - this.context = context; - this.repository = repository; - } - - @MainThread - public void loadReminder(LiveRecipient liveRecipient, Runnable reminderCheckComplete) { - SimpleTask.run(() -> createReminderInfo(liveRecipient.resolve()), result -> { - reminderInfo.set(result); - reminderCheckComplete.run(); - }); - } - - @WorkerThread - private @NonNull ReminderInfo createReminderInfo(Recipient recipient) { - Recipient resolved = recipient.resolve(); - - if (resolved.isRegistered() || resolved.isGroup() || resolved.hasSeenSecondInviteReminder()) { - return new NoReminderInfo(); - } - - ThreadTable threadTable = SignalDatabase.threads(); - Long threadId = threadTable.getThreadIdFor(recipient.getId()); - - if (threadId != null) { - int conversationCount = SignalDatabase.messages().getInsecureMessageSentCount(threadId); - - if (conversationCount >= SECOND_INVITE_REMINDER_MESSAGE_THRESHOLD && !resolved.hasSeenSecondInviteReminder()) { - return new SecondInviteReminderInfo(context, resolved, repository, repository.getPercentOfInsecureMessages(conversationCount)); - } else if (conversationCount >= FIRST_INVITE_REMINDER_MESSAGE_THRESHOLD && !resolved.hasSeenFirstInviteReminder()) { - return new FirstInviteReminderInfo(resolved, repository, repository.getPercentOfInsecureMessages(conversationCount)); - } - } - return new NoReminderInfo(); - } - - public @NonNull Optional getReminder() { - ReminderInfo info = reminderInfo.get(); - if (info == null) return Optional.empty(); - else return Optional.ofNullable(info.reminder); - } - - public void dismissReminder() { - final ReminderInfo info = reminderInfo.getAndSet(null); - - SimpleTask.run(() -> { - info.dismiss(); - return null; - }, (v) -> {}); - } - - interface Repository { - void setHasSeenFirstInviteReminder(Recipient recipient); - void setHasSeenSecondInviteReminder(Recipient recipient); - int getPercentOfInsecureMessages(int insecureCount); - } - - private static abstract class ReminderInfo { - - private final Reminder reminder; - - ReminderInfo(Reminder reminder) { - this.reminder = reminder; - } - - @WorkerThread - void dismiss() { - } - } - - private static class NoReminderInfo extends ReminderInfo { - private NoReminderInfo() { - super(null); - } - } - - private class FirstInviteReminderInfo extends ReminderInfo { - - private final Repository repository; - private final Recipient recipient; - - private FirstInviteReminderInfo(@NonNull Recipient recipient, @NonNull Repository repository, int percentInsecure) { - super(new FirstInviteReminder(percentInsecure)); - - this.recipient = recipient; - this.repository = repository; - } - - @Override - @WorkerThread - void dismiss() { - repository.setHasSeenFirstInviteReminder(recipient); - } - } - - private static class SecondInviteReminderInfo extends ReminderInfo { - - private final Repository repository; - private final Recipient recipient; - - private SecondInviteReminderInfo(@NonNull Context context, @NonNull Recipient recipient, @NonNull Repository repository, int percentInsecure) { - super(new SecondInviteReminder(context, recipient, percentInsecure)); - - this.repository = repository; - this.recipient = recipient; - } - - @Override - @WorkerThread - void dismiss() { - repository.setHasSeenSecondInviteReminder(recipient); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java b/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java deleted file mode 100644 index 82e793b942..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/invites/InviteReminderRepository.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.thoughtcrime.securesms.invites; - -import android.content.Context; - -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.RecipientTable; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.recipients.Recipient; - -public final class InviteReminderRepository implements InviteReminderModel.Repository { - - private final Context context; - - public InviteReminderRepository(Context context) { - this.context = context; - } - - @Override - public void setHasSeenFirstInviteReminder(Recipient recipient) { - RecipientTable recipientTable = SignalDatabase.recipients(); - recipientTable.setSeenFirstInviteReminder(recipient.getId()); - } - - @Override - public void setHasSeenSecondInviteReminder(Recipient recipient) { - RecipientTable recipientTable = SignalDatabase.recipients(); - recipientTable.setSeenSecondInviteReminder(recipient.getId()); - } - - @Override - public int getPercentOfInsecureMessages(int insecureCount) { - MessageTable messageTable = SignalDatabase.messages(); - int insecure = messageTable.getInsecureMessageCountForInsights(); - int secure = messageTable.getSecureMessageCountForInsights(); - - if (insecure + secure == 0) return 0; - return Math.round(100f * (insecureCount / (float) (insecure + secure))); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java index 20c482f62f..b564850518 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java @@ -91,7 +91,7 @@ public final class MmsSendJob extends SendJob { } List compressionJobs = Stream.of(message.getAttachments()) - .map(a -> (Job) AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, true, message.getSubscriptionId())) + .map(a -> (Job) AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, true, -1)) .toList(); MmsSendJob sendJob = new MmsSendJob(messageId); @@ -139,7 +139,7 @@ public final class MmsSendJob extends SendJob { validateDestinations(message, pdu); final byte[] pduBytes = getPduBytes(pdu); - final SendConf sendConf = new CompatMmsConnection(context).send(pduBytes, message.getSubscriptionId()); + final SendConf sendConf = new CompatMmsConnection(context).send(pduBytes, -1); final MmsSendResult result = getSendResult(sendConf, pdu); database.markAsSent(messageId, false); @@ -231,7 +231,7 @@ public final class MmsSendJob extends SendJob { { SendReq req = new SendReq(); String lineNumber = getMyNumber(context); - MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(message.getSubscriptionId()); + MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(-1); List scaledAttachments = message.getAttachments(); if (!TextUtils.isEmpty(lineNumber)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java index 6eb05b2fdf..5fba6a5c8e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java @@ -108,7 +108,7 @@ public class TypingSendJob extends BaseJob { return; } - if (!recipient.isRegistered() || recipient.isForceSmsSelection()) { + if (!recipient.isRegistered()) { Log.w(TAG, "Not sending typing indicators to non-Signal recipients."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java index e30e324507..53524b5ac7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java @@ -414,8 +414,6 @@ public class MessageContentProcessor { warn(String.valueOf(content.getTimestamp()), "Got unrecognized message!"); } - resetRecipientToPush(senderRecipient); - if (pending != null) { warn(content.getTimestamp(), "Pending retry was processed. Deleting."); ApplicationDependencies.getPendingRetryReceiptCache().delete(pending); @@ -2219,7 +2217,6 @@ public class MessageContentProcessor { body, Collections.emptyList(), message.getTimestamp(), - -1, expiresInMillis, false, ThreadTable.DistributionTypes.DEFAULT, @@ -2342,7 +2339,6 @@ public class MessageContentProcessor { textStoryBody, pendingAttachments, sentAtTimestamp, - -1, 0, false, ThreadTable.DistributionTypes.DEFAULT, @@ -2442,7 +2438,6 @@ public class MessageContentProcessor { message.getDataMessage().get().getBody().orElse(null), syncAttachments, message.getTimestamp(), - -1, TimeUnit.SECONDS.toMillis(message.getDataMessage().get().getExpiresInSeconds()), viewOnce, ThreadTable.DistributionTypes.DEFAULT, @@ -2657,7 +2652,6 @@ public class MessageContentProcessor { new SlideDeck(), body, message.getTimestamp(), - -1, expiresInMillis, false, StoryType.NONE, @@ -3403,12 +3397,6 @@ public class MessageContentProcessor { return false; } - private void resetRecipientToPush(@NonNull Recipient recipient) { - if (recipient.isForceSmsSelection()) { - SignalDatabase.recipients().setForceSmsSelection(recipient.getId(), false); - } - } - private void forceStickerDownloadIfNecessary(long messageId, List stickerAttachments) { if (stickerAttachments.isEmpty()) return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessorV2.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessorV2.kt index deadda5677..42e13f1de9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessorV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessorV2.kt @@ -284,12 +284,6 @@ open class MessageContentProcessorV2(private val context: Context) { null } } - - private fun resetRecipientToPush(recipient: Recipient) { - if (recipient.isForceSmsSelection) { - SignalDatabase.recipients.setForceSmsSelection(recipient.id, false) - } - } } /** @@ -425,8 +419,6 @@ open class MessageContentProcessorV2(private val context: Context) { } } - resetRecipientToPush(senderRecipient) - if (pending != null) { warn(envelope.timestamp, "Pending retry was processed. Deleting.") ApplicationDependencies.getPendingRetryReceiptCache().delete(pending) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMessage.kt b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMessage.kt index 838af0a159..dcce6f0f83 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMessage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMessage.kt @@ -23,7 +23,6 @@ data class OutgoingMessage( val sentTimeMillis: Long, val body: String = "", val distributionType: Int = ThreadTable.DistributionTypes.DEFAULT, - val subscriptionId: Int = -1, val expiresIn: Long = 0L, val isViewOnce: Boolean = false, val outgoingQuote: QuoteModel? = null, @@ -66,7 +65,6 @@ data class OutgoingMessage( body: String? = "", attachments: List = emptyList(), timestamp: Long, - subscriptionId: Int = -1, expiresIn: Long = 0L, viewOnce: Boolean = false, distributionType: Int = ThreadTable.DistributionTypes.DEFAULT, @@ -89,7 +87,6 @@ data class OutgoingMessage( body = body ?: "", attachments = attachments, sentTimeMillis = timestamp, - subscriptionId = subscriptionId, expiresIn = expiresIn, isViewOnce = viewOnce, distributionType = distributionType, @@ -117,7 +114,6 @@ data class OutgoingMessage( slideDeck: SlideDeck, body: String? = "", timestamp: Long, - subscriptionId: Int = -1, expiresIn: Long = 0L, viewOnce: Boolean = false, storyType: StoryType = StoryType.NONE, @@ -131,7 +127,6 @@ data class OutgoingMessage( body = buildMessage(slideDeck, body ?: ""), attachments = slideDeck.asAttachments(), sentTimeMillis = timestamp, - subscriptionId = subscriptionId, expiresIn = expiresIn, isViewOnce = viewOnce, storyType = storyType, @@ -142,6 +137,8 @@ data class OutgoingMessage( sharedContacts = contacts ) + val subscriptionId = -1 + fun withExpiry(expiresIn: Long): OutgoingMessage { return copy(expiresIn = expiresIn) } @@ -172,12 +169,11 @@ data class OutgoingMessage( * A literal, insecure SMS message. */ @JvmStatic - fun sms(threadRecipient: Recipient, body: String, subscriptionId: Int): OutgoingMessage { + fun sms(threadRecipient: Recipient, body: String): OutgoingMessage { return OutgoingMessage( threadRecipient = threadRecipient, sentTimeMillis = System.currentTimeMillis(), body = body, - subscriptionId = subscriptionId, isSecure = false ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java index 02ef6c5e5a..cdf5022d9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java @@ -76,7 +76,6 @@ public class RemoteReplyReceiver extends BroadcastReceiver { long threadId; Recipient recipient = Recipient.resolved(recipientId); - int subscriptionId = recipient.getDefaultSubscriptionId().orElse(-1); long expiresIn = TimeUnit.SECONDS.toMillis(recipient.getExpiresInSeconds()); ParentStoryId parentStoryId = groupStoryId != Long.MIN_VALUE ? ParentStoryId.deserialize(groupStoryId) : null; @@ -86,7 +85,6 @@ public class RemoteReplyReceiver extends BroadcastReceiver { responseText.toString(), new LinkedList<>(), System.currentTimeMillis(), - subscriptionId, expiresIn, false, 0, @@ -112,11 +110,6 @@ public class RemoteReplyReceiver extends BroadcastReceiver { threadId = MessageSender.send(context, reply, -1, MessageSender.SendType.SIGNAL, null, null); break; } - case UnsecuredSmsMessage: { - OutgoingMessage reply = OutgoingMessage.sms(recipient, responseText.toString(), subscriptionId); - threadId = MessageSender.send(context, reply, -1, MessageSender.SendType.SMS, null, null); - break; - } default: throw new AssertionError("Unknown Reply method"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/ReplyMethod.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/ReplyMethod.java index c755ddf1d4..ce797cd796 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/ReplyMethod.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/ReplyMethod.java @@ -1,26 +1,19 @@ package org.thoughtcrime.securesms.notifications; -import android.content.Context; - import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.database.RecipientTable; -import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; public enum ReplyMethod { GroupMessage, - SecureMessage, - UnsecuredSmsMessage; + SecureMessage; - public static @NonNull ReplyMethod forRecipient(Context context, Recipient recipient) { + public static @NonNull ReplyMethod forRecipient(Recipient recipient) { if (recipient.isGroup()) { return ReplyMethod.GroupMessage; - } else if (SignalStore.account().isRegistered() && recipient.getRegistered() == RecipientTable.RegisteredState.REGISTERED && !recipient.isForceSmsSelection()) { - return ReplyMethod.SecureMessage; } else { - return ReplyMethod.UnsecuredSmsMessage; + return ReplyMethod.SecureMessage; } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt index 61ecf33c55..0d9f2f18c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt @@ -123,7 +123,7 @@ sealed class NotificationBuilder(protected val context: Context) { } } - addActions(ReplyMethod.forRecipient(context, conversation.recipient), conversation) + addActions(ReplyMethod.forRecipient(conversation.recipient), conversation) } } @@ -504,6 +504,5 @@ private fun ReplyMethod.toLongDescription(): Int { return when (this) { ReplyMethod.GroupMessage -> R.string.MessageNotifier_reply ReplyMethod.SecureMessage -> R.string.MessageNotifier_signal_message - ReplyMethod.UnsecuredSmsMessage -> R.string.MessageNotifier_unsecured_sms } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index f35bf4cb23..233be951c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -104,7 +104,6 @@ public class Recipient { private final VibrateState callVibrate; private final Uri messageRingtone; private final Uri callRingtone; - private final Optional defaultSubscriptionId; private final int expireMessages; private final RegisteredState registered; private final byte[] profileKey; @@ -121,9 +120,7 @@ public class Recipient { private final long lastProfileFetch; private final String notificationChannel; private final UnidentifiedAccessMode unidentifiedAccessMode; - private final boolean forceSmsSelection; private final RecipientRecord.Capabilities capabilities; - private final InsightsBannerTier insightsBannerTier; private final byte[] storageId; private final MentionSetting mentionSetting; private final ChatWallpaper wallpaper; @@ -392,8 +389,6 @@ public class Recipient { this.callVibrate = VibrateState.DEFAULT; this.messageRingtone = null; this.callRingtone = null; - this.insightsBannerTier = InsightsBannerTier.TIER_TWO; - this.defaultSubscriptionId = Optional.empty(); this.expireMessages = 0; this.registered = RegisteredState.UNKNOWN; this.profileKey = null; @@ -410,7 +405,6 @@ public class Recipient { this.lastProfileFetch = 0; this.notificationChannel = null; this.unidentifiedAccessMode = UnidentifiedAccessMode.DISABLED; - this.forceSmsSelection = false; this.capabilities = RecipientRecord.Capabilities.UNKNOWN; this.storageId = null; this.mentionSetting = MentionSetting.ALWAYS_NOTIFY; @@ -450,8 +444,6 @@ public class Recipient { this.callVibrate = details.callVibrateState; this.messageRingtone = details.messageRingtone; this.callRingtone = details.callRingtone; - this.insightsBannerTier = details.insightsBannerTier; - this.defaultSubscriptionId = details.defaultSubscriptionId; this.expireMessages = details.expireMessages; this.registered = details.registered; this.profileKey = details.profileKey; @@ -468,7 +460,6 @@ public class Recipient { this.lastProfileFetch = details.lastProfileFetch; this.notificationChannel = details.notificationChannel; this.unidentifiedAccessMode = details.unidentifiedAccessMode; - this.forceSmsSelection = details.forceSmsSelection; this.capabilities = details.capabilities; this.storageId = details.storageId; this.mentionSetting = details.mentionSetting; @@ -840,10 +831,6 @@ public class Recipient { return requireSmsAddress(); } - public Optional getDefaultSubscriptionId() { - return defaultSubscriptionId; - } - public @NonNull ProfileName getProfileName() { return signalProfileName; } @@ -1029,14 +1016,6 @@ public class Recipient { return expireMessages; } - public boolean hasSeenFirstInviteReminder() { - return insightsBannerTier.seen(InsightsBannerTier.TIER_ONE); - } - - public boolean hasSeenSecondInviteReminder() { - return insightsBannerTier.seen(InsightsBannerTier.TIER_TWO); - } - public @NonNull RegisteredState getRegistered() { if (isPushGroup() || isDistributionList()) { return RegisteredState.REGISTERED; @@ -1063,10 +1042,6 @@ public class Recipient { return !NotificationChannels.supported() ? null : notificationChannel; } - public boolean isForceSmsSelection() { - return forceSmsSelection; - } - public @NonNull Capability getStoriesCapability() { return capabilities.getStoriesCapability(); } @@ -1353,7 +1328,6 @@ public class Recipient { Objects.equals(profileAvatarFileDetails, other.profileAvatarFileDetails) && profileSharing == other.profileSharing && isHidden == other.isHidden && - forceSmsSelection == other.forceSmsSelection && Objects.equals(aci, other.aci) && Objects.equals(username, other.username) && Objects.equals(e164, other.e164) && @@ -1365,7 +1339,6 @@ public class Recipient { callVibrate == other.callVibrate && Objects.equals(messageRingtone, other.messageRingtone) && Objects.equals(callRingtone, other.callRingtone) && - Objects.equals(defaultSubscriptionId, other.defaultSubscriptionId) && registered == other.registered && Arrays.equals(profileKey, other.profileKey) && Objects.equals(expiringProfileKeyCredential, other.expiringProfileKeyCredential) && @@ -1378,7 +1351,6 @@ public class Recipient { Objects.equals(profileAvatar, other.profileAvatar) && Objects.equals(notificationChannel, other.notificationChannel) && unidentifiedAccessMode == other.unidentifiedAccessMode && - insightsBannerTier == other.insightsBannerTier && Arrays.equals(storageId, other.storageId) && mentionSetting == other.mentionSetting && Objects.equals(wallpaper, other.wallpaper) && diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java index 26b60b426c..a9dfb8ba80 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -58,7 +58,6 @@ public class RecipientDetails { final int expireMessages; final List participantIds; final ProfileName profileName; - final Optional defaultSubscriptionId; final RegisteredState registered; final byte[] profileKey; final ExpiringProfileKeyCredential expiringProfileKeyCredential; @@ -72,9 +71,7 @@ public class RecipientDetails { final boolean isSelf; final String notificationChannel; final UnidentifiedAccessMode unidentifiedAccessMode; - final boolean forceSmsSelection; final RecipientRecord.Capabilities capabilities; - final InsightsBannerTier insightsBannerTier; final byte[] storageId; final MentionSetting mentionSetting; final ChatWallpaper wallpaper; @@ -125,7 +122,6 @@ public class RecipientDetails { this.participantIds = participantIds == null ? new LinkedList<>() : participantIds; this.isActiveGroup = isActiveGroup; this.profileName = record.getProfileName(); - this.defaultSubscriptionId = record.getDefaultSubscriptionId(); this.registered = registeredState; this.profileKey = record.getProfileKey(); this.expiringProfileKeyCredential = record.getExpiringProfileKeyCredential(); @@ -138,9 +134,7 @@ public class RecipientDetails { this.isSelf = isSelf; this.notificationChannel = record.getNotificationChannel(); this.unidentifiedAccessMode = record.getUnidentifiedAccessMode(); - this.forceSmsSelection = record.isForceSmsSelection(); this.capabilities = record.getCapabilities(); - this.insightsBannerTier = record.getInsightsBannerTier(); this.storageId = record.getStorageId(); this.mentionSetting = record.getMentionSetting(); this.wallpaper = record.getWallpaper(); @@ -181,8 +175,6 @@ public class RecipientDetails { this.expireMessages = 0; this.participantIds = new LinkedList<>(); this.profileName = ProfileName.EMPTY; - this.insightsBannerTier = InsightsBannerTier.TIER_TWO; - this.defaultSubscriptionId = Optional.empty(); this.registered = RegisteredState.UNKNOWN; this.profileKey = null; this.expiringProfileKeyCredential = null; @@ -195,7 +187,6 @@ public class RecipientDetails { this.isSelf = false; this.notificationChannel = null; this.unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN; - this.forceSmsSelection = false; this.groupName = null; this.capabilities = RecipientRecord.Capabilities.UNKNOWN; this.storageId = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index be60ca3e85..d5e2621791 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -297,7 +297,6 @@ public class RecipientUtil { threadRecipient.isProfileSharing() || threadRecipient.isSystemContact() || !threadRecipient.isRegistered() || - threadRecipient.isForceSmsSelection() || threadRecipient.isHidden(); } @@ -346,7 +345,6 @@ public class RecipientUtil { threadRecipient.isSelf() || threadRecipient.isProfileSharing() || threadRecipient.isSystemContact() || - threadRecipient.isForceSmsSelection() || !threadRecipient.isRegistered() || (!threadRecipient.isHidden() && ( hasSentMessageInThread(threadId) || diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java b/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java index 8233a4ed20..445b9f0f08 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java @@ -46,11 +46,10 @@ public class QuickResponseService extends IntentService { number = URLDecoder.decode(number); } - Recipient recipient = Recipient.external(this, number); - int subscriptionId = recipient.getDefaultSubscriptionId().orElse(-1); + Recipient recipient = Recipient.external(this, number); if (!TextUtils.isEmpty(content)) { - MessageSender.send(this, OutgoingMessage.sms(recipient, content, subscriptionId), -1, MessageSender.SendType.SIGNAL, null, null); + MessageSender.send(this, OutgoingMessage.sms(recipient, content), -1, MessageSender.SendType.SIGNAL, null, null); } } catch (URISyntaxException e) { Toast.makeText(this, R.string.QuickResponseService_problem_sending_message, Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java index ac2b1439b1..bb4742d515 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java @@ -108,9 +108,7 @@ public final class MultiShareSender { long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient); List mentions = getValidMentionsForRecipient(recipient, multiShareArgs.getMentions()); - MessageSendType sendType = resolveTransportOption(context, recipient); - boolean forceSms = recipient.isForceSmsSelection() && sendType.usesSmsTransport(); - int subscriptionId = sendType.getSimSubscriptionIdOr(-1); + MessageSendType sendType = MessageSendType.SignalMessageSendType.INSTANCE; long expiresIn = TimeUnit.SECONDS.toMillis(recipient.getExpiresInSeconds()); List contacts = multiShareArgs.getSharedContacts(); boolean needsSplit = !sendType.usesSmsTransport() && @@ -139,10 +137,8 @@ public final class MultiShareSender { slideDeck, sendType, threadId, - forceSms, expiresIn, multiShareArgs.isViewOnce(), - subscriptionId, mentions, recipientSearchKey.isStory(), sentTimestamp, @@ -154,7 +150,7 @@ public final class MultiShareSender { } else if (recipientSearchKey.isStory()) { results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.INVALID_SHARE_TO_STORY)); } else { - sendTextMessage(context, multiShareArgs, recipient, threadId, forceSms, expiresIn, subscriptionId); + sendTextMessage(context, multiShareArgs, recipient, threadId, expiresIn); results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.SUCCESS)); } @@ -179,39 +175,14 @@ public final class MultiShareSender { return new MultiShareSendResultCollection(results); } - public static @NonNull MessageSendType getWorstTransportOption(@NonNull Context context, @NonNull Set recipientSearchKeys) { - for (ContactSearchKey.RecipientSearchKey recipientSearchKey : recipientSearchKeys) { - MessageSendType type = resolveTransportOption(context, Recipient.resolved(recipientSearchKey.getRecipientId()).isForceSmsSelection() && !recipientSearchKey.isStory()); - if (type.usesSmsTransport()) { - return type; - } - } - - return MessageSendType.SignalMessageSendType.INSTANCE; - } - - private static @NonNull MessageSendType resolveTransportOption(@NonNull Context context, @NonNull Recipient recipient) { - return resolveTransportOption(context, !recipient.isDistributionList() && (recipient.isForceSmsSelection() || !recipient.isRegistered())); - } - - public static @NonNull MessageSendType resolveTransportOption(@NonNull Context context, boolean forceSms) { - if (forceSms && SignalStore.misc().getSmsExportPhase().allowSmsFeatures()) { - return MessageSendType.getFirstForTransport(context, false, MessageSendType.TransportType.SMS); - } else { - return MessageSendType.SignalMessageSendType.INSTANCE; - } - } - private static void sendMediaMessageOrCollectStoryToBatch(@NonNull Context context, @NonNull MultiShareArgs multiShareArgs, @NonNull Recipient recipient, @NonNull SlideDeck slideDeck, @NonNull MessageSendType sendType, long threadId, - boolean forceSms, long expiresIn, boolean isViewOnce, - int subscriptionId, @NonNull List validatedMentions, boolean isStory, @NonNull MultiShareTimestampProvider sentTimestamps, @@ -221,7 +192,7 @@ public final class MultiShareSender { @NonNull List contacts) { String body = multiShareArgs.getDraftText(); - if (sendType.usesSignalTransport() && !forceSms && body != null) { + if (sendType.usesSignalTransport() && body != null) { MessageUtil.SplitResult splitMessage = MessageUtil.getSplitMessage(context, body, sendType.calculateCharacters(body).maxPrimaryMessageSize); body = splitMessage.getBody(); @@ -249,7 +220,6 @@ public final class MultiShareSender { new SlideDeck(), body, sentTimestamps.getMillis(0), - subscriptionId, 0L, false, storyType.toTextStoryType(), @@ -289,7 +259,6 @@ public final class MultiShareSender { singletonDeck, body, sentTimestamps.getMillis(i), - subscriptionId, 0L, false, storyType, @@ -307,7 +276,6 @@ public final class MultiShareSender { slideDeck, body, sentTimestamps.getMillis(0), - subscriptionId, expiresIn, isViewOnce, StoryType.NONE, @@ -322,7 +290,7 @@ public final class MultiShareSender { if (isStory) { storiesToBatchSend.addAll(outgoingMessages); - } else if (shouldSendAsPush(recipient, forceSms)) { + } else if (shouldSendAsPush(recipient)) { for (final OutgoingMessage outgoingMessage : outgoingMessages) { MessageSender.send(context, outgoingMessage.makeSecure(), threadId, SendType.SIGNAL, null, null); } @@ -399,20 +367,18 @@ public final class MultiShareSender { @NonNull MultiShareArgs multiShareArgs, @NonNull Recipient recipient, long threadId, - boolean forceSms, - long expiresIn, - int subscriptionId) + long expiresIn) { String body = multiShareArgs.getDraftText() == null ? "" : multiShareArgs.getDraftText(); OutgoingMessage outgoingMessage; - if (shouldSendAsPush(recipient, forceSms)) { + if (shouldSendAsPush(recipient)) { outgoingMessage = OutgoingMessage.text(recipient, body, expiresIn, System.currentTimeMillis(), multiShareArgs.getBodyRanges()); } else { - outgoingMessage = OutgoingMessage.sms(recipient, body, subscriptionId); + outgoingMessage = OutgoingMessage.sms(recipient, body); } - MessageSender.send(context, outgoingMessage, threadId, forceSms ? SendType.SMS : SendType.SIGNAL, null, null); + MessageSender.send(context, outgoingMessage, threadId, SendType.SIGNAL, null, null); } private static @NonNull OutgoingMessage generateTextStory(@NonNull Context context, @@ -458,10 +424,10 @@ public final class MultiShareSender { return trimmed.replace(linkPreview.getUrl(), "").trim(); } - private static boolean shouldSendAsPush(@NonNull Recipient recipient, boolean forceSms) { + private static boolean shouldSendAsPush(@NonNull Recipient recipient) { return recipient.isDistributionList() || recipient.isServiceIdOnly() || - (recipient.isRegistered() && !forceSms); + recipient.isRegistered(); } private static @NonNull SlideDeck buildSlideDeck(@NonNull Context context, @NonNull MultiShareArgs multiShareArgs) throws SlideNotFoundException { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java index 08345e295e..86df41c31a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java @@ -93,7 +93,7 @@ public class ShareInterstitialActivity extends PassphraseRequiredActivity { return false; } - return !recipient.isRegistered() || recipient.isForceSmsSelection(); + return !recipient.isRegistered(); }); if (hasSms) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareActivity.kt index 09e383c5f4..77b175252d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareActivity.kt @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActivity import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey import org.thoughtcrime.securesms.conversation.ConversationIntents +import org.thoughtcrime.securesms.conversation.MessageSendType import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFullScreenDialogFragment @@ -271,7 +272,7 @@ class ShareActivity : PassphraseRequiredActivity(), MultiselectForwardFragment.C val intent = share( this, - MultiShareSender.getWorstTransportOption(this, multiShareArgs.recipientSearchKeys), + MessageSendType.SignalMessageSendType, media, multiShareArgs.recipientSearchKeys.toList(), multiShareArgs.draftText, diff --git a/app/src/main/res/layout/insights_dashboard.xml b/app/src/main/res/layout/insights_dashboard.xml deleted file mode 100644 index 515c4131c4..0000000000 --- a/app/src/main/res/layout/insights_dashboard.xml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/insights_dashboard_adapter_item.xml b/app/src/main/res/layout/insights_dashboard_adapter_item.xml deleted file mode 100644 index 95b7bc57d6..0000000000 --- a/app/src/main/res/layout/insights_dashboard_adapter_item.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/insights_modal.xml b/app/src/main/res/layout/insights_modal.xml deleted file mode 100644 index 55476fb53d..0000000000 --- a/app/src/main/res/layout/insights_modal.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -