mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Add full send attachments.
This commit is contained in:
committed by
Cody Henthorne
parent
3879a8ffdb
commit
a966812bfc
@@ -17,25 +17,19 @@
|
||||
package org.thoughtcrime.securesms.mms;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
@@ -50,7 +44,6 @@ import org.signal.core.util.concurrent.SettableFuture;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.components.DocumentView;
|
||||
import org.thoughtcrime.securesms.components.RemovableEditableMediaView;
|
||||
@@ -58,7 +51,6 @@ import org.thoughtcrime.securesms.components.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalMapView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalPlace;
|
||||
import org.thoughtcrime.securesms.conversation.MessageSendType;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
import org.thoughtcrime.securesms.database.MediaTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
|
||||
@@ -256,149 +248,6 @@ public class AttachmentManager {
|
||||
attachmentListener.onAttachmentChanged();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public ListenableFuture<Boolean> setMedia(@NonNull final RequestManager requestManager,
|
||||
@NonNull final Uri uri,
|
||||
@NonNull final SlideFactory.MediaType mediaType,
|
||||
@NonNull final MediaConstraints constraints,
|
||||
final int width,
|
||||
final int height)
|
||||
{
|
||||
inflateStub();
|
||||
|
||||
final SettableFuture<Boolean> result = new SettableFuture<>();
|
||||
|
||||
new AsyncTask<Void, Void, Slide>() {
|
||||
private boolean areConstraintsSatisfied = false;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
thumbnail.clear(requestManager);
|
||||
thumbnail.showProgressSpinner();
|
||||
attachmentViewStub.get().setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Slide doInBackground(Void... params) {
|
||||
Slide slide;
|
||||
try {
|
||||
if (PartAuthority.isLocalUri(uri)) {
|
||||
slide = getManuallyCalculatedSlideInfo(uri, width, height);
|
||||
} else {
|
||||
Slide result = getContentResolverSlideInfo(uri, width, height);
|
||||
slide = (result == null) ? getManuallyCalculatedSlideInfo(uri, width, height) : result;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
this.areConstraintsSatisfied = areConstraintsSatisfied(context, slide, constraints);
|
||||
return slide;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(@Nullable final Slide slide) {
|
||||
if (slide == null) {
|
||||
attachmentViewStub.get().setVisibility(View.GONE);
|
||||
Toast.makeText(context,
|
||||
R.string.ConversationActivity_sorry_there_was_an_error_setting_your_attachment,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
result.set(false);
|
||||
} else if (!areConstraintsSatisfied) {
|
||||
attachmentViewStub.get().setVisibility(View.GONE);
|
||||
Toast.makeText(context,
|
||||
R.string.ConversationActivity_attachment_exceeds_size_limits,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
result.set(false);
|
||||
} else {
|
||||
setSlide(slide);
|
||||
attachmentViewStub.get().setVisibility(View.VISIBLE);
|
||||
|
||||
if (slide.hasAudio()) {
|
||||
audioView.setAudio((AudioSlide) slide, null, false, false);
|
||||
removableMediaView.display(audioView, false);
|
||||
result.set(true);
|
||||
} else if (slide.hasDocument()) {
|
||||
documentView.setDocument((DocumentSlide) slide, false);
|
||||
removableMediaView.display(documentView, false);
|
||||
result.set(true);
|
||||
} else {
|
||||
Attachment attachment = slide.asAttachment();
|
||||
result.deferTo(thumbnail.setImageResource(requestManager, slide, false, true, attachment.width, attachment.height));
|
||||
removableMediaView.display(thumbnail, mediaType == SlideFactory.MediaType.IMAGE);
|
||||
}
|
||||
|
||||
attachmentListener.onAttachmentChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Slide getContentResolverSlideInfo(Uri uri, int width, int height) {
|
||||
Cursor cursor = null;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, null, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
String fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
|
||||
long fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(OpenableColumns.SIZE));
|
||||
String mimeType = context.getContentResolver().getType(uri);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
Pair<Integer, Integer> dimens = MediaUtil.getDimensions(context, mimeType, uri);
|
||||
width = dimens.first;
|
||||
height = dimens.second;
|
||||
}
|
||||
|
||||
Log.d(TAG, "remote slide with size " + fileSize + " took " + (System.currentTimeMillis() - start) + "ms");
|
||||
return mediaType.createSlide(context, uri, fileName, mimeType, null, fileSize, width, height, false, null);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private @NonNull Slide getManuallyCalculatedSlideInfo(Uri uri, int width, int height) throws IOException {
|
||||
long start = System.currentTimeMillis();
|
||||
Long mediaSize = null;
|
||||
String fileName = null;
|
||||
String mimeType = null;
|
||||
boolean gif = false;
|
||||
AttachmentTable.TransformProperties transformProperties = null;
|
||||
|
||||
if (PartAuthority.isLocalUri(uri)) {
|
||||
mediaSize = PartAuthority.getAttachmentSize(context, uri);
|
||||
fileName = PartAuthority.getAttachmentFileName(context, uri);
|
||||
mimeType = PartAuthority.getAttachmentContentType(context, uri);
|
||||
gif = PartAuthority.getAttachmentIsVideoGif(context, uri);
|
||||
transformProperties = PartAuthority.getAttachmentTransformProperties(uri);
|
||||
}
|
||||
|
||||
if (mediaSize == null) {
|
||||
mediaSize = MediaUtil.getMediaSize(context, uri);
|
||||
}
|
||||
|
||||
if (mimeType == null) {
|
||||
mimeType = MediaUtil.getMimeType(context, uri);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
Pair<Integer, Integer> dimens = MediaUtil.getDimensions(context, mimeType, uri);
|
||||
width = dimens.first;
|
||||
height = dimens.second;
|
||||
}
|
||||
|
||||
Log.d(TAG, "local slide with size " + mediaSize + " took " + (System.currentTimeMillis() - start) + "ms");
|
||||
return mediaType.createSlide(context, uri, fileName, mimeType, null, mediaSize, width, height, gif, transformProperties);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isAttachmentPresent() {
|
||||
return attachmentViewStub.resolved() && attachmentViewStub.get().getVisibility() == View.VISIBLE;
|
||||
}
|
||||
@@ -531,16 +380,6 @@ public class AttachmentManager {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private boolean areConstraintsSatisfied(final @NonNull Context context,
|
||||
final @Nullable Slide slide,
|
||||
final @NonNull MediaConstraints constraints)
|
||||
{
|
||||
return slide == null ||
|
||||
constraints.isSatisfied(context, slide.asAttachment()) ||
|
||||
constraints.canResize(slide.asAttachment());
|
||||
}
|
||||
|
||||
private void previewImageDraft(final @NonNull Slide slide) {
|
||||
if (MediaPreviewV2Fragment.isContentTypeSupported(slide.getContentType()) && slide.getUri() != null) {
|
||||
MediaIntentFactory.MediaPreviewArgs args = new MediaIntentFactory.MediaPreviewArgs(
|
||||
|
||||
@@ -230,34 +230,7 @@ public abstract class Slide {
|
||||
}
|
||||
|
||||
public @NonNull Optional<String> getFileType(@NonNull Context context) {
|
||||
Optional<String> fileName = getFileName();
|
||||
|
||||
if (fileName.isPresent()) {
|
||||
String fileType = getFileType(fileName);
|
||||
if (!fileType.isEmpty()) {
|
||||
return Optional.of(fileType);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.ofNullable(MediaUtil.getExtension(context, getUri()));
|
||||
}
|
||||
|
||||
private static @NonNull String getFileType(Optional<String> fileName) {
|
||||
if (!fileName.isPresent()) return "";
|
||||
|
||||
String[] parts = fileName.get().split("\\.");
|
||||
|
||||
if (parts.length < 2) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String suffix = parts[parts.length - 1];
|
||||
|
||||
if (suffix.length() <= 3) {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
return "";
|
||||
return MediaUtil.getFileType(context, getFileName(), getUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user