diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8da04333f6..28220cceae 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -126,6 +126,7 @@
Unblock?
Are you sure you want to unblock this contact?
Unblock
+ Attachment exceeds size limits for the type of message you\'re sending.
Message details
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index 3b945074ff..b9026de61e 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -35,6 +35,7 @@ import android.os.Build;
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;
@@ -85,6 +86,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
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;
@@ -113,6 +115,7 @@ import org.thoughtcrime.securesms.util.DirectoryHelper;
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;
@@ -288,13 +291,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
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());
@@ -308,7 +314,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
break;
case TAKE_PHOTO:
if (attachmentManager.getCaptureUri() != null) {
- addAttachmentImage(masterSecret, attachmentManager.getCaptureUri());
+ setMedia(attachmentManager.getCaptureUri(), MediaType.IMAGE, true);
}
break;
}
@@ -671,9 +677,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
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();
@@ -707,11 +714,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
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);
}
}
@@ -917,55 +924,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
}
- 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) {
@@ -1132,6 +1092,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
return rawText;
}
+ private MediaConstraints getCurrentMediaConstraints() {
+ return sendButton.getSelectedTransport().getType() == Type.TEXTSECURE
+ ? MediaConstraints.PUSH_CONSTRAINTS
+ : MediaConstraints.MMS_CONSTRAINTS;
+ }
+
private void markThreadAsRead() {
new AsyncTask() {
@Override
@@ -1198,8 +1164,24 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
final Context context = getApplicationContext();
SlideDeck slideDeck;
- if (attachmentManager.isAttachmentPresent()) slideDeck = new SlideDeck(attachmentManager.getSlideDeck());
- else slideDeck = new SlideDeck();
+ if (attachmentManager.isAttachmentPresent()) {
+ Slide mediaSlide = attachmentManager.getSlideDeck().getThumbnailSlide();
+ MediaConstraints constraints = getCurrentMediaConstraints();
+
+ if (mediaSlide != null &&
+ !constraints.isSatisfied(this, masterSecret, mediaSlide.getPart()) &&
+ !constraints.canResize(mediaSlide.getPart()))
+ {
+ 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);
@@ -1272,8 +1254,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@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);
}
@@ -1397,4 +1378,5 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
initializeSecurity();
updateToggleButtonState();
}
+
}
diff --git a/src/org/thoughtcrime/securesms/ImageMediaAdapter.java b/src/org/thoughtcrime/securesms/ImageMediaAdapter.java
index 200fe28a86..6691399db0 100644
--- a/src/org/thoughtcrime/securesms/ImageMediaAdapter.java
+++ b/src/org/thoughtcrime/securesms/ImageMediaAdapter.java
@@ -74,7 +74,7 @@ public class ImageMediaAdapter extends CursorRecyclerViewAdapter {
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);
}
diff --git a/src/org/thoughtcrime/securesms/components/ThumbnailView.java b/src/org/thoughtcrime/securesms/components/ThumbnailView.java
index 8d37cff54d..2ad29342ce 100644
--- a/src/org/thoughtcrime/securesms/components/ThumbnailView.java
+++ b/src/org/thoughtcrime/securesms/components/ThumbnailView.java
@@ -201,7 +201,12 @@ public class ThumbnailView extends FrameLayout {
}
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) {
@@ -209,6 +214,11 @@ public class ThumbnailView extends FrameLayout {
if (hideControls) hideProgressWheel();
}
+ public void showProgressSpinner() {
+ getProgressWheel().spin();
+ getProgressWheel().setVisibility(VISIBLE);
+ }
+
@TargetApi(VERSION_CODES.JELLY_BEAN_MR1)
private boolean isContextValid() {
return !(getContext() instanceof Activity) ||
diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
index c479b3e52a..a85c2aa703 100644
--- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
@@ -1094,7 +1094,7 @@ public class MmsDatabase extends MessagingDatabase {
List mismatches = getMismatchedIdentities(mismatchDocument);
List networkFailures = getFailures(networkDocument);
- ListenableFutureTask slideDeck = getSlideDeck(masterSecret, dateReceived, id);
+ ListenableFutureTask slideDeck = getSlideDeck(dateReceived, id);
return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, receiptCount,
@@ -1159,8 +1159,7 @@ public class MmsDatabase extends MessagingDatabase {
}
}
- private ListenableFutureTask getSlideDeck(final MasterSecret masterSecret,
- final long timestamp,
+ private ListenableFutureTask getSlideDeck(final long timestamp,
final long id)
{
ListenableFutureTask future = getCachedSlideDeck(timestamp, id);
@@ -1172,12 +1171,9 @@ public class MmsDatabase extends MessagingDatabase {
Callable task = new Callable() {
@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));
diff --git a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java
index bb0168b911..e401918a55 100644
--- a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java
+++ b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java
@@ -21,9 +21,11 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Build;
import android.provider.ContactsContract;
import android.provider.MediaStore;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
@@ -36,7 +38,6 @@ import org.thoughtcrime.securesms.components.ThumbnailView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.providers.CaptureProvider;
import org.thoughtcrime.securesms.recipients.Recipients;
-import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.io.IOException;
@@ -54,7 +55,7 @@ public class AttachmentManager {
public AttachmentManager(Activity view, AttachmentListener listener) {
this.attachmentView = view.findViewById(R.id.attachment_editor);
- this.thumbnail = (ThumbnailView)view.findViewById(R.id.attachment_thumbnail);
+ this.thumbnail = (ThumbnailView) view.findViewById(R.id.attachment_thumbnail);
this.slideDeck = new SlideDeck();
this.context = view;
this.attachmentListener = listener;
@@ -70,6 +71,7 @@ public class AttachmentManager {
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation animation) {
slideDeck.clear();
+ thumbnail.clear();
attachmentView.setVisibility(View.GONE);
attachmentListener.onAttachmentChanged();
}
@@ -83,34 +85,55 @@ public class AttachmentManager {
captureUri = null;
}
- public void setImage(MasterSecret masterSecret, Uri image)
- throws IOException, BitmapDecodingException, MediaTooLargeException
+ public void setMedia(@NonNull final MasterSecret masterSecret,
+ @NonNull final Uri uri,
+ @NonNull final MediaType mediaType,
+ @NonNull final MediaConstraints constraints,
+ final boolean isCapture)
{
- if (MediaUtil.isGif(MediaUtil.getMimeType(context, image))) {
- setMedia(new GifSlide(context, masterSecret, image), masterSecret);
- } else {
- setMedia(new ImageSlide(context, masterSecret, image), masterSecret);
- }
- }
+ new AsyncTask() {
+ @Override protected void onPreExecute() {
+ slideDeck.clear();
+ thumbnail.clear();
+ thumbnail.showProgressSpinner();
+ attachmentView.setVisibility(View.VISIBLE);
- public void setVideo(Uri video) throws IOException, MediaTooLargeException {
- setMedia(new VideoSlide(context, video));
- }
+ if (isCapture) captureUri = uri;
+ if (!uri.equals(captureUri)) cleanup();
+ }
- public void setAudio(Uri audio) throws IOException, MediaTooLargeException {
- setMedia(new AudioSlide(context, audio));
- }
+ @Override protected @Nullable Slide doInBackground(Void... params) {
+ long start = System.currentTimeMillis();
+ try {
+ final long mediaSize = MediaUtil.getMediaSize(context, masterSecret, uri);
+ final Slide slide = mediaType.createSlide(context, uri, mediaSize);
+ Log.w(TAG, "slide with size " + mediaSize + " took " + (System.currentTimeMillis() - start) + "ms");
+ return slide;
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ return null;
+ }
+ }
- public void setMedia(final Slide slide) {
- setMedia(slide, null);
- }
-
- public void setMedia(final Slide slide, @Nullable MasterSecret masterSecret) {
- slideDeck.clear();
- slideDeck.addSlide(slide);
- attachmentView.setVisibility(View.VISIBLE);
- thumbnail.setImageResource(slide, masterSecret);
- attachmentListener.onAttachmentChanged();
+ @Override protected void onPostExecute(@Nullable final Slide slide) {
+ if (slide == null) {
+ attachmentView.setVisibility(View.GONE);
+ Toast.makeText(context,
+ R.string.ConversationActivity_sorry_there_was_an_error_setting_your_attachment,
+ Toast.LENGTH_SHORT).show();
+ } else if (!areConstraintsSatisfied(context, masterSecret, slide, constraints)) {
+ attachmentView.setVisibility(View.GONE);
+ Toast.makeText(context,
+ R.string.ConversationActivity_attachment_exceeds_size_limits,
+ Toast.LENGTH_SHORT).show();
+ } else {
+ slideDeck.addSlide(slide);
+ attachmentView.setVisibility(View.VISIBLE);
+ thumbnail.setImageResource(slide, masterSecret);
+ attachmentListener.onAttachmentChanged();
+ }
+ }
+ }.execute();
}
public boolean isAttachmentPresent() {
@@ -118,7 +141,7 @@ public class AttachmentManager {
}
- public SlideDeck getSlideDeck() {
+ public @NonNull SlideDeck getSlideDeck() {
return slideDeck;
}
@@ -143,10 +166,6 @@ public class AttachmentManager {
return captureUri;
}
- public void setCaptureUri(Uri captureUri) {
- this.captureUri = captureUri;
- }
-
public void capturePhoto(Activity activity, Recipients recipients, int requestCode) {
try {
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
@@ -183,6 +202,16 @@ public class AttachmentManager {
}
}
+ private boolean areConstraintsSatisfied(final @NonNull Context context,
+ final @NonNull MasterSecret masterSecret,
+ final @Nullable Slide slide,
+ final @NonNull MediaConstraints constraints)
+ {
+ return slide == null ||
+ constraints.isSatisfied(context, masterSecret, slide.getPart()) ||
+ constraints.canResize(slide.getPart());
+ }
+
private class RemoveButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
@@ -194,4 +223,22 @@ public class AttachmentManager {
public interface AttachmentListener {
void onAttachmentChanged();
}
+
+ public enum MediaType {
+ IMAGE, GIF, AUDIO, VIDEO;
+
+ public @NonNull Slide createSlide(@NonNull Context context,
+ @NonNull Uri uri,
+ long dataSize)
+ throws IOException
+ {
+ switch (this) {
+ case IMAGE: return new ImageSlide(context, uri, dataSize);
+ case GIF: return new GifSlide(context, uri, dataSize);
+ case AUDIO: return new AudioSlide(context, uri, dataSize);
+ case VIDEO: return new VideoSlide(context, uri, dataSize);
+ default: throw new AssertionError("unrecognized enum");
+ }
+ }
+ }
}
diff --git a/src/org/thoughtcrime/securesms/mms/AudioSlide.java b/src/org/thoughtcrime/securesms/mms/AudioSlide.java
index 68bc123bc2..78948e65c2 100644
--- a/src/org/thoughtcrime/securesms/mms/AudioSlide.java
+++ b/src/org/thoughtcrime/securesms/mms/AudioSlide.java
@@ -18,27 +18,25 @@ package org.thoughtcrime.securesms.mms;
import android.content.Context;
import android.content.res.Resources.Theme;
-import android.database.Cursor;
import android.net.Uri;
-import android.provider.MediaStore.Audio;
import android.support.annotation.DrawableRes;
import org.thoughtcrime.securesms.R;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.ResUtil;
import java.io.IOException;
+import ws.com.google.android.mms.ContentType;
import ws.com.google.android.mms.pdu.PduPart;
public class AudioSlide extends Slide {
- public AudioSlide(Context context, Uri uri) throws IOException, MediaTooLargeException {
- super(context, constructPartFromUri(context, uri));
+ public AudioSlide(Context context, Uri uri, long dataSize) throws IOException {
+ super(context, constructPartFromUri(context, uri, ContentType.AUDIO_UNSPECIFIED, dataSize));
}
- public AudioSlide(Context context, MasterSecret masterSecret, PduPart part) {
- super(context, masterSecret, part);
+ public AudioSlide(Context context, PduPart part) {
+ super(context, part);
}
@Override
@@ -55,30 +53,4 @@ public class AudioSlide extends Slide {
public @DrawableRes int getPlaceholderRes(Theme theme) {
return ResUtil.getDrawableRes(theme, R.attr.conversation_icon_attach_audio);
}
-
- public static PduPart constructPartFromUri(Context context, Uri uri) throws IOException, MediaTooLargeException {
- PduPart part = new PduPart();
-
- assertMediaSize(context, uri, MmsMediaConstraints.MAX_MESSAGE_SIZE);
-
- Cursor cursor = null;
-
- try {
- cursor = context.getContentResolver().query(uri, new String[]{Audio.Media.MIME_TYPE}, null, null, null);
-
- if (cursor != null && cursor.moveToFirst())
- part.setContentType(cursor.getString(0).getBytes());
- else
- throw new IOException("Unable to query content type.");
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
- part.setDataUri(uri);
- part.setContentId((System.currentTimeMillis()+"").getBytes());
- part.setName(("Audio" + System.currentTimeMillis()).getBytes());
-
- return part;
- }
}
diff --git a/src/org/thoughtcrime/securesms/mms/GifSlide.java b/src/org/thoughtcrime/securesms/mms/GifSlide.java
index 4c87c25742..9fcbb65e86 100644
--- a/src/org/thoughtcrime/securesms/mms/GifSlide.java
+++ b/src/org/thoughtcrime/securesms/mms/GifSlide.java
@@ -2,33 +2,18 @@ package org.thoughtcrime.securesms.mms;
import android.content.Context;
import android.net.Uri;
-import android.provider.MediaStore.Audio.Media;
-
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.util.BitmapDecodingException;
import java.io.IOException;
import ws.com.google.android.mms.pdu.PduPart;
public class GifSlide extends ImageSlide {
- public GifSlide(Context context, MasterSecret masterSecret, PduPart part) {
- super(context, masterSecret, part);
+ public GifSlide(Context context, PduPart part) {
+ super(context, part);
}
- public GifSlide(Context context, MasterSecret masterSecret, Uri uri)
- throws IOException, BitmapDecodingException, MediaTooLargeException
- {
- super(context, masterSecret, uri);
- assertMediaSize();
- }
-
- private void assertMediaSize() throws MediaTooLargeException, IOException {
- // TODO move assertion outside of slides and take available transport options into account
- assertMediaSize(context, getPart().getDataUri(), MediaConstraints.PUSH_CONSTRAINTS.getGifMaxSize());
- if (!MediaConstraints.PUSH_CONSTRAINTS.isSatisfied(context, masterSecret, part)) {
- throw new MediaTooLargeException("Media exceeds maximum message size.");
- }
+ public GifSlide(Context context, Uri uri, long dataSize) throws IOException {
+ super(context, uri, dataSize);
}
@Override public Uri getThumbnailUri() {
diff --git a/src/org/thoughtcrime/securesms/mms/ImageSlide.java b/src/org/thoughtcrime/securesms/mms/ImageSlide.java
index 95fea0352d..5720a53074 100644
--- a/src/org/thoughtcrime/securesms/mms/ImageSlide.java
+++ b/src/org/thoughtcrime/securesms/mms/ImageSlide.java
@@ -22,9 +22,6 @@ import android.net.Uri;
import android.support.annotation.DrawableRes;
import org.thoughtcrime.securesms.R;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.util.BitmapDecodingException;
-import org.thoughtcrime.securesms.util.MediaUtil;
import java.io.IOException;
@@ -34,12 +31,12 @@ import ws.com.google.android.mms.pdu.PduPart;
public class ImageSlide extends Slide {
private static final String TAG = ImageSlide.class.getSimpleName();
- public ImageSlide(Context context, MasterSecret masterSecret, PduPart part) {
- super(context, masterSecret, part);
+ public ImageSlide(Context context, PduPart part) {
+ super(context, part);
}
- public ImageSlide(Context context, MasterSecret masterSecret, Uri uri) throws IOException, BitmapDecodingException {
- super(context, masterSecret, constructPartFromUri(context, uri));
+ public ImageSlide(Context context, Uri uri, long size) throws IOException {
+ super(context, constructPartFromUri(context, uri, ContentType.IMAGE_JPEG, size));
}
@Override
@@ -62,20 +59,4 @@ public class ImageSlide extends Slide {
public boolean hasImage() {
return true;
}
-
- private static PduPart constructPartFromUri(Context context, Uri uri)
- throws IOException, BitmapDecodingException
- {
- PduPart part = new PduPart();
-
- final String mimeType = MediaUtil.getMimeType(context, uri);
-
- part.setDataUri(uri);
- part.setContentType((mimeType != null ? mimeType : ContentType.IMAGE_JPEG).getBytes());
- part.setContentId((System.currentTimeMillis()+"").getBytes());
- part.setName(("Image" + System.currentTimeMillis()).getBytes());
-
- return part;
- }
-
}
diff --git a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java
index f59ece7865..d505ebe6e8 100644
--- a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java
+++ b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java
@@ -27,16 +27,16 @@ public class PushMediaConstraints extends MediaConstraints {
@Override
public int getGifMaxSize() {
- return 1 * MB;
+ return 5 * MB;
}
@Override
public int getVideoMaxSize() {
- return MmsMediaConstraints.MAX_MESSAGE_SIZE;
+ return 100 * MB;
}
@Override
public int getAudioMaxSize() {
- return MmsMediaConstraints.MAX_MESSAGE_SIZE;
+ return 100 * MB;
}
}
diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java
index 7f52885292..60e925576d 100644
--- a/src/org/thoughtcrime/securesms/mms/Slide.java
+++ b/src/org/thoughtcrime/securesms/mms/Slide.java
@@ -21,8 +21,10 @@ import android.content.res.Resources.Theme;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.crypto.MasterSecret;
+import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@@ -32,20 +34,14 @@ import ws.com.google.android.mms.pdu.PduPart;
public abstract class Slide {
- protected final PduPart part;
- protected final Context context;
- protected MasterSecret masterSecret;
+ protected final PduPart part;
+ protected final Context context;
public Slide(Context context, @NonNull PduPart part) {
this.part = part;
this.context = context;
}
- public Slide(Context context, @NonNull MasterSecret masterSecret, @NonNull PduPart part) {
- this(context, part);
- this.masterSecret = masterSecret;
- }
-
public String getContentType() {
return new String(part.getContentType());
}
@@ -90,18 +86,24 @@ public abstract class Slide {
return !getPart().getPartId().isValid();
}
- protected static void assertMediaSize(Context context, Uri uri, long max)
- throws MediaTooLargeException, IOException
- {
- InputStream in = context.getContentResolver().openInputStream(uri);
- long size = 0;
- byte[] buffer = new byte[512];
- int read;
- while ((read = in.read(buffer)) != -1) {
- size += read;
- if (size > max) throw new MediaTooLargeException("Media exceeds maximum message size.");
- }
+ protected static PduPart constructPartFromUri(@NonNull Context context,
+ @NonNull Uri uri,
+ @NonNull String defaultMime,
+ long dataSize)
+ throws IOException
+ {
+ final PduPart part = new PduPart();
+ final String mimeType = MediaUtil.getMimeType(context, uri);
+ final String derivedMimeType = mimeType != null ? mimeType : defaultMime;
+
+ part.setDataSize(dataSize);
+ part.setDataUri(uri);
+ part.setContentType(derivedMimeType.getBytes());
+ part.setContentId((System.currentTimeMillis()+"").getBytes());
+ part.setName((MediaUtil.getDiscreteMimeType(derivedMimeType) + System.currentTimeMillis()).getBytes());
+
+ return part;
}
@Override
@@ -125,7 +127,4 @@ public abstract class Slide {
return Util.hashCode(getContentType(), hasAudio(), hasImage(),
hasVideo(), isDraft(), getUri(), getThumbnailUri(), getTransferProgress());
}
-
-
-
}
diff --git a/src/org/thoughtcrime/securesms/mms/SlideDeck.java b/src/org/thoughtcrime/securesms/mms/SlideDeck.java
index 794b63b895..66afee40be 100644
--- a/src/org/thoughtcrime/securesms/mms/SlideDeck.java
+++ b/src/org/thoughtcrime/securesms/mms/SlideDeck.java
@@ -47,10 +47,10 @@ public class SlideDeck {
this.slides.addAll(copy.getSlides());
}
- public SlideDeck(Context context, MasterSecret masterSecret, PduBody body) {
+ public SlideDeck(Context context, PduBody body) {
for (int i=0;i 1 ? sections[0] : null;
}