mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-24 08:19:03 +00:00
committed by
Moxie Marlinspike
parent
c4a37e38ab
commit
54a37cc658
@@ -20,10 +20,10 @@ import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -38,9 +38,9 @@ import android.widget.Toast;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.providers.CaptureProvider;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AttachmentManager {
|
||||
@@ -53,7 +53,7 @@ public class AttachmentManager {
|
||||
private final SlideDeck slideDeck;
|
||||
private final AttachmentListener attachmentListener;
|
||||
|
||||
private File captureFile;
|
||||
private Uri captureUri;
|
||||
|
||||
public AttachmentManager(Activity view, AttachmentListener listener) {
|
||||
this.attachmentView = view.findViewById(R.id.attachment_editor);
|
||||
@@ -92,12 +92,12 @@ public class AttachmentManager {
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (captureFile != null) captureFile.delete();
|
||||
captureFile = null;
|
||||
if (captureUri != null) CaptureProvider.getInstance(context).delete(captureUri);
|
||||
captureUri = null;
|
||||
}
|
||||
|
||||
public void setImage(Uri image) throws IOException, BitmapDecodingException {
|
||||
setMedia(new ImageSlide(context, image));
|
||||
public void setImage(MasterSecret masterSecret, Uri image) throws IOException, BitmapDecodingException {
|
||||
setMedia(new ImageSlide(context, masterSecret, image), masterSecret);
|
||||
}
|
||||
|
||||
public void setVideo(Uri video) throws IOException, MediaTooLargeException {
|
||||
@@ -108,20 +108,11 @@ public class AttachmentManager {
|
||||
setMedia(new AudioSlide(context, audio));
|
||||
}
|
||||
|
||||
public void setEncryptedImage(Uri uri, MasterSecret masterSecret) throws IOException, BitmapDecodingException {
|
||||
setMedia(new ImageSlide(context, masterSecret, uri), masterSecret);
|
||||
}
|
||||
|
||||
public void setMedia(final Slide slide) {
|
||||
setMedia(slide, null);
|
||||
}
|
||||
|
||||
public void setMedia(final Slide slide, @Nullable MasterSecret masterSecret) {
|
||||
Slide thumbnailSlide = slideDeck.getThumbnailSlide(context);
|
||||
if (thumbnailSlide != null && thumbnailSlide.isEncrypted()) {
|
||||
Uri dataUri = slideDeck.getThumbnailSlide(context).getPart().getDataUri();
|
||||
new File(dataUri.getPath()).delete();
|
||||
}
|
||||
slideDeck.clear();
|
||||
slideDeck.addSlide(slide);
|
||||
attachmentView.setVisibility(View.VISIBLE);
|
||||
@@ -137,20 +128,11 @@ public class AttachmentManager {
|
||||
return slideDeck;
|
||||
}
|
||||
|
||||
public File getCaptureFile() {
|
||||
return captureFile;
|
||||
}
|
||||
|
||||
public void capturePhoto(Activity activity, int requestCode) {
|
||||
public void setCaptureImage(MasterSecret masterSecret, Bitmap bitmap) {
|
||||
try {
|
||||
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
|
||||
if (captureIntent.resolveActivity(activity.getPackageManager()) != null) {
|
||||
captureFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), ".jpg", activity.getExternalFilesDir(null));
|
||||
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(captureFile));
|
||||
activity.startActivityForResult(captureIntent, requestCode);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
captureUri = CaptureProvider.getInstance(context).create(masterSecret, bitmap);
|
||||
setImage(masterSecret, captureUri);
|
||||
} catch (IOException | BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
@@ -204,6 +186,6 @@ public class AttachmentManager {
|
||||
}
|
||||
|
||||
public interface AttachmentListener {
|
||||
public void onAttachmentChanged();
|
||||
void onAttachmentChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ public class AttachmentTypeSelectorAdapter extends ArrayAdapter<AttachmentTypeSe
|
||||
public static final int ADD_VIDEO = 2;
|
||||
public static final int ADD_SOUND = 3;
|
||||
public static final int ADD_CONTACT_INFO = 4;
|
||||
public static final int TAKE_PHOTO = 5;
|
||||
|
||||
private final Context context;
|
||||
|
||||
@@ -72,11 +71,10 @@ public class AttachmentTypeSelectorAdapter extends ArrayAdapter<AttachmentTypeSe
|
||||
|
||||
private static List<IconListItem> getItemList(Context context) {
|
||||
List<IconListItem> data = new ArrayList<>(4);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_take_photo), ResUtil.getDrawableRes(context, R.attr.conversation_attach_photo), TAKE_PHOTO);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_picture), ResUtil.getDrawableRes(context, R.attr.conversation_attach_image), ADD_IMAGE);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_video), ResUtil.getDrawableRes(context, R.attr.conversation_attach_video), ADD_VIDEO);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_audio), ResUtil.getDrawableRes(context, R.attr.conversation_attach_sound), ADD_SOUND);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_contact), ResUtil.getDrawableRes(context, R.attr.conversation_attach_contact_info), ADD_CONTACT_INFO);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_picture), ResUtil.getDrawableRes(context, R.attr.conversation_attach_image), ADD_IMAGE);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_video), ResUtil.getDrawableRes(context, R.attr.conversation_attach_video), ADD_VIDEO);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_audio), ResUtil.getDrawableRes(context, R.attr.conversation_attach_sound), ADD_SOUND);
|
||||
addItem(data, context.getString(R.string.AttachmentTypeSelectorAdapter_contact), ResUtil.getDrawableRes(context, R.attr.conversation_attach_contact_info), ADD_CONTACT_INFO);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -20,36 +20,25 @@ import android.content.Context;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
|
||||
public class ImageSlide extends Slide {
|
||||
private static final String TAG = ImageSlide.class.getSimpleName();
|
||||
private boolean encrypted = false;
|
||||
|
||||
public ImageSlide(Context context, MasterSecret masterSecret, PduPart part) {
|
||||
super(context, masterSecret, part);
|
||||
}
|
||||
|
||||
public ImageSlide(Context context, Uri uri) throws IOException, BitmapDecodingException {
|
||||
this(context, null, uri);
|
||||
}
|
||||
|
||||
public ImageSlide(Context context, MasterSecret masterSecret, Uri uri) throws IOException, BitmapDecodingException {
|
||||
super(context, masterSecret, constructPartFromByteArrayAndUri(uri, decryptContent(uri, masterSecret), masterSecret != null));
|
||||
encrypted = masterSecret != null;
|
||||
super(context, masterSecret, constructPartFromUri(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,32 +62,12 @@ public class ImageSlide extends Slide {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypted() {
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
private static byte[] decryptContent(Uri uri, MasterSecret masterSecret) {
|
||||
try {
|
||||
if (masterSecret != null) {
|
||||
InputStream inputStream = new DecryptingPartInputStream(new File(uri.getPath()), masterSecret);
|
||||
return Util.readFully(inputStream);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PduPart constructPartFromByteArrayAndUri(Uri uri, @Nullable byte[] data, boolean encrypted)
|
||||
private static PduPart constructPartFromUri(Uri uri)
|
||||
throws IOException, BitmapDecodingException
|
||||
{
|
||||
PduPart part = new PduPart();
|
||||
|
||||
part.setDataUri(uri);
|
||||
if (data != null)
|
||||
part.setData(data);
|
||||
part.setEncrypted(encrypted);
|
||||
part.setContentType(ContentType.IMAGE_JPEG.getBytes());
|
||||
part.setContentId((System.currentTimeMillis()+"").getBytes());
|
||||
part.setName(("Image" + System.currentTimeMillis()).getBytes());
|
||||
|
||||
@@ -5,13 +5,12 @@ import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.PartDatabase;
|
||||
import org.thoughtcrime.securesms.providers.CaptureProvider;
|
||||
import org.thoughtcrime.securesms.providers.PartProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -22,8 +21,9 @@ public class PartAuthority {
|
||||
private static final Uri PART_CONTENT_URI = Uri.parse(PART_URI_STRING);
|
||||
private static final Uri THUMB_CONTENT_URI = Uri.parse(THUMB_URI_STRING);
|
||||
|
||||
private static final int PART_ROW = 1;
|
||||
private static final int THUMB_ROW = 2;
|
||||
private static final int PART_ROW = 1;
|
||||
private static final int THUMB_ROW = 2;
|
||||
private static final int CAPTURE_ROW = 3;
|
||||
|
||||
private static final UriMatcher uriMatcher;
|
||||
|
||||
@@ -31,28 +31,25 @@ 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);
|
||||
}
|
||||
|
||||
public static InputStream getPartStream(Context context, MasterSecret masterSecret, Uri uri)
|
||||
throws IOException
|
||||
{
|
||||
PartDatabase partDatabase = DatabaseFactory.getPartDatabase(context);
|
||||
int match = uriMatcher.match(uri);
|
||||
|
||||
int match = uriMatcher.match(uri);
|
||||
try {
|
||||
switch (match) {
|
||||
case PART_ROW:
|
||||
PartUriParser partUri = new PartUriParser(uri);
|
||||
return partDatabase.getPartStream(masterSecret, partUri.getPartId());
|
||||
return DatabaseFactory.getPartDatabase(context).getPartStream(masterSecret, partUri.getPartId());
|
||||
case THUMB_ROW:
|
||||
partUri = new PartUriParser(uri);
|
||||
return partDatabase.getThumbnailStream(masterSecret, partUri.getPartId());
|
||||
return DatabaseFactory.getPartDatabase(context).getThumbnailStream(masterSecret, partUri.getPartId());
|
||||
case CAPTURE_ROW:
|
||||
return CaptureProvider.getInstance(context).getStream(masterSecret, ContentUris.parseId(uri));
|
||||
default:
|
||||
String tempMediaDir = context.getDir("media", Context.MODE_PRIVATE).getPath();
|
||||
if (uri.getPath().startsWith(tempMediaDir))
|
||||
return new DecryptingPartInputStream(new File(uri.getPath()), masterSecret);
|
||||
else
|
||||
return context.getContentResolver().openInputStream(uri);
|
||||
return context.getContentResolver().openInputStream(uri);
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
throw new IOException(se);
|
||||
|
||||
@@ -66,10 +66,6 @@ public abstract class Slide {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEncrypted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public PduPart getPart() {
|
||||
return part;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user