Skip to content

Commit

Permalink
Support for dual-sim SMS/MMS functionality
Browse files Browse the repository at this point in the history
Allow source selection for sending SMS/MMS, and display the
SIM that received SMS/MMS.

Fixes #555
Closes #5199
// FREEBIE
  • Loading branch information
moxie0 committed Feb 10, 2016
1 parent c1106d9 commit 6da86e4
Show file tree
Hide file tree
Showing 53 changed files with 727 additions and 281 deletions.
20 changes: 19 additions & 1 deletion res/layout/conversation_item_received.xml
Expand Up @@ -113,6 +113,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingTop="2dp"
android:paddingRight="4dp"
android:paddingEnd="4dp"
android:src="?menu_lock_icon_small"
android:contentDescription="@string/conversation_item__secure_message_description"
android:visibility="gone"
Expand All @@ -126,6 +128,19 @@
android:visibility="gone"/>

<TextView android:id="@+id/conversation_item_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:paddingTop="1dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?conversation_item_received_text_secondary_color"
android:textSize="@dimen/conversation_item_date_text_size"
android:fontFamily="sans-serif-light"
android:autoLink="none"
android:linksClickable="false"
tools:text="Now"/>

<TextView android:id="@+id/sim_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
Expand All @@ -137,7 +152,10 @@
android:textSize="@dimen/conversation_item_date_text_size"
android:fontFamily="sans-serif-light"
android:autoLink="none"
android:linksClickable="false" />
android:linksClickable="false"
android:visibility="gone"
tools:visibility="visible"
tools:text="from SIM1"/>
</LinearLayout>
</LinearLayout>

Expand Down
19 changes: 19 additions & 0 deletions res/layout/conversation_item_sent.xml
Expand Up @@ -125,6 +125,25 @@
android:paddingBottom="2dp"
tools:text="30 mins" />

<TextView android:id="@+id/sim_info"
android:autoLink="none"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="15sp"
android:linksClickable="false"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_gravity="right"
android:fontFamily="sans-serif-light"
android:textColor="?conversation_item_sent_text_secondary_color"
android:textSize="@dimen/conversation_item_date_text_size"
android:paddingTop="1dip"
android:paddingBottom="2dp"
android:paddingLeft="4dp"
android:paddingStart="4dp"
android:visibility="gone"
tools:visibility="visible"
tools:text="to SIM1"/>

<org.thoughtcrime.securesms.components.DeliveryStatusView
android:id="@+id/delivery_status"
android:layout_width="20dp"
Expand Down
32 changes: 25 additions & 7 deletions res/layout/transport_selection_list_item.xml
Expand Up @@ -8,6 +8,7 @@
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">

<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Expand All @@ -16,11 +17,28 @@
android:contentDescription="@string/transport_selection_list_item__transport_icon"
tools:src="@drawable/ic_send_push_white_24dp"
tools:backgroundTint="@color/textsecure_primary" />
<TextView android:id="@+id/text"
android:paddingLeft="10dp"
android:fontFamily="sans-serif-light"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="TextSecure" />

<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="10dp">

<TextView android:id="@+id/text"
android:fontFamily="sans-serif-light"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="TextSecure" />

<TextView android:id="@+id/subtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:textSize="12dp"
android:visibility="gone"
tools:text="From Home"
tools:visibility="visible"/>

</LinearLayout>
</LinearLayout>
2 changes: 2 additions & 0 deletions res/values/strings.xml
Expand Up @@ -100,6 +100,8 @@
<string name="ConversationItem_click_to_approve_unencrypted_mms_dialog_title">Fallback to unencrypted MMS?</string>
<string name="ConversationItem_click_to_approve_unencrypted_dialog_message">This message will <b>not</b> be encrypted because the recipient is no longer a Signal user.\n\nSend unsecured message?</string>
<string name="ConversationItem_unable_to_open_media">Can\'t find an app able to open this media.</string>
<string name="ConversationItem_from_s">from %s</string>
<string name="ConversationItem_to_s">to %s</string>

<!-- ConversationActivity -->
<string name="ConversationActivity_reset_secure_session_question">Reset secure session?</string>
Expand Down
107 changes: 68 additions & 39 deletions src/org/thoughtcrime/securesms/ConversationActivity.java
Expand Up @@ -535,7 +535,7 @@ public void onClick(DialogInterface dialog, int which) {
final Context context = getApplicationContext();

OutgoingEndSessionMessage endSessionMessage =
new OutgoingEndSessionMessage(new OutgoingTextMessage(getRecipients(), "TERMINATE"));
new OutgoingEndSessionMessage(new OutgoingTextMessage(getRecipients(), "TERMINATE", -1));

new AsyncTask<OutgoingEndSessionMessage, Void, Long>() {
@Override
Expand Down Expand Up @@ -823,22 +823,43 @@ protected void onPostExecute(Pair<Boolean, Boolean> result) {
}

private void onSecurityUpdated() {
updateInviteReminder();
updateRecipientPreferences();
}

protected void updateInviteReminder() {
private void updateRecipientPreferences() {
if (recipients.getPrimaryRecipient() != null &&
recipients.getPrimaryRecipient().getContactUri() != null)
{
new RecipientPreferencesTask().execute(recipients);
}
}

protected void updateInviteReminder(boolean seenInvite) {
Log.w(TAG, "updateInviteReminder(" + seenInvite+")");
if (TextSecurePreferences.isPushRegistered(this) &&
!isSecureText &&
recipients.isSingleRecipient() &&
recipients.getPrimaryRecipient() != null &&
recipients.getPrimaryRecipient().getContactUri() != null)
!seenInvite &&
recipients.isSingleRecipient())
{
new ShowInviteReminderTask().execute(recipients);
InviteReminder reminder = new InviteReminder(this, recipients);
reminder.setOkListener(new OnClickListener() {
@Override
public void onClick(View v) {
handleInviteLink();
reminderView.requestDismiss();
}
});
reminderView.showReminder(reminder);
} else {
reminderView.hide();
}
}

private void updateDefaultSubscriptionId(Optional<Integer> defaultSubscriptionId) {
Log.w(TAG, "updateDefaultSubscriptionId(" + defaultSubscriptionId.orNull() + ")");
sendButton.setDefaultSubscriptionId(defaultSubscriptionId);
}

private void initializeMmsEnabledCheck() {
new AsyncTask<Void, Void, Boolean>() {
@Override
Expand Down Expand Up @@ -896,11 +917,12 @@ private void initializeViews() {
sendButton.setEnabled(true);
sendButton.addOnTransportChangedListener(new OnTransportChangedListener() {
@Override
public void onChange(TransportOption newTransport) {
public void onChange(TransportOption newTransport, boolean manuallySelected) {
calculateCharactersRemaining();
composeText.setTransport(newTransport);
buttonToggle.getBackground().setColorFilter(newTransport.getBackgroundColor(), Mode.MULTIPLY);
buttonToggle.getBackground().invalidateSelf();
if (manuallySelected) recordSubscriptionIdPreference(newTransport.getSimSubscriptionId());
}
});

Expand Down Expand Up @@ -968,7 +990,7 @@ public void run() {
titleView.setTitle(recipients);
setBlockedUserState(recipients);
setActionBarColor(recipients.getColor());
updateInviteReminder();
updateRecipientPreferences();
}
});
}
Expand Down Expand Up @@ -1242,8 +1264,9 @@ protected void sendComplete(long threadId) {

private void sendMessage() {
try {
Recipients recipients = getRecipients();
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
Recipients recipients = getRecipients();
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);

Log.w(TAG, "isManual Selection: " + sendButton.isManualSelection());
Log.w(TAG, "forceSms: " + forceSms);
Expand All @@ -1255,9 +1278,9 @@ private void sendMessage() {
if ((!recipients.isSingleRecipient() || recipients.isEmailRecipient()) && !isMmsEnabled) {
handleManualMmsRequired();
} else if (attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient() || recipients.isGroupRecipient() || recipients.isEmailRecipient()) {
sendMediaMessage(forceSms);
sendMediaMessage(forceSms, subscriptionId);
} else {
sendTextMessage(forceSms);
sendTextMessage(forceSms, subscriptionId);
}
} catch (RecipientFormattingException ex) {
Toast.makeText(ConversationActivity.this,
Expand All @@ -1271,13 +1294,13 @@ private void sendMessage() {
}
}

private void sendMediaMessage(final boolean forceSms)
private void sendMediaMessage(final boolean forceSms, final int subscriptionId)
throws InvalidMessageException
{
sendMediaMessage(forceSms, getMessage(), attachmentManager.buildSlideDeck());
sendMediaMessage(forceSms, getMessage(), attachmentManager.buildSlideDeck(), subscriptionId);
}

private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck)
private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck, final int subscriptionId)
throws InvalidMessageException
{
final SettableFuture<Void> future = new SettableFuture<>();
Expand All @@ -1286,6 +1309,7 @@ private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String b
slideDeck,
body,
System.currentTimeMillis(),
subscriptionId,
distributionType);

if (isSecureText && !forceSms) {
Expand All @@ -1311,7 +1335,7 @@ protected void onPostExecute(Long result) {
return future;
}

private void sendTextMessage(final boolean forceSms)
private void sendTextMessage(final boolean forceSms, final int subscriptionId)
throws InvalidMessageException
{
final Context context = getApplicationContext();
Expand All @@ -1320,7 +1344,7 @@ private void sendTextMessage(final boolean forceSms)
if (isSecureText && !forceSms) {
message = new OutgoingEncryptedMessage(recipients, getMessage());
} else {
message = new OutgoingTextMessage(recipients, getMessage());
message = new OutgoingTextMessage(recipients, getMessage(), subscriptionId);
}

this.composeText.setText("");
Expand Down Expand Up @@ -1348,6 +1372,17 @@ private void updateToggleButtonState() {
}
}

private void recordSubscriptionIdPreference(final Optional<Integer> subscriptionId) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getRecipientPreferenceDatabase(ConversationActivity.this)
.setDefaultSubscriptionId(recipients, subscriptionId.or(-1));
return null;
}
}.execute();
}

@Override
public void onAttachmentDrawerStateChanged(DrawerState drawerState) {
if (drawerState == DrawerState.FULL_EXPANDED) {
Expand Down Expand Up @@ -1398,12 +1433,13 @@ public void onRecorderFinished() {
@Override
public void onSuccess(final @NonNull Pair<Uri, Long> result) {
try {
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, ContentType.AUDIO_AAC);
SlideDeck slideDeck = new SlideDeck();
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, ContentType.AUDIO_AAC);
SlideDeck slideDeck = new SlideDeck();
slideDeck.addSlide(audioSlide);

sendMediaMessage(forceSms, "", slideDeck).addListener(new AssertedSuccessListener<Void>() {
sendMediaMessage(forceSms, "", slideDeck, subscriptionId).addListener(new AssertedSuccessListener<Void>() {
@Override
public void onSuccess(Void nothing) {
new AsyncTask<Void, Void, Void>() {
Expand Down Expand Up @@ -1568,30 +1604,23 @@ public void onAttachmentChanged() {
updateToggleButtonState();
}

private class ShowInviteReminderTask extends AsyncTask<Recipients, Void, Pair<Recipients,Boolean>> {
private class RecipientPreferencesTask extends AsyncTask<Recipients, Void, Pair<Recipients,RecipientsPreferences>> {
@Override
protected Pair<Recipients, Boolean> doInBackground(Recipients... recipients) {
if (recipients.length != 1 || recipients[0] == null) throw new AssertionError("task needs exactly one Recipients object");
protected Pair<Recipients, RecipientsPreferences> doInBackground(Recipients... recipients) {
if (recipients.length != 1 || recipients[0] == null) {
throw new AssertionError("task needs exactly one Recipients object");
}

Optional<RecipientsPreferences> prefs = DatabaseFactory.getRecipientPreferenceDatabase(ConversationActivity.this)
.getRecipientsPreferences(recipients[0].getIds());
return new Pair<>(recipients[0], prefs.isPresent() && prefs.get().hasSeenInviteReminder());
return new Pair<>(recipients[0], prefs.orNull());
}

@Override
protected void onPostExecute(Pair<Recipients, Boolean> result) {
if (!result.second && result.first == recipients) {
InviteReminder reminder = new InviteReminder(ConversationActivity.this, result.first);
reminder.setOkListener(new OnClickListener() {
@Override
public void onClick(View v) {
handleInviteLink();
reminderView.requestDismiss();
}
});
reminderView.showReminder(reminder);
} else {
reminderView.hide();
protected void onPostExecute(@NonNull Pair<Recipients, RecipientsPreferences> result) {
if (result.first == recipients) {
updateInviteReminder(result.second != null && result.second.hasSeenInviteReminder());
updateDefaultSubscriptionId(result.second != null ? result.second.getDefaultSubscriptionId() : Optional.<Integer>absent());
}
}
}
Expand Down

0 comments on commit 6da86e4

Please sign in to comment.