mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
parent
1c8c6d5f85
commit
e96bf2bdc7
@ -165,6 +165,9 @@
|
|||||||
<data android:mimeType="image/*" />
|
<data android:mimeType="image/*" />
|
||||||
<data android:mimeType="text/plain" />
|
<data android:mimeType="text/plain" />
|
||||||
<data android:mimeType="video/*" />
|
<data android:mimeType="video/*" />
|
||||||
|
<data android:mimeType="application/*"/>
|
||||||
|
<data android:mimeType="text/*"/>
|
||||||
|
<data android:mimeType="*/*"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
|
@ -876,7 +876,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
final String draftText = getIntent().getStringExtra(TEXT_EXTRA);
|
final String draftText = getIntent().getStringExtra(TEXT_EXTRA);
|
||||||
final Uri draftMedia = getIntent().getData();
|
final Uri draftMedia = getIntent().getData();
|
||||||
final MediaType draftMediaType = MediaType.from(getIntent().getType());
|
final MediaType draftMediaType = MediaType.from(getIntent().getType());
|
||||||
|
|
||||||
if (draftText != null) composeText.setText(draftText);
|
if (draftText != null) composeText.setText(draftText);
|
||||||
if (draftMedia != null && draftMediaType != null) setMedia(draftMedia, draftMediaType);
|
if (draftMedia != null && draftMediaType != null) setMedia(draftMedia, draftMediaType);
|
||||||
|
|
||||||
@ -1605,7 +1605,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onImageCapture(@NonNull final byte[] imageBytes) {
|
public void onImageCapture(@NonNull final byte[] imageBytes) {
|
||||||
setMedia(PersistentBlobProvider.getInstance(this)
|
setMedia(PersistentBlobProvider.getInstance(this)
|
||||||
.create(masterSecret, imageBytes, MediaUtil.IMAGE_JPEG),
|
.create(masterSecret, imageBytes, MediaUtil.IMAGE_JPEG, null),
|
||||||
MediaType.IMAGE);
|
MediaType.IMAGE);
|
||||||
quickAttachmentDrawer.hide(false);
|
quickAttachmentDrawer.hide(false);
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,12 @@ package org.thoughtcrime.securesms;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.provider.OpenableColumns;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -235,7 +237,24 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PersistentBlobProvider.getInstance(context).create(masterSecret, inputStream, mimeType);
|
Cursor cursor = getContentResolver().query(uris[0], new String[] {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null);
|
||||||
|
String fileName = null;
|
||||||
|
Long fileSize = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
try {
|
||||||
|
fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
|
||||||
|
fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(OpenableColumns.SIZE));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) cursor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PersistentBlobProvider.getInstance(context).create(masterSecret, inputStream, mimeType, fileName, fileSize);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.w(TAG, ioe);
|
Log.w(TAG, ioe);
|
||||||
return null;
|
return null;
|
||||||
|
@ -56,7 +56,7 @@ public class AudioRecorder {
|
|||||||
|
|
||||||
captureUri = blobProvider.create(masterSecret,
|
captureUri = blobProvider.create(masterSecret,
|
||||||
new ParcelFileDescriptor.AutoCloseInputStream(fds[0]),
|
new ParcelFileDescriptor.AutoCloseInputStream(fds[0]),
|
||||||
MediaUtil.AUDIO_AAC);
|
MediaUtil.AUDIO_AAC, null, null);
|
||||||
audioCodec = new AudioCodec();
|
audioCodec = new AudioCodec();
|
||||||
|
|
||||||
audioCodec.start(new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]));
|
audioCodec.start(new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]));
|
||||||
|
@ -190,7 +190,7 @@ public class AttachmentManager {
|
|||||||
public void onSuccess(@NonNull Bitmap result) {
|
public void onSuccess(@NonNull Bitmap result) {
|
||||||
byte[] blob = BitmapUtil.toByteArray(result);
|
byte[] blob = BitmapUtil.toByteArray(result);
|
||||||
Uri uri = PersistentBlobProvider.getInstance(context)
|
Uri uri = PersistentBlobProvider.getInstance(context)
|
||||||
.create(masterSecret, blob, MediaUtil.IMAGE_PNG);
|
.create(masterSecret, blob, MediaUtil.IMAGE_PNG, null);
|
||||||
LocationSlide locationSlide = new LocationSlide(context, uri, blob.length, place);
|
LocationSlide locationSlide = new LocationSlide(context, uri, blob.length, place);
|
||||||
|
|
||||||
setSlide(locationSlide);
|
setSlide(locationSlide);
|
||||||
@ -206,7 +206,7 @@ public class AttachmentManager {
|
|||||||
{
|
{
|
||||||
inflateStub();
|
inflateStub();
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Slide>() {
|
new AsyncTask<Void, Void, Slide>() {
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
thumbnail.clear();
|
thumbnail.clear();
|
||||||
@ -285,11 +285,23 @@ public class AttachmentManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull Slide getManuallyCalculatedSlideInfo(Uri uri) throws IOException {
|
private @NonNull Slide getManuallyCalculatedSlideInfo(Uri uri) throws IOException {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
long mediaSize = MediaUtil.getMediaSize(context, masterSecret, uri);
|
Long mediaSize = null;
|
||||||
|
String fileName = null;
|
||||||
|
String mimeType = null;
|
||||||
|
|
||||||
|
if (PartAuthority.isLocalUri(uri)) {
|
||||||
|
mediaSize = PartAuthority.getAttachmentSize(context, masterSecret, uri);
|
||||||
|
fileName = PartAuthority.getAttachmentFileName(context, masterSecret, uri);
|
||||||
|
mimeType = PartAuthority.getAttachmentContentType(context, masterSecret, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mediaSize == null) {
|
||||||
|
mediaSize = MediaUtil.getMediaSize(context, masterSecret, uri);
|
||||||
|
}
|
||||||
|
|
||||||
Log.w(TAG, "local slide with size " + mediaSize + " took " + (System.currentTimeMillis() - start) + "ms");
|
Log.w(TAG, "local slide with size " + mediaSize + " took " + (System.currentTimeMillis() - start) + "ms");
|
||||||
return mediaType.createSlide(context, uri, null, null, mediaSize);
|
return mediaType.createSlide(context, uri, fileName, mimeType, mediaSize);
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
@ -466,7 +478,8 @@ public class AttachmentManager {
|
|||||||
if (MediaUtil.isImageType(mimeType)) return IMAGE;
|
if (MediaUtil.isImageType(mimeType)) return IMAGE;
|
||||||
if (MediaUtil.isAudioType(mimeType)) return AUDIO;
|
if (MediaUtil.isAudioType(mimeType)) return AUDIO;
|
||||||
if (MediaUtil.isVideoType(mimeType)) return VIDEO;
|
if (MediaUtil.isVideoType(mimeType)) return VIDEO;
|
||||||
return null;
|
|
||||||
|
return DOCUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@ import android.content.Context;
|
|||||||
import android.content.UriMatcher;
|
import android.content.UriMatcher;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
@ -34,7 +36,8 @@ public class PartAuthority {
|
|||||||
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||||
uriMatcher.addURI("org.thoughtcrime.securesms", "part/*/#", PART_ROW);
|
uriMatcher.addURI("org.thoughtcrime.securesms", "part/*/#", PART_ROW);
|
||||||
uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/*/#", THUMB_ROW);
|
uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/*/#", THUMB_ROW);
|
||||||
uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH, PERSISTENT_ROW);
|
uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH_OLD, PERSISTENT_ROW);
|
||||||
|
uriMatcher.addURI(PersistentBlobProvider.AUTHORITY, PersistentBlobProvider.EXPECTED_PATH_NEW, PERSISTENT_ROW);
|
||||||
uriMatcher.addURI(SingleUseBlobProvider.AUTHORITY, SingleUseBlobProvider.PATH, SINGLE_USE_ROW);
|
uriMatcher.addURI(SingleUseBlobProvider.AUTHORITY, SingleUseBlobProvider.PATH, SINGLE_USE_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,24 +47,71 @@ public class PartAuthority {
|
|||||||
int match = uriMatcher.match(uri);
|
int match = uriMatcher.match(uri);
|
||||||
try {
|
try {
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PART_ROW:
|
case PART_ROW: return DatabaseFactory.getAttachmentDatabase(context).getAttachmentStream(masterSecret, new PartUriParser(uri).getPartId());
|
||||||
PartUriParser partUri = new PartUriParser(uri);
|
case THUMB_ROW: return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(masterSecret, new PartUriParser(uri).getPartId());
|
||||||
return DatabaseFactory.getAttachmentDatabase(context).getAttachmentStream(masterSecret, partUri.getPartId());
|
case PERSISTENT_ROW: return PersistentBlobProvider.getInstance(context).getStream(masterSecret, ContentUris.parseId(uri));
|
||||||
case THUMB_ROW:
|
case SINGLE_USE_ROW: return SingleUseBlobProvider.getInstance().getStream(ContentUris.parseId(uri));
|
||||||
partUri = new PartUriParser(uri);
|
default: return context.getContentResolver().openInputStream(uri);
|
||||||
return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(masterSecret, partUri.getPartId());
|
|
||||||
case PERSISTENT_ROW:
|
|
||||||
return PersistentBlobProvider.getInstance(context).getStream(masterSecret, ContentUris.parseId(uri));
|
|
||||||
case SINGLE_USE_ROW:
|
|
||||||
return SingleUseBlobProvider.getInstance().getStream(ContentUris.parseId(uri));
|
|
||||||
default:
|
|
||||||
return context.getContentResolver().openInputStream(uri);
|
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw new IOException(se);
|
throw new IOException(se);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable String getAttachmentFileName(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Uri uri) {
|
||||||
|
int match = uriMatcher.match(uri);
|
||||||
|
|
||||||
|
switch (match) {
|
||||||
|
case THUMB_ROW:
|
||||||
|
case PART_ROW:
|
||||||
|
Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(masterSecret, new PartUriParser(uri).getPartId());
|
||||||
|
|
||||||
|
if (attachment != null) return attachment.getFileName();
|
||||||
|
else return null;
|
||||||
|
case PERSISTENT_ROW:
|
||||||
|
return PersistentBlobProvider.getFileName(context, masterSecret, uri);
|
||||||
|
case SINGLE_USE_ROW:
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable Long getAttachmentSize(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Uri uri) {
|
||||||
|
int match = uriMatcher.match(uri);
|
||||||
|
|
||||||
|
switch (match) {
|
||||||
|
case THUMB_ROW:
|
||||||
|
case PART_ROW:
|
||||||
|
Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(masterSecret, new PartUriParser(uri).getPartId());
|
||||||
|
|
||||||
|
if (attachment != null) return attachment.getSize();
|
||||||
|
else return null;
|
||||||
|
case PERSISTENT_ROW:
|
||||||
|
return PersistentBlobProvider.getFileSize(context, uri);
|
||||||
|
case SINGLE_USE_ROW:
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable String getAttachmentContentType(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Uri uri) {
|
||||||
|
int match = uriMatcher.match(uri);
|
||||||
|
|
||||||
|
switch (match) {
|
||||||
|
case THUMB_ROW:
|
||||||
|
case PART_ROW:
|
||||||
|
Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(masterSecret, new PartUriParser(uri).getPartId());
|
||||||
|
|
||||||
|
if (attachment != null) return attachment.getContentType();
|
||||||
|
else return null;
|
||||||
|
case PERSISTENT_ROW:
|
||||||
|
return PersistentBlobProvider.getMimeType(context, uri);
|
||||||
|
case SINGLE_USE_ROW:
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Uri getAttachmentPublicUri(Uri uri) {
|
public static Uri getAttachmentPublicUri(Uri uri) {
|
||||||
PartUriParser partUri = new PartUriParser(uri);
|
PartUriParser partUri = new PartUriParser(uri);
|
||||||
return PartProvider.getContentUri(partUri.getPartId());
|
return PartProvider.getContentUri(partUri.getPartId());
|
||||||
|
@ -12,8 +12,10 @@ import android.webkit.MimeTypeMap;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
|
||||||
import org.thoughtcrime.securesms.crypto.EncryptingPartOutputStream;
|
import org.thoughtcrime.securesms.crypto.EncryptingPartOutputStream;
|
||||||
|
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.whispersystems.libsignal.InvalidMessageException;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -30,15 +32,23 @@ public class PersistentBlobProvider {
|
|||||||
|
|
||||||
private static final String TAG = PersistentBlobProvider.class.getSimpleName();
|
private static final String TAG = PersistentBlobProvider.class.getSimpleName();
|
||||||
|
|
||||||
private static final String URI_STRING = "content://org.thoughtcrime.securesms/capture";
|
private static final String URI_STRING = "content://org.thoughtcrime.securesms/capture-new";
|
||||||
public static final Uri CONTENT_URI = Uri.parse(URI_STRING);
|
public static final Uri CONTENT_URI = Uri.parse(URI_STRING);
|
||||||
public static final String AUTHORITY = "org.thoughtcrime.securesms";
|
public static final String AUTHORITY = "org.thoughtcrime.securesms";
|
||||||
public static final String EXPECTED_PATH = "capture/*/*/#";
|
public static final String EXPECTED_PATH_OLD = "capture/*/*/#";
|
||||||
|
public static final String EXPECTED_PATH_NEW = "capture-new/*/*/*/*/#";
|
||||||
|
|
||||||
private static final int MIMETYPE_PATH_SEGMENT = 1;
|
private static final int MIMETYPE_PATH_SEGMENT = 1;
|
||||||
|
private static final int FILENAME_PATH_SEGMENT = 2;
|
||||||
|
private static final int FILESIZE_PATH_SEGMENT = 3;
|
||||||
|
|
||||||
private static final String BLOB_EXTENSION = "blob";
|
private static final String BLOB_EXTENSION = "blob";
|
||||||
private static final int MATCH = 1;
|
private static final int MATCH_OLD = 1;
|
||||||
|
private static final int MATCH_NEW = 2;
|
||||||
|
|
||||||
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH) {{
|
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH) {{
|
||||||
addURI(AUTHORITY, EXPECTED_PATH, MATCH);
|
addURI(AUTHORITY, EXPECTED_PATH_OLD, MATCH_OLD);
|
||||||
|
addURI(AUTHORITY, EXPECTED_PATH_NEW, MATCH_NEW);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private static volatile PersistentBlobProvider instance;
|
private static volatile PersistentBlobProvider instance;
|
||||||
@ -63,26 +73,37 @@ public class PersistentBlobProvider {
|
|||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri create(@NonNull MasterSecret masterSecret,
|
public Uri create(@NonNull MasterSecret masterSecret,
|
||||||
@NonNull byte[] blobBytes,
|
@NonNull byte[] blobBytes,
|
||||||
@NonNull String mimeType)
|
@NonNull String mimeType,
|
||||||
|
@Nullable String fileName)
|
||||||
{
|
{
|
||||||
final long id = System.currentTimeMillis();
|
final long id = System.currentTimeMillis();
|
||||||
cache.put(id, blobBytes);
|
cache.put(id, blobBytes);
|
||||||
return create(masterSecret, new ByteArrayInputStream(blobBytes), id, mimeType);
|
return create(masterSecret, new ByteArrayInputStream(blobBytes), id, mimeType, fileName, (long) blobBytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri create(@NonNull MasterSecret masterSecret,
|
public Uri create(@NonNull MasterSecret masterSecret,
|
||||||
@NonNull InputStream input,
|
@NonNull InputStream input,
|
||||||
@NonNull String mimeType)
|
@NonNull String mimeType,
|
||||||
|
@Nullable String fileName,
|
||||||
|
@Nullable Long fileSize)
|
||||||
{
|
{
|
||||||
return create(masterSecret, input, System.currentTimeMillis(), mimeType);
|
return create(masterSecret, input, System.currentTimeMillis(), mimeType, fileName, fileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uri create(MasterSecret masterSecret, InputStream input, long id, String mimeType) {
|
private Uri create(@NonNull MasterSecret masterSecret,
|
||||||
|
@NonNull InputStream input,
|
||||||
|
long id,
|
||||||
|
@NonNull String mimeType,
|
||||||
|
@Nullable String fileName,
|
||||||
|
@Nullable Long fileSize)
|
||||||
|
{
|
||||||
persistToDisk(masterSecret, id, input);
|
persistToDisk(masterSecret, id, input);
|
||||||
final Uri uniqueUri = CONTENT_URI.buildUpon()
|
final Uri uniqueUri = CONTENT_URI.buildUpon()
|
||||||
.appendPath(mimeType)
|
.appendPath(mimeType)
|
||||||
|
.appendPath(getEncryptedFileName(masterSecret, fileName))
|
||||||
|
.appendEncodedPath(String.valueOf(fileSize))
|
||||||
.appendEncodedPath(String.valueOf(System.currentTimeMillis()))
|
.appendEncodedPath(String.valueOf(System.currentTimeMillis()))
|
||||||
.build();
|
.build();
|
||||||
return ContentUris.withAppendedId(uniqueUri, id);
|
return ContentUris.withAppendedId(uniqueUri, id);
|
||||||
@ -113,13 +134,14 @@ public class PersistentBlobProvider {
|
|||||||
|
|
||||||
public boolean delete(@NonNull Uri uri) {
|
public boolean delete(@NonNull Uri uri) {
|
||||||
switch (MATCHER.match(uri)) {
|
switch (MATCHER.match(uri)) {
|
||||||
case MATCH:
|
case MATCH_OLD:
|
||||||
|
case MATCH_NEW:
|
||||||
long id = ContentUris.parseId(uri);
|
long id = ContentUris.parseId(uri);
|
||||||
cache.remove(id);
|
cache.remove(id);
|
||||||
return getFile(ContentUris.parseId(uri)).delete();
|
return getFile(ContentUris.parseId(uri)).delete();
|
||||||
default:
|
|
||||||
return new File(uri.getPath()).delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull InputStream getStream(MasterSecret masterSecret, long id) throws IOException {
|
public @NonNull InputStream getStream(MasterSecret masterSecret, long id) throws IOException {
|
||||||
@ -132,6 +154,11 @@ public class PersistentBlobProvider {
|
|||||||
return new File(context.getDir("captures", Context.MODE_PRIVATE), id + "." + BLOB_EXTENSION);
|
return new File(context.getDir("captures", Context.MODE_PRIVATE), id + "." + BLOB_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @Nullable String getEncryptedFileName(@NonNull MasterSecret masterSecret, @Nullable String fileName) {
|
||||||
|
if (fileName == null) return null;
|
||||||
|
return new MasterCipher(masterSecret).encryptBody(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public static @Nullable String getMimeType(@NonNull Context context, @NonNull Uri persistentBlobUri) {
|
public static @Nullable String getMimeType(@NonNull Context context, @NonNull Uri persistentBlobUri) {
|
||||||
if (!isAuthority(context, persistentBlobUri)) return null;
|
if (!isAuthority(context, persistentBlobUri)) return null;
|
||||||
return isExternalBlobUri(context, persistentBlobUri)
|
return isExternalBlobUri(context, persistentBlobUri)
|
||||||
@ -139,6 +166,35 @@ public class PersistentBlobProvider {
|
|||||||
: persistentBlobUri.getPathSegments().get(MIMETYPE_PATH_SEGMENT);
|
: persistentBlobUri.getPathSegments().get(MIMETYPE_PATH_SEGMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable String getFileName(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Uri persistentBlobUri) {
|
||||||
|
if (!isAuthority(context, persistentBlobUri)) return null;
|
||||||
|
if (isExternalBlobUri(context, persistentBlobUri)) return null;
|
||||||
|
if (MATCHER.match(persistentBlobUri) == MATCH_OLD) return null;
|
||||||
|
|
||||||
|
String fileName = persistentBlobUri.getPathSegments().get(FILENAME_PATH_SEGMENT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new MasterCipher(masterSecret).decryptBody(fileName);
|
||||||
|
} catch (InvalidMessageException e) {
|
||||||
|
Log.w(TAG, "No valid filename for URI");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable Long getFileSize(@NonNull Context context, Uri persistentBlobUri) {
|
||||||
|
if (!isAuthority(context, persistentBlobUri)) return null;
|
||||||
|
if (isExternalBlobUri(context, persistentBlobUri)) return null;
|
||||||
|
if (MATCHER.match(persistentBlobUri) == MATCH_OLD) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Long.valueOf(persistentBlobUri.getPathSegments().get(FILESIZE_PATH_SEGMENT));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static @NonNull String getExtensionFromMimeType(String mimeType) {
|
private static @NonNull String getExtensionFromMimeType(String mimeType) {
|
||||||
final String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
final String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
||||||
return extension != null ? extension : BLOB_EXTENSION;
|
return extension != null ? extension : BLOB_EXTENSION;
|
||||||
@ -157,7 +213,8 @@ public class PersistentBlobProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAuthority(@NonNull Context context, @NonNull Uri uri) {
|
public static boolean isAuthority(@NonNull Context context, @NonNull Uri uri) {
|
||||||
return MATCHER.match(uri) == MATCH || isExternalBlobUri(context, uri);
|
int matchResult = MATCHER.match(uri);
|
||||||
|
return matchResult == MATCH_NEW || matchResult == MATCH_OLD || isExternalBlobUri(context, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isExternalBlobUri(@NonNull Context context, @NonNull Uri uri) {
|
private static boolean isExternalBlobUri(@NonNull Context context, @NonNull Uri uri) {
|
||||||
|
@ -229,7 +229,7 @@ public class ScribbleActivity extends PassphraseRequiredActionBarActivity implem
|
|||||||
baos = null;
|
baos = null;
|
||||||
result = null;
|
result = null;
|
||||||
|
|
||||||
Uri uri = provider.create(masterSecret, data, MediaUtil.IMAGE_JPEG);
|
Uri uri = provider.create(masterSecret, data, MediaUtil.IMAGE_JPEG, null);
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setData(uri);
|
intent.setData(uri);
|
||||||
setResult(RESULT_OK, intent);
|
setResult(RESULT_OK, intent);
|
||||||
|
Loading…
Reference in New Issue
Block a user