mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:18:27 +00:00
Turned SingleUseBlobProvider into MemoryBlobProvider.
Keep the single-use behavior, but allow the creation of multi-use memory blobs that can be deleted when we're done with them. Will help out with having URI's for temporary images during the camera capture flow.
This commit is contained in:
parent
e63773e5c8
commit
e9a38bab1e
@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.providers.SingleUseBlobProvider;
|
||||
import org.thoughtcrime.securesms.providers.MemoryBlobProvider;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
@ -111,7 +111,7 @@ public class GroupManager {
|
||||
GroupContext groupContext = groupContextBuilder.build();
|
||||
|
||||
if (avatar != null) {
|
||||
Uri avatarUri = SingleUseBlobProvider.getInstance().createUri(avatar);
|
||||
Uri avatarUri = MemoryBlobProvider.getInstance().createSingleUseUri(avatar);
|
||||
avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.MmsRadioException;
|
||||
import org.thoughtcrime.securesms.mms.PartParser;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.providers.SingleUseBlobProvider;
|
||||
import org.thoughtcrime.securesms.providers.MemoryBlobProvider;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -174,7 +174,7 @@ public class MmsDownloadJob extends MasterSecretJob {
|
||||
LegacyMessageException
|
||||
{
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
SingleUseBlobProvider provider = SingleUseBlobProvider.getInstance();
|
||||
MemoryBlobProvider provider = MemoryBlobProvider.getInstance();
|
||||
Optional<Address> group = Optional.absent();
|
||||
Set<Address> members = new HashSet<>();
|
||||
String body = null;
|
||||
@ -213,7 +213,7 @@ public class MmsDownloadJob extends MasterSecretJob {
|
||||
PduPart part = media.getPart(i);
|
||||
|
||||
if (part.getData() != null) {
|
||||
Uri uri = provider.createUri(part.getData());
|
||||
Uri uri = provider.createSingleUseUri(part.getData());
|
||||
String name = null;
|
||||
|
||||
if (part.getName() != null) name = Util.toIsoString(part.getName());
|
||||
|
@ -9,11 +9,10 @@ import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
||||
import org.thoughtcrime.securesms.providers.PartProvider;
|
||||
import org.thoughtcrime.securesms.providers.SingleUseBlobProvider;
|
||||
import org.thoughtcrime.securesms.providers.MemoryBlobProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -38,7 +37,7 @@ public class PartAuthority {
|
||||
uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/*/#", THUMB_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(MemoryBlobProvider.AUTHORITY, MemoryBlobProvider.PATH, SINGLE_USE_ROW);
|
||||
}
|
||||
|
||||
public static InputStream getAttachmentStream(@NonNull Context context, @NonNull Uri uri)
|
||||
@ -50,7 +49,7 @@ public class PartAuthority {
|
||||
case PART_ROW: return DatabaseFactory.getAttachmentDatabase(context).getAttachmentStream(new PartUriParser(uri).getPartId(), 0);
|
||||
case THUMB_ROW: return DatabaseFactory.getAttachmentDatabase(context).getThumbnailStream(new PartUriParser(uri).getPartId());
|
||||
case PERSISTENT_ROW: return PersistentBlobProvider.getInstance(context).getStream(context, ContentUris.parseId(uri));
|
||||
case SINGLE_USE_ROW: return SingleUseBlobProvider.getInstance().getStream(ContentUris.parseId(uri));
|
||||
case SINGLE_USE_ROW: return MemoryBlobProvider.getInstance().getStream(ContentUris.parseId(uri));
|
||||
default: return context.getContentResolver().openInputStream(uri);
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
|
@ -0,0 +1,90 @@
|
||||
package org.thoughtcrime.securesms.providers;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemoryBlobProvider {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = MemoryBlobProvider.class.getSimpleName();
|
||||
|
||||
public static final String AUTHORITY = "org.thoughtcrime.securesms";
|
||||
public static final String PATH = "memory/*/#";
|
||||
private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/memory");
|
||||
|
||||
private final Map<Long, Entry> cache = new HashMap<>();
|
||||
|
||||
private static final MemoryBlobProvider instance = new MemoryBlobProvider();
|
||||
|
||||
public static MemoryBlobProvider getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private MemoryBlobProvider() {}
|
||||
|
||||
public synchronized Uri createSingleUseUri(@NonNull byte[] blob) {
|
||||
return createUriInternal(blob, true);
|
||||
}
|
||||
|
||||
public synchronized Uri createUri(@NonNull byte[] blob) {
|
||||
return createUriInternal(blob, false);
|
||||
}
|
||||
|
||||
public synchronized void delete(@NonNull Uri uri) {
|
||||
cache.remove(ContentUris.parseId(uri));
|
||||
}
|
||||
|
||||
public synchronized @NonNull InputStream getStream(long id) throws IOException {
|
||||
Entry entry = cache.get(id);
|
||||
|
||||
if (entry == null) {
|
||||
throw new IOException("ID not found: " + id);
|
||||
}
|
||||
|
||||
if (entry.isSingleUse()) {
|
||||
cache.remove(id);
|
||||
}
|
||||
|
||||
return new ByteArrayInputStream(entry.getBlob());
|
||||
}
|
||||
|
||||
private Uri createUriInternal(@NonNull byte[] blob, boolean singleUse) {
|
||||
try {
|
||||
long id = Math.abs(SecureRandom.getInstance("SHA1PRNG").nextLong());
|
||||
cache.put(id, new Entry(blob, singleUse));
|
||||
|
||||
Uri uniqueUri = Uri.withAppendedPath(CONTENT_URI, String.valueOf(System.currentTimeMillis()));
|
||||
return ContentUris.withAppendedId(uniqueUri, id);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Entry {
|
||||
|
||||
private final byte[] blob;
|
||||
private final boolean singleUse;
|
||||
|
||||
private Entry(@NonNull byte[] blob, boolean singleUse) {
|
||||
this.blob = blob;
|
||||
this.singleUse = singleUse;
|
||||
}
|
||||
|
||||
public byte[] getBlob() {
|
||||
return blob;
|
||||
}
|
||||
|
||||
public boolean isSingleUse() {
|
||||
return singleUse;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package org.thoughtcrime.securesms.providers;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SingleUseBlobProvider {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = SingleUseBlobProvider.class.getSimpleName();
|
||||
|
||||
public static final String AUTHORITY = "org.thoughtcrime.securesms";
|
||||
public static final String PATH = "memory/*/#";
|
||||
private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/memory");
|
||||
|
||||
private final Map<Long, byte[]> cache = new HashMap<>();
|
||||
|
||||
private static final SingleUseBlobProvider instance = new SingleUseBlobProvider();
|
||||
|
||||
public static SingleUseBlobProvider getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private SingleUseBlobProvider() {}
|
||||
|
||||
public synchronized Uri createUri(@NonNull byte[] blob) {
|
||||
try {
|
||||
long id = Math.abs(SecureRandom.getInstance("SHA1PRNG").nextLong());
|
||||
cache.put(id, blob);
|
||||
|
||||
Uri uniqueUri = Uri.withAppendedPath(CONTENT_URI, String.valueOf(System.currentTimeMillis()));
|
||||
return ContentUris.withAppendedId(uniqueUri, id);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized @NonNull InputStream getStream(long id) throws IOException {
|
||||
byte[] cached = cache.get(id);
|
||||
cache.remove(id);
|
||||
|
||||
if (cached != null) return new ByteArrayInputStream(cached);
|
||||
else throw new IOException("ID not found: " + id);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user