unjankify incoming media sharing

Closes #4374
Fixes #3989
// FREEBIE
This commit is contained in:
Jake McGinty
2015-10-15 14:40:45 -07:00
committed by Moxie Marlinspike
parent 60ab71099f
commit 59f2446a2b
7 changed files with 216 additions and 109 deletions

View File

@@ -38,9 +38,11 @@ import org.thoughtcrime.securesms.components.AudioView;
import org.thoughtcrime.securesms.components.RemovableMediaView;
import org.thoughtcrime.securesms.components.ThumbnailView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.providers.CaptureProvider;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.whispersystems.libaxolotl.util.guava.Optional;
import java.io.IOException;
@@ -53,18 +55,17 @@ public class AttachmentManager {
private final @NonNull RemovableMediaView removableMediaView;
private final @NonNull ThumbnailView thumbnail;
private final @NonNull AudioView audioView;
private final @NonNull SlideDeck slideDeck;
private final @NonNull AttachmentListener attachmentListener;
private Uri captureUri;
private @NonNull Optional<Slide> slide = Optional.absent();
private @Nullable Uri captureUri;
public AttachmentManager(@NonNull Activity view, @NonNull AttachmentListener listener) {
this.attachmentView = view.findViewById(R.id.attachment_editor);
this.thumbnail = (ThumbnailView) view.findViewById(R.id.attachment_thumbnail);
this.audioView = (AudioView) view.findViewById(R.id.attachment_audio);
this.removableMediaView = (RemovableMediaView) view.findViewById(R.id.removable_media_view);
this.slideDeck = new SlideDeck();
this.context = view;
public AttachmentManager(@NonNull Activity activity, @NonNull AttachmentListener listener) {
this.attachmentView = ViewUtil.findById(activity, R.id.attachment_editor);
this.thumbnail = ViewUtil.findById(activity, R.id.attachment_thumbnail);
this.audioView = ViewUtil.findById(activity, R.id.attachment_audio);
this.removableMediaView = ViewUtil.findById(activity, R.id.removable_media_view);
this.context = activity;
this.attachmentListener = listener;
removableMediaView.setRemoveClickListener(new RemoveButtonListener());
@@ -76,11 +77,13 @@ public class AttachmentManager {
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
slideDeck.clear();
slide = Optional.absent();
thumbnail.clear();
attachmentView.setVisibility(View.GONE);
attachmentListener.onAttachmentChanged();
@@ -92,26 +95,39 @@ public class AttachmentManager {
}
public void cleanup() {
if (captureUri != null) CaptureProvider.getInstance(context).delete(captureUri);
cleanup(captureUri);
cleanup(getSlideUri());
captureUri = null;
slide = Optional.absent();
}
public void setMedia(@NonNull final MasterSecret masterSecret,
@NonNull final Uri uri,
@NonNull final MediaType mediaType,
@NonNull final MediaConstraints constraints,
final boolean isCapture)
private void cleanup(final @Nullable Uri uri) {
if (uri != null && PersistentBlobProvider.isAuthority(context, uri)) {
Log.w(TAG, "cleaning up " + uri);
PersistentBlobProvider.getInstance(context).delete(uri);
}
}
private void setSlide(@NonNull Slide slide) {
if (getSlideUri() != null) cleanup(getSlideUri());
if (captureUri != null && slide.getUri() != captureUri) cleanup(captureUri);
this.captureUri = null;
this.slide = Optional.of(slide);
}
public void setMedia(@NonNull final MasterSecret masterSecret,
@NonNull final Uri uri,
@NonNull final MediaType mediaType,
@NonNull final MediaConstraints constraints)
{
new AsyncTask<Void, Void, Slide>() {
@Override
protected void onPreExecute() {
slideDeck.clear();
thumbnail.clear();
thumbnail.showProgressSpinner();
attachmentView.setVisibility(View.VISIBLE);
if (isCapture) captureUri = uri;
if (!uri.equals(captureUri)) cleanup();
}
@Override
@@ -141,7 +157,7 @@ public class AttachmentManager {
R.string.ConversationActivity_attachment_exceeds_size_limits,
Toast.LENGTH_SHORT).show();
} else {
slideDeck.addSlide(slide);
setSlide(slide);
attachmentView.setVisibility(View.VISIBLE);
if (slide.hasAudio()) {
@@ -162,9 +178,10 @@ public class AttachmentManager {
return attachmentView.getVisibility() == View.VISIBLE;
}
public @NonNull SlideDeck getSlideDeck() {
return slideDeck;
public @NonNull SlideDeck buildSlideDeck() {
SlideDeck deck = new SlideDeck();
if (slide.isPresent()) deck.addSlide(slide.get());
return deck;
}
public static void selectVideo(Activity activity, int requestCode) {
@@ -184,7 +201,11 @@ public class AttachmentManager {
activity.startActivityForResult(intent, requestCode);
}
public Uri getCaptureUri() {
private @Nullable Uri getSlideUri() {
return slide.isPresent() ? slide.get().getUri() : null;
}
public @Nullable Uri getCaptureUri() {
return captureUri;
}
@@ -192,7 +213,10 @@ public class AttachmentManager {
try {
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (captureIntent.resolveActivity(activity.getPackageManager()) != null) {
captureUri = CaptureProvider.getInstance(context).createForExternal(recipients);
if (captureUri == null) {
captureUri = PersistentBlobProvider.getInstance(context).createForExternal(recipients);
}
Log.w(TAG, "captureUri path is " + captureUri.getPath());
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, captureUri);
activity.startActivityForResult(captureIntent, requestCode);
}
@@ -237,8 +261,8 @@ public class AttachmentManager {
private class RemoveButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
clear();
cleanup();
clear();
}
}

View File

@@ -9,7 +9,7 @@ import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.providers.CaptureProvider;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.providers.PartProvider;
import org.thoughtcrime.securesms.providers.SingleUseBlobProvider;
@@ -25,7 +25,7 @@ public class PartAuthority {
private static final int PART_ROW = 1;
private static final int THUMB_ROW = 2;
private static final int CAPTURE_ROW = 3;
private static final int PERSISTENT_ROW = 3;
private static final int SINGLE_USE_ROW = 4;
private static final UriMatcher uriMatcher;
@@ -34,7 +34,7 @@ public class PartAuthority {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("org.thoughtcrime.securesms", "part/*/#", PART_ROW);
uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/*/#", THUMB_ROW);
uriMatcher.addURI(CaptureProvider.AUTHORITY, CaptureProvider.EXPECTED_PATH, CAPTURE_ROW);
uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH, PERSISTENT_ROW);
uriMatcher.addURI(SingleUseBlobProvider.AUTHORITY, SingleUseBlobProvider.PATH, SINGLE_USE_ROW);
}
@@ -50,8 +50,8 @@ public class PartAuthority {
case THUMB_ROW:
partUri = new PartUriParser(uri);
return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(masterSecret, partUri.getPartId());
case CAPTURE_ROW:
return CaptureProvider.getInstance(context).getStream(masterSecret, ContentUris.parseId(uri));
case PERSISTENT_ROW:
return PersistentBlobProvider.getInstance(context).getStream(masterSecret, ContentUris.parseId(uri));
case SINGLE_USE_ROW:
return SingleUseBlobProvider.getInstance().getStream(ContentUris.parseId(uri));
default: