Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large attachments #4019

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<string name="ConversationActivity_unblock_question">Unblock?</string>
<string name="ConversationActivity_are_you_sure_you_want_to_unblock_this_contact">Are you sure you want to unblock this contact?</string>
<string name="ConversationActivity_unblock">Unblock</string>
<string name="ConversationActivity_attachment_exceeds_size_limits">Attachment exceeds size limits for the type of message you\'re sending.</string>

<!-- ConversationFragment -->
<string name="ConversationFragment_message_details">Message details</string>
Expand Down
111 changes: 48 additions & 63 deletions src/org/thoughtcrime/securesms/ConversationActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.WindowCompat;
import android.text.Editable;
import android.text.TextWatcher;
Expand Down Expand Up @@ -85,6 +86,7 @@
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MediaTooLargeException;
Expand Down Expand Up @@ -113,6 +115,7 @@
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
Expand Down Expand Up @@ -288,13 +291,16 @@ public void onActivityResult(int reqCode, int resultCode, Intent data) {

switch (reqCode) {
case PICK_IMAGE:
addAttachmentImage(masterSecret, data.getData());
setMedia(data.getData(),
MediaUtil.isGif(MediaUtil.getMimeType(this, data.getData())) ? MediaType.GIF
: MediaType.IMAGE,
false);
break;
case PICK_VIDEO:
addAttachmentVideo(data.getData());
setMedia(data.getData(), MediaType.VIDEO, false);
break;
case PICK_AUDIO:
addAttachmentAudio(data.getData());
setMedia(data.getData(), MediaType.AUDIO, false);
break;
case PICK_CONTACT_INFO:
addAttachmentContactInfo(data.getData());
Expand All @@ -308,7 +314,7 @@ public void onActivityResult(int reqCode, int resultCode, Intent data) {
break;
case TAKE_PHOTO:
if (attachmentManager.getCaptureUri() != null) {
addAttachmentImage(masterSecret, attachmentManager.getCaptureUri());
setMedia(attachmentManager.getCaptureUri(), MediaType.IMAGE, true);
}
break;
}
Expand Down Expand Up @@ -671,9 +677,10 @@ private void initializeDraft() {
Uri draftVideo = getIntent().getParcelableExtra(DRAFT_VIDEO_EXTRA);

if (draftText != null) composeText.setText(draftText);
if (draftImage != null) addAttachmentImage(masterSecret, draftImage);
if (draftAudio != null) addAttachmentAudio(draftAudio);
if (draftVideo != null) addAttachmentVideo(draftVideo);

if (draftImage != null) setMedia(draftImage, MediaType.IMAGE, false);
else if (draftAudio != null) setMedia(draftAudio, MediaType.AUDIO, false);
else if (draftVideo != null) setMedia(draftVideo, MediaType.VIDEO, false);

if (draftText == null && draftImage == null && draftAudio == null && draftVideo == null) {
initializeDraftFromDatabase();
Expand Down Expand Up @@ -707,11 +714,11 @@ protected void onPostExecute(List<Draft> drafts) {
if (draft.getType().equals(Draft.TEXT)) {
composeText.setText(draft.getValue());
} else if (draft.getType().equals(Draft.IMAGE)) {
addAttachmentImage(masterSecret, Uri.parse(draft.getValue()));
setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE, false);
} else if (draft.getType().equals(Draft.AUDIO)) {
addAttachmentAudio(Uri.parse(draft.getValue()));
setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO, false);
} else if (draft.getType().equals(Draft.VIDEO)) {
addAttachmentVideo(Uri.parse(draft.getValue()));
setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO, false);
}
}

Expand Down Expand Up @@ -917,55 +924,8 @@ private void addAttachment(int type) {
}
}

private void addAttachmentImage(MasterSecret masterSecret, Uri imageUri) {
try {
attachmentManager.setImage(masterSecret, imageUri);
} catch (IOException | BitmapDecodingException e) {
Log.w(TAG, e);
attachmentManager.clear();
Toast.makeText(this, R.string.ConversationActivity_sorry_there_was_an_error_setting_your_attachment,
Toast.LENGTH_LONG).show();
} catch (MediaTooLargeException e) {
attachmentManager.clear();
Toast.makeText(this, getString(R.string.ConversationActivity_the_gif_you_selected_was_too_big),
Toast.LENGTH_LONG).show();
Log.w(TAG, e);
}
}

private void addAttachmentVideo(Uri videoUri) {
try {
attachmentManager.setVideo(videoUri);
} catch (IOException e) {
attachmentManager.clear();
Toast.makeText(this, R.string.ConversationActivity_sorry_there_was_an_error_setting_your_attachment,
Toast.LENGTH_LONG).show();
Log.w("ComposeMessageActivity", e);
} catch (MediaTooLargeException e) {
attachmentManager.clear();

Toast.makeText(this, getString(R.string.ConversationActivity_sorry_the_selected_video_exceeds_message_size_restrictions,
(MmsMediaConstraints.MAX_MESSAGE_SIZE/1024)),
Toast.LENGTH_LONG).show();
Log.w("ComposeMessageActivity", e);
}
}

private void addAttachmentAudio(Uri audioUri) {
try {
attachmentManager.setAudio(audioUri);
} catch (IOException e) {
attachmentManager.clear();
Toast.makeText(this, R.string.ConversationActivity_sorry_there_was_an_error_setting_your_attachment,
Toast.LENGTH_LONG).show();
Log.w("ComposeMessageActivity", e);
} catch (MediaTooLargeException e) {
attachmentManager.clear();
Toast.makeText(this, getString(R.string.ConversationActivity_sorry_the_selected_audio_exceeds_message_size_restrictions,
(MmsMediaConstraints.MAX_MESSAGE_SIZE/1024)),
Toast.LENGTH_LONG).show();
Log.w("ComposeMessageActivity", e);
}
private void setMedia(Uri uri, MediaType mediaType, boolean isCapture) {
attachmentManager.setMedia(masterSecret, uri, mediaType, getCurrentMediaConstraints(), isCapture);
}

private void addAttachmentContactInfo(Uri contactUri) {
Expand Down Expand Up @@ -1132,6 +1092,20 @@ private String getMessage() throws InvalidMessageException {
return rawText;
}

private MediaConstraints getCurrentMediaConstraints() {
return sendButton.getSelectedTransport().getType() == Type.TEXTSECURE
? MediaConstraints.PUSH_CONSTRAINTS
: MediaConstraints.MMS_CONSTRAINTS;
}

private boolean isCurrentMediaConstraintSatisfied() {
final MediaConstraints constraints = getCurrentMediaConstraints();
final Slide mediaSlide = attachmentManager.getSlideDeck().getThumbnailSlide();
return mediaSlide == null ||
constraints.isSatisfied(this, masterSecret, mediaSlide.getPart()) ||
constraints.canResize(mediaSlide.getPart());
}

private void markThreadAsRead() {
new AsyncTask<Long, Void, Void>() {
@Override
Expand Down Expand Up @@ -1198,8 +1172,17 @@ private void sendMediaMessage(final boolean forceSms)
final Context context = getApplicationContext();
SlideDeck slideDeck;

if (attachmentManager.isAttachmentPresent()) slideDeck = new SlideDeck(attachmentManager.getSlideDeck());
else slideDeck = new SlideDeck();
if (attachmentManager.isAttachmentPresent()) {
if (!isCurrentMediaConstraintSatisfied()) {
Toast.makeText(context,
R.string.ConversationActivity_attachment_exceeds_size_limits,
Toast.LENGTH_SHORT).show();
return;
}
slideDeck = new SlideDeck(attachmentManager.getSlideDeck());
} else {
slideDeck = new SlideDeck();
}

OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(this, recipients, slideDeck,
getMessage(), distributionType);
Expand Down Expand Up @@ -1272,8 +1255,9 @@ public void onAttachmentDrawerStateChanged(DrawerState drawerState) {

@Override
public void onImageCapture(@NonNull final byte[] imageBytes) {
attachmentManager.setCaptureUri(CaptureProvider.getInstance(this).create(masterSecret, recipients, imageBytes));
addAttachmentImage(masterSecret, attachmentManager.getCaptureUri());
setMedia(CaptureProvider.getInstance(this).create(masterSecret, recipients, imageBytes),
MediaType.IMAGE,
true);
quickAttachmentDrawer.hide(false);
}

Expand Down Expand Up @@ -1397,4 +1381,5 @@ public void onAttachmentChanged() {
initializeSecurity();
updateToggleButtonState();
}

}
2 changes: 1 addition & 1 deletion src/org/thoughtcrime/securesms/ImageMediaAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void onBindViewHolder(final ViewHolder viewHolder, final Cursor cursor) {
part.setContentType(imageRecord.getContentType().getBytes());
part.setPartId(imageRecord.getPartId());

Slide slide = MediaUtil.getSlideForPart(getContext(), masterSecret, part, imageRecord.getContentType());
Slide slide = MediaUtil.getSlideForPart(getContext(), part, imageRecord.getContentType());
if (slide != null) {
imageView.setImageResource(slide, masterSecret);
}
Expand Down
12 changes: 11 additions & 1 deletion src/org/thoughtcrime/securesms/components/ThumbnailView.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,24 @@ public void setDownloadClickListener(ThumbnailClickListener listener) {
}

public void clear() {
if (isContextValid()) Glide.clear(this);
if (isContextValid()) Glide.clear(image);
if (slideDeckFuture != null) slideDeckFuture.removeListener(slideDeckListener);
slide = null;
slideId = null;
slideDeckFuture = null;
slideDeckListener = null;
}

public void hideControls(boolean hideControls) {
this.hideControls = hideControls;
if (hideControls) hideProgressWheel();
}

public void showProgressSpinner() {
getProgressWheel().spin();
getProgressWheel().setVisibility(VISIBLE);
}

@TargetApi(VERSION_CODES.JELLY_BEAN_MR1)
private boolean isContextValid() {
return !(getContext() instanceof Activity) ||
Expand Down
10 changes: 3 additions & 7 deletions src/org/thoughtcrime/securesms/database/MmsDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,7 @@ private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
List<IdentityKeyMismatch> mismatches = getMismatchedIdentities(mismatchDocument);
List<NetworkFailure> networkFailures = getFailures(networkDocument);

ListenableFutureTask<SlideDeck> slideDeck = getSlideDeck(masterSecret, dateReceived, id);
ListenableFutureTask<SlideDeck> slideDeck = getSlideDeck(dateReceived, id);

return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, receiptCount,
Expand Down Expand Up @@ -1159,8 +1159,7 @@ private DisplayRecord.Body getBody(Cursor cursor) {
}
}

private ListenableFutureTask<SlideDeck> getSlideDeck(final MasterSecret masterSecret,
final long timestamp,
private ListenableFutureTask<SlideDeck> getSlideDeck(final long timestamp,
final long id)
{
ListenableFutureTask<SlideDeck> future = getCachedSlideDeck(timestamp, id);
Expand All @@ -1172,12 +1171,9 @@ private ListenableFutureTask<SlideDeck> getSlideDeck(final MasterSecret masterSe
Callable<SlideDeck> task = new Callable<SlideDeck>() {
@Override
public SlideDeck call() throws Exception {
if (masterSecret == null)
return null;

PartDatabase partDatabase = DatabaseFactory.getPartDatabase(context);
PduBody body = getPartsAsBody(partDatabase.getParts(id));
SlideDeck slideDeck = new SlideDeck(context, masterSecret, body);
SlideDeck slideDeck = new SlideDeck(context, body);

if (!body.containsPushInProgress()) {
slideCache.put(timestamp + "::" + id, new SoftReference<>(slideDeck));
Expand Down
Loading