Remove dedicated MMS download controls

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2017-01-20 15:26:17 -08:00
parent 183f8742a7
commit 235a8472d9
12 changed files with 173 additions and 202 deletions

View File

@ -74,29 +74,6 @@
android:autoLink="all" android:autoLink="all"
android:linksClickable="true" /> android:linksClickable="true" />
<LinearLayout android:id="@+id/mms_download_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/mms_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/conversation_item_received__download"
android:visibility="gone" />
<TextView android:id="@+id/mms_label_downloading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center"
android:text="@string/conversation_item_received__downloading"
android:visibility="gone" />
</LinearLayout>
<LinearLayout android:layout_width="wrap_content" <LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="2dip" android:paddingTop="2dip"

View File

@ -64,29 +64,6 @@
android:textSize="@dimen/conversation_item_body_text_size" android:textSize="@dimen/conversation_item_body_text_size"
tools:text="Mango pickle lorem ipsum" /> tools:text="Mango pickle lorem ipsum" />
<LinearLayout android:id="@+id/mms_download_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/mms_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/conversation_item_sent__download"
android:visibility="gone" />
<TextView android:id="@+id/mms_label_downloading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center"
android:text="@string/conversation_item_sent__downloading"
android:visibility="gone" />
</LinearLayout>
<LinearLayout android:layout_width="wrap_content" <LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"

View File

@ -380,6 +380,8 @@
<!-- NotificationMmsMessageRecord --> <!-- NotificationMmsMessageRecord -->
<string name="NotificationMmsMessageRecord_multimedia_message">Multimedia message</string> <string name="NotificationMmsMessageRecord_multimedia_message">Multimedia message</string>
<string name="NotificationMmsMessageRecord_downloading_mms_message">Downloading MMS message</string>
<string name="NotificationMmsMessageRecord_error_downloading_mms_message">Error downloading MMS message, tap to retry</string>
<!-- MessageRecord --> <!-- MessageRecord -->
<string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Received a message encrypted using an old version of Signal that is no longer supported. Please ask the sender to update to the most recent version and resend the message.</string> <string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Received a message encrypted using an old version of Signal that is no longer supported. Please ask the sender to update to the most recent version and resend the message.</string>

View File

@ -23,6 +23,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -35,8 +36,8 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.LRUCache;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
@ -61,6 +62,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
{ {
private static final int MAX_CACHE_SIZE = 40; private static final int MAX_CACHE_SIZE = 40;
private static final String TAG = ConversationAdapter.class.getName();
private final Map<String,SoftReference<MessageRecord>> messageRecordCache = private final Map<String,SoftReference<MessageRecord>> messageRecordCache =
Collections.synchronizedMap(new LRUCache<String, SoftReference<MessageRecord>>(MAX_CACHE_SIZE)); Collections.synchronizedMap(new LRUCache<String, SoftReference<MessageRecord>>(MAX_CACHE_SIZE));
@ -135,15 +137,18 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
@Override @Override
public void onBindItemViewHolder(ViewHolder viewHolder, @NonNull Cursor cursor) { public void onBindItemViewHolder(ViewHolder viewHolder, @NonNull Cursor cursor) {
long start = System.currentTimeMillis();
long id = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.ID)); long id = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.ID));
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT)); String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
MessageRecord messageRecord = getMessageRecord(id, cursor, type); MessageRecord messageRecord = getMessageRecord(id, cursor, type);
viewHolder.getView().bind(masterSecret, messageRecord, locale, batchSelected, recipients); viewHolder.getView().bind(masterSecret, messageRecord, locale, batchSelected, recipients);
Log.w(TAG, "Bind time: " + (System.currentTimeMillis() - start));
} }
@Override @Override
public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
long start = System.currentTimeMillis();
final V itemView = ViewUtil.inflate(inflater, parent, getLayoutForViewType(viewType)); final V itemView = ViewUtil.inflate(inflater, parent, getLayoutForViewType(viewType));
itemView.setOnClickListener(new OnClickListener() { itemView.setOnClickListener(new OnClickListener() {
@Override @Override
@ -162,7 +167,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
return true; return true;
} }
}); });
Log.w(TAG, "Inflate time: " + (System.currentTimeMillis() - start));
return new ViewHolder(itemView); return new ViewHolder(itemView);
} }
@ -243,14 +248,10 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
} }
private boolean hasAudio(MessageRecord messageRecord) { private boolean hasAudio(MessageRecord messageRecord) {
return messageRecord.isMms() && return messageRecord.isMms() && ((MmsMessageRecord)messageRecord).getSlideDeck().getAudioSlide() != null;
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getAudioSlide() != null;
} }
private boolean hasThumbnail(MessageRecord messageRecord) { private boolean hasThumbnail(MessageRecord messageRecord) {
return messageRecord.isMms() && return messageRecord.isMms() && ((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide() != null;
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide() != null;
} }
} }

View File

@ -34,7 +34,6 @@ import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewStub; import android.view.ViewStub;
import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
@ -55,7 +54,7 @@ import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.jobs.MmsDownloadJob; import org.thoughtcrime.securesms.jobs.MmsDownloadJob;
import org.thoughtcrime.securesms.jobs.MmsSendJob; import org.thoughtcrime.securesms.jobs.MmsSendJob;
import org.thoughtcrime.securesms.jobs.SmsSendJob; import org.thoughtcrime.securesms.jobs.SmsSendJob;
@ -113,14 +112,10 @@ public class ConversationItem extends LinearLayout
private @Nullable Recipients conversationRecipients; private @Nullable Recipients conversationRecipients;
private @NonNull Stub<ThumbnailView> mediaThumbnailStub; private @NonNull Stub<ThumbnailView> mediaThumbnailStub;
private @NonNull Stub<AudioView> audioViewStub; private @NonNull Stub<AudioView> audioViewStub;
private @NonNull Button mmsDownloadButton;
private @NonNull TextView mmsDownloadingLabel;
private @NonNull ExpirationTimerView expirationTimer; private @NonNull ExpirationTimerView expirationTimer;
private int defaultBubbleColor; private int defaultBubbleColor;
private final MmsDownloadClickListener mmsDownloadClickListener = new MmsDownloadClickListener();
private final MmsPreferencesClickListener mmsPreferencesClickListener = new MmsPreferencesClickListener();
private final PassthroughClickListener passthroughClickListener = new PassthroughClickListener(); private final PassthroughClickListener passthroughClickListener = new PassthroughClickListener();
private final AttachmentDownloadClickListener downloadClickListener = new AttachmentDownloadClickListener(); private final AttachmentDownloadClickListener downloadClickListener = new AttachmentDownloadClickListener();
@ -154,8 +149,6 @@ public class ConversationItem extends LinearLayout
this.secureImage = (ImageView) findViewById(R.id.secure_indicator); this.secureImage = (ImageView) findViewById(R.id.secure_indicator);
this.deliveryStatusIndicator = (DeliveryStatusView) findViewById(R.id.delivery_status); this.deliveryStatusIndicator = (DeliveryStatusView) findViewById(R.id.delivery_status);
this.alertView = (AlertView) findViewById(R.id.indicators_parent); this.alertView = (AlertView) findViewById(R.id.indicators_parent);
this.mmsDownloadButton = (Button) findViewById(R.id.mms_download_button);
this.mmsDownloadingLabel = (TextView) findViewById(R.id.mms_label_downloading);
this.contactPhoto = (AvatarImageView) findViewById(R.id.contact_photo); this.contactPhoto = (AvatarImageView) findViewById(R.id.contact_photo);
this.bodyBubble = findViewById(R.id.body_bubble); this.bodyBubble = findViewById(R.id.body_bubble);
this.mediaThumbnailStub = new Stub<>((ViewStub) findViewById(R.id.image_view_stub)); this.mediaThumbnailStub = new Stub<>((ViewStub) findViewById(R.id.image_view_stub));
@ -164,7 +157,6 @@ public class ConversationItem extends LinearLayout
setOnClickListener(new ClickListener(null)); setOnClickListener(new ClickListener(null));
mmsDownloadButton.setOnClickListener(mmsDownloadClickListener);
bodyText.setOnLongClickListener(passthroughClickListener); bodyText.setOnLongClickListener(passthroughClickListener);
bodyText.setOnClickListener(passthroughClickListener); bodyText.setOnClickListener(passthroughClickListener);
} }
@ -267,15 +259,11 @@ public class ConversationItem extends LinearLayout
} }
private boolean hasAudio(MessageRecord messageRecord) { private boolean hasAudio(MessageRecord messageRecord) {
return messageRecord.isMms() && return messageRecord.isMms() && ((MmsMessageRecord)messageRecord).getSlideDeck().getAudioSlide() != null;
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getAudioSlide() != null;
} }
private boolean hasThumbnail(MessageRecord messageRecord) { private boolean hasThumbnail(MessageRecord messageRecord) {
return messageRecord.isMms() && return messageRecord.isMms() && ((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide() != null;
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide() != null;
} }
private void setBodyText(MessageRecord messageRecord) { private void setBodyText(MessageRecord messageRecord) {
@ -293,13 +281,7 @@ public class ConversationItem extends LinearLayout
private void setMediaAttributes(MessageRecord messageRecord) { private void setMediaAttributes(MessageRecord messageRecord) {
boolean showControls = !messageRecord.isFailed() && (!messageRecord.isOutgoing() || messageRecord.isPending()); boolean showControls = !messageRecord.isFailed() && (!messageRecord.isOutgoing() || messageRecord.isPending());
if (messageRecord.isMmsNotification()) { if (hasAudio(messageRecord)) {
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE);
bodyText.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setNotificationMmsAttributes((NotificationMmsMessageRecord) messageRecord);
} else if (hasAudio(messageRecord)) {
audioViewStub.get().setVisibility(View.VISIBLE); audioViewStub.get().setVisibility(View.VISIBLE);
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE); if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
@ -315,7 +297,7 @@ public class ConversationItem extends LinearLayout
//noinspection ConstantConditions //noinspection ConstantConditions
mediaThumbnailStub.get().setImageResource(masterSecret, mediaThumbnailStub.get().setImageResource(masterSecret,
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide(), ((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide(),
showControls); showControls);
mediaThumbnailStub.get().setThumbnailClickListener(new ThumbnailClickListener()); mediaThumbnailStub.get().setThumbnailClickListener(new ThumbnailClickListener());
mediaThumbnailStub.get().setDownloadClickListener(downloadClickListener); mediaThumbnailStub.get().setDownloadClickListener(downloadClickListener);
@ -337,8 +319,6 @@ public class ConversationItem extends LinearLayout
} }
private void setStatusIcons(MessageRecord messageRecord) { private void setStatusIcons(MessageRecord messageRecord) {
mmsDownloadButton.setVisibility(View.GONE);
mmsDownloadingLabel.setVisibility(View.GONE);
indicatorText.setVisibility(View.GONE); indicatorText.setVisibility(View.GONE);
secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE); secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE);
@ -452,31 +432,6 @@ public class ConversationItem extends LinearLayout
} }
} }
private void setNotificationMmsAttributes(NotificationMmsMessageRecord messageRecord) {
String messageSize = String.format(context.getString(R.string.ConversationItem_message_size_d_kb),
messageRecord.getMessageSize());
String expires = String.format(context.getString(R.string.ConversationItem_expires_s),
DateUtils.getRelativeTimeSpanString(getContext(),
messageRecord.getExpiration(),
false));
dateText.setText(messageSize + "\n" + expires);
if (MmsDatabase.Status.isDisplayDownloadButton(messageRecord.getStatus())) {
mmsDownloadButton.setVisibility(View.VISIBLE);
mmsDownloadingLabel.setVisibility(View.GONE);
} else {
mmsDownloadingLabel.setText(MmsDatabase.Status.getLabelForStatus(context, messageRecord.getStatus()));
mmsDownloadButton.setVisibility(View.GONE);
mmsDownloadingLabel.setVisibility(View.VISIBLE);
if (MmsDatabase.Status.isHardError(messageRecord.getStatus()) && !messageRecord.isOutgoing())
setOnClickListener(mmsDownloadClickListener);
else if (MmsDatabase.Status.DOWNLOAD_APN_UNAVAILABLE == messageRecord.getStatus() && !messageRecord.isOutgoing())
setOnClickListener(mmsPreferencesClickListener);
}
}
/// Helper Methods /// Helper Methods
private void setContactPhotoForRecipient(final Recipient recipient) { private void setContactPhotoForRecipient(final Recipient recipient) {
@ -521,10 +476,18 @@ public class ConversationItem extends LinearLayout
} }
private class AttachmentDownloadClickListener implements SlideClickListener { private class AttachmentDownloadClickListener implements SlideClickListener {
@Override public void onClick(View v, final Slide slide) { @Override
DatabaseFactory.getAttachmentDatabase(context).setTransferState(messageRecord.getId(), public void onClick(View v, final Slide slide) {
slide.asAttachment(), if (messageRecord.isMmsNotification()) {
AttachmentDatabase.TRANSFER_PROGRESS_STARTED); ApplicationContext.getInstance(context)
.getJobManager()
.add(new MmsDownloadJob(context, messageRecord.getId(),
messageRecord.getThreadId(), false));
} else {
DatabaseFactory.getAttachmentDatabase(context).setTransferState(messageRecord.getId(),
slide.asAttachment(),
AttachmentDatabase.TRANSFER_PROGRESS_STARTED);
}
} }
} }
@ -572,30 +535,6 @@ public class ConversationItem extends LinearLayout
} }
} }
private class MmsDownloadClickListener implements View.OnClickListener {
public void onClick(View v) {
NotificationMmsMessageRecord notificationRecord = (NotificationMmsMessageRecord)messageRecord;
Log.w(TAG, "Content location: " + new String(notificationRecord.getContentLocation()));
mmsDownloadButton.setVisibility(View.GONE);
mmsDownloadingLabel.setVisibility(View.VISIBLE);
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MmsDownloadJob(context, messageRecord.getId(),
messageRecord.getThreadId(), false));
}
}
private class MmsPreferencesClickListener implements View.OnClickListener {
public void onClick(View v) {
Intent intent = new Intent(context, PromptMmsActivity.class);
intent.putExtra("message_id", messageRecord.getId());
intent.putExtra("thread_id", messageRecord.getThreadId());
intent.putExtra("automatic", true);
context.startActivity(intent);
}
}
private class PassthroughClickListener implements View.OnLongClickListener, View.OnClickListener { private class PassthroughClickListener implements View.OnLongClickListener, View.OnClickListener {
@Override @Override

View File

@ -0,0 +1,39 @@
package org.thoughtcrime.securesms.attachments;
import android.net.Uri;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
public class MmsNotificationAttachment extends Attachment {
public MmsNotificationAttachment(int status, long size) {
super("application/mms", getTransferStateFromStatus(status), size, null, null, null);
}
@Nullable
@Override
public Uri getDataUri() {
return null;
}
@Nullable
@Override
public Uri getThumbnailUri() {
return null;
}
private static int getTransferStateFromStatus(int status) {
if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED ||
status == MmsDatabase.Status.DOWNLOAD_NO_CONNECTIVITY)
{
return AttachmentDatabase.TRANSFER_PROGRESS_AUTO_PENDING;
} else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) {
return AttachmentDatabase.TRANSFER_PROGRESS_STARTED;
} else {
return AttachmentDatabase.TRANSFER_PROGRESS_FAILED;
}
}
}

View File

@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment;
import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher; import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher;
import org.thoughtcrime.securesms.crypto.MasterCipher; import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret;
@ -1075,28 +1076,6 @@ public class MmsDatabase extends MessagingDatabase {
public static final int DOWNLOAD_SOFT_FAILURE = 4; public static final int DOWNLOAD_SOFT_FAILURE = 4;
public static final int DOWNLOAD_HARD_FAILURE = 5; public static final int DOWNLOAD_HARD_FAILURE = 5;
public static final int DOWNLOAD_APN_UNAVAILABLE = 6; public static final int DOWNLOAD_APN_UNAVAILABLE = 6;
public static boolean isDisplayDownloadButton(int status) {
return
status == DOWNLOAD_INITIALIZED ||
status == DOWNLOAD_NO_CONNECTIVITY ||
status == DOWNLOAD_SOFT_FAILURE;
}
public static String getLabelForStatus(Context context, int status) {
switch (status) {
case DOWNLOAD_CONNECTING: return context.getString(R.string.MmsDatabase_connecting_to_mms_server);
case DOWNLOAD_INITIALIZED: return context.getString(R.string.MmsDatabase_downloading_mms);
case DOWNLOAD_HARD_FAILURE: return context.getString(R.string.MmsDatabase_mms_download_failed);
case DOWNLOAD_APN_UNAVAILABLE: return context.getString(R.string.MmsDatabase_mms_pending_download);
}
return context.getString(R.string.MmsDatabase_downloading);
}
public static boolean isHardError(int status) {
return status == DOWNLOAD_HARD_FAILURE;
}
} }
public class Reader { public class Reader {
@ -1157,11 +1136,13 @@ public class MmsDatabase extends MessagingDatabase {
if (!TextUtils.isEmpty(transactionId)) if (!TextUtils.isEmpty(transactionId))
transactionIdBytes = org.thoughtcrime.securesms.util.Util.toIsoBytes(transactionId); transactionIdBytes = org.thoughtcrime.securesms.util.Util.toIsoBytes(transactionId);
SlideDeck slideDeck = new SlideDeck(context, new MmsNotificationAttachment(status, messageSize));
return new NotificationMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(), return new NotificationMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, receiptCount, threadId, addressDeviceId, dateSent, dateReceived, receiptCount, threadId,
contentLocationBytes, messageSize, expiry, status, contentLocationBytes, messageSize, expiry, status,
transactionIdBytes, mailbox, subscriptionId); transactionIdBytes, mailbox, subscriptionId, slideDeck);
} }
private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) { private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {

View File

@ -25,7 +25,6 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase.Status; import org.thoughtcrime.securesms.database.SmsDatabase.Status;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.recipients.Recipients;
@ -40,12 +39,11 @@ import java.util.List;
* *
*/ */
public class MediaMmsMessageRecord extends MessageRecord { public class MediaMmsMessageRecord extends MmsMessageRecord {
private final static String TAG = MediaMmsMessageRecord.class.getSimpleName(); private final static String TAG = MediaMmsMessageRecord.class.getSimpleName();
private final Context context; private final Context context;
private final int partCount; private final int partCount;
private final @NonNull SlideDeck slideDeck;
public MediaMmsMessageRecord(Context context, long id, Recipients recipients, public MediaMmsMessageRecord(Context context, long id, Recipients recipients,
Recipient individualRecipient, int recipientDeviceId, Recipient individualRecipient, int recipientDeviceId,
@ -59,46 +57,21 @@ public class MediaMmsMessageRecord extends MessageRecord {
{ {
super(context, id, body, recipients, individualRecipient, recipientDeviceId, dateSent, super(context, id, body, recipients, individualRecipient, recipientDeviceId, dateSent,
dateReceived, threadId, Status.STATUS_NONE, receiptCount, mailbox, mismatches, failures, dateReceived, threadId, Status.STATUS_NONE, receiptCount, mailbox, mismatches, failures,
subscriptionId, expiresIn, expireStarted); subscriptionId, expiresIn, expireStarted, slideDeck);
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.partCount = partCount; this.partCount = partCount;
this.slideDeck = slideDeck;
}
public @NonNull SlideDeck getSlideDeck() {
return slideDeck;
}
public boolean containsMediaSlide() {
return slideDeck.containsMediaSlide();
} }
public int getPartCount() { public int getPartCount() {
return partCount; return partCount;
} }
@Override
public boolean isMms() {
return true;
}
@Override @Override
public boolean isMmsNotification() { public boolean isMmsNotification() {
return false; return false;
} }
@Override
public boolean isMediaPending() {
for (Slide slide : getSlideDeck().getSlides()) {
if (slide.isInProgress() || slide.isPendingDownload()) {
return true;
}
}
return false;
}
@Override @Override
public SpannableString getDisplayBody() { public SpannableString getDisplayBody() {
if (MmsDatabase.Types.isDecryptInProgressType(type)) { if (MmsDatabase.Types.isDecryptInProgressType(type)) {

View File

@ -0,0 +1,57 @@
package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
import java.util.List;
public abstract class MmsMessageRecord extends MessageRecord {
private final @NonNull SlideDeck slideDeck;
MmsMessageRecord(Context context, long id, Body body, Recipients recipients,
Recipient individualRecipient, int recipientDeviceId, long dateSent,
long dateReceived, long threadId, int deliveryStatus, int receiptCount,
long type, List<IdentityKeyMismatch> mismatches,
List<NetworkFailure> networkFailures, int subscriptionId, long expiresIn,
long expireStarted, @NonNull SlideDeck slideDeck)
{
super(context, id, body, recipients, individualRecipient, recipientDeviceId, dateSent, dateReceived, threadId, deliveryStatus, receiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted);
this.slideDeck = slideDeck;
}
@Override
public boolean isMms() {
return true;
}
@NonNull
public SlideDeck getSlideDeck() {
return slideDeck;
}
@Override
public boolean isMediaPending() {
for (Slide slide : getSlideDeck().getSlides()) {
if (slide.isInProgress() || slide.isPendingDownload()) {
return true;
}
}
return false;
}
public boolean containsMediaSlide() {
return slideDeck.containsMediaSlide();
}
}

View File

@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.database.SmsDatabase.Status;
import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.recipients.Recipients;
@ -37,12 +38,12 @@ import java.util.LinkedList;
* *
*/ */
public class NotificationMmsMessageRecord extends MessageRecord { public class NotificationMmsMessageRecord extends MmsMessageRecord {
private final byte[] contentLocation; private final byte[] contentLocation;
private final long messageSize; private final long messageSize;
private final long expiry; private final long expiry;
private final int status; private final int status;
private final byte[] transactionId; private final byte[] transactionId;
public NotificationMmsMessageRecord(Context context, long id, Recipients recipients, public NotificationMmsMessageRecord(Context context, long id, Recipients recipients,
@ -50,12 +51,12 @@ public class NotificationMmsMessageRecord extends MessageRecord {
long dateSent, long dateReceived, int receiptCount, long dateSent, long dateReceived, int receiptCount,
long threadId, byte[] contentLocation, long messageSize, long threadId, byte[] contentLocation, long messageSize,
long expiry, int status, byte[] transactionId, long mailbox, long expiry, int status, byte[] transactionId, long mailbox,
int subscriptionId) int subscriptionId, SlideDeck slideDeck)
{ {
super(context, id, new Body("", true), recipients, individualRecipient, recipientDeviceId, super(context, id, new Body("", true), recipients, individualRecipient, recipientDeviceId,
dateSent, dateReceived, threadId, Status.STATUS_NONE, receiptCount, mailbox, dateSent, dateReceived, threadId, Status.STATUS_NONE, receiptCount, mailbox,
new LinkedList<IdentityKeyMismatch>(), new LinkedList<NetworkFailure>(), subscriptionId, new LinkedList<IdentityKeyMismatch>(), new LinkedList<NetworkFailure>(), subscriptionId,
0, 0); 0, 0, slideDeck);
this.contentLocation = contentLocation; this.contentLocation = contentLocation;
this.messageSize = messageSize; this.messageSize = messageSize;
@ -89,11 +90,6 @@ public class NotificationMmsMessageRecord extends MessageRecord {
return false; return false;
} }
@Override
public boolean isFailed() {
return MmsDatabase.Status.isHardError(status);
}
@Override @Override
public boolean isSecure() { public boolean isSecure() {
return false; return false;
@ -104,11 +100,6 @@ public class NotificationMmsMessageRecord extends MessageRecord {
return false; return false;
} }
@Override
public boolean isMms() {
return true;
}
@Override @Override
public boolean isMmsNotification() { public boolean isMmsNotification() {
return true; return true;
@ -121,6 +112,12 @@ public class NotificationMmsMessageRecord extends MessageRecord {
@Override @Override
public SpannableString getDisplayBody() { public SpannableString getDisplayBody() {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_multimedia_message)); if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED) {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_multimedia_message));
} else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_downloading_mms_message));
} else {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message));
}
} }
} }

View File

@ -0,0 +1,21 @@
package org.thoughtcrime.securesms.mms;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.attachments.Attachment;
public class MmsSlide extends ImageSlide {
public MmsSlide(@NonNull Context context, @NonNull Attachment attachment) {
super(context, attachment);
}
@NonNull
@Override
public String getContentDescription() {
return "MMS";
}
}

View File

@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.mms.AudioSlide;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GifSlide; import org.thoughtcrime.securesms.mms.GifSlide;
import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.ImageSlide;
import org.thoughtcrime.securesms.mms.MmsSlide;
import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.VideoSlide; import org.thoughtcrime.securesms.mms.VideoSlide;
@ -79,6 +80,8 @@ public class MediaUtil {
slide = new VideoSlide(context, attachment); slide = new VideoSlide(context, attachment);
} else if (ContentType.isAudioType(attachment.getContentType())) { } else if (ContentType.isAudioType(attachment.getContentType())) {
slide = new AudioSlide(context, attachment); slide = new AudioSlide(context, attachment);
} else if (isMms(attachment.getContentType())) {
slide = new MmsSlide(context, attachment);
} }
return slide; return slide;
@ -128,6 +131,10 @@ public class MediaUtil {
return size; return size;
} }
public static boolean isMms(String contentType) {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals("application/mms");
}
public static boolean isGif(String contentType) { public static boolean isGif(String contentType) {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif"); return !TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif");
} }