mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 04:25:18 +00:00
Make BlobProvider write to disk on a background thread.
Otherwise we hit some weird blocking issues with voice note recording.
This commit is contained in:
parent
5a8753de85
commit
ce0058864f
@ -339,7 +339,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
|
|||||||
.forData(inputStream, fileSize == null ? 0 : fileSize)
|
.forData(inputStream, fileSize == null ? 0 : fileSize)
|
||||||
.withMimeType(mimeType)
|
.withMimeType(mimeType)
|
||||||
.withFileName(fileName)
|
.withFileName(fileName)
|
||||||
.createForMultipleSessionsOnDisk(context);
|
.createForMultipleSessionsOnDisk(context, e -> Log.w(TAG, "Failed to write to disk.", e));
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.w(TAG, ioe);
|
Log.w(TAG, ioe);
|
||||||
return null;
|
return null;
|
||||||
|
@ -50,7 +50,7 @@ public class AudioRecorder {
|
|||||||
captureUri = BlobProvider.getInstance()
|
captureUri = BlobProvider.getInstance()
|
||||||
.forData(new ParcelFileDescriptor.AutoCloseInputStream(fds[0]), 0)
|
.forData(new ParcelFileDescriptor.AutoCloseInputStream(fds[0]), 0)
|
||||||
.withMimeType(MediaUtil.AUDIO_AAC)
|
.withMimeType(MediaUtil.AUDIO_AAC)
|
||||||
.createForSingleSessionOnDisk(context);
|
.createForSingleSessionOnDisk(context, e -> Log.w(TAG, "Error during recording", e));
|
||||||
audioCodec = new AudioCodec();
|
audioCodec = new AudioCodec();
|
||||||
|
|
||||||
audioCodec.start(new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]));
|
audioCodec.start(new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]));
|
||||||
|
@ -121,7 +121,7 @@ public class GiphyActivity extends PassphraseRequiredActionBarActivity
|
|||||||
return BlobProvider.getInstance()
|
return BlobProvider.getInstance()
|
||||||
.forData(data)
|
.forData(data)
|
||||||
.withMimeType(MediaUtil.IMAGE_GIF)
|
.withMimeType(MediaUtil.IMAGE_GIF)
|
||||||
.createForSingleSessionOnDisk(GiphyActivity.this);
|
.createForSingleSessionOnDisk(GiphyActivity.this, e -> Log.w(TAG, "Failed to write to disk.", e));
|
||||||
} catch (InterruptedException | ExecutionException | IOException e) {
|
} catch (InterruptedException | ExecutionException | IOException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
return null;
|
return null;
|
||||||
|
@ -297,7 +297,7 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple
|
|||||||
Uri uri = BlobProvider.getInstance()
|
Uri uri = BlobProvider.getInstance()
|
||||||
.forData(data)
|
.forData(data)
|
||||||
.withMimeType(MediaUtil.IMAGE_JPEG)
|
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||||
.createForSingleSessionOnDisk(this);
|
.createForSingleSessionOnDisk(this, e -> Log.w(TAG, "Failed to write to disk.", e));
|
||||||
return new Media(uri,
|
return new Media(uri,
|
||||||
MediaUtil.IMAGE_JPEG,
|
MediaUtil.IMAGE_JPEG,
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
|
@ -460,13 +460,12 @@ public class MediaSendFragment extends Fragment implements ViewTreeObserver.OnGl
|
|||||||
Uri uri = BlobProvider.getInstance()
|
Uri uri = BlobProvider.getInstance()
|
||||||
.forData(baos.toByteArray())
|
.forData(baos.toByteArray())
|
||||||
.withMimeType(MediaUtil.IMAGE_JPEG)
|
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||||
.createForSingleSessionOnDisk(context);
|
.createForSingleSessionOnDisk(context, e -> Log.w(TAG, "Failed to write to disk.", e));
|
||||||
|
|
||||||
Media updated = new Media(uri, MediaUtil.IMAGE_JPEG, media.getDate(), bitmap.getWidth(), bitmap.getHeight(), baos.size(), media.getBucketId(), media.getCaption());
|
Media updated = new Media(uri, MediaUtil.IMAGE_JPEG, media.getDate(), bitmap.getWidth(), bitmap.getHeight(), baos.size(), media.getBucketId(), media.getCaption());
|
||||||
|
|
||||||
updatedMedia.add(updated);
|
updatedMedia.add(updated);
|
||||||
renderTimer.split("item");
|
renderTimer.split("item");
|
||||||
|
|
||||||
} catch (InterruptedException | ExecutionException | IOException e) {
|
} catch (InterruptedException | ExecutionException | IOException e) {
|
||||||
Log.w(TAG, "Failed to render image. Using base image.");
|
Log.w(TAG, "Failed to render image. Using base image.");
|
||||||
updatedMedia.add(media);
|
updatedMedia.add(media);
|
||||||
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream;
|
|||||||
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream;
|
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -24,6 +25,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows for the creation and retrieval of blobs.
|
* Allows for the creation and retrieval of blobs.
|
||||||
@ -172,13 +174,21 @@ public class BlobProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private synchronized @NonNull Uri writeBlobSpecToDisk(@NonNull Context context, @NonNull BlobSpec blobSpec) throws IOException {
|
private synchronized @NonNull Uri writeBlobSpecToDisk(@NonNull Context context, @NonNull BlobSpec blobSpec, @Nullable ErrorListener errorListener) throws IOException {
|
||||||
AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret();
|
AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret();
|
||||||
String directory = getDirectory(blobSpec.getStorageType());
|
String directory = getDirectory(blobSpec.getStorageType());
|
||||||
File outputFile = new File(getOrCreateCacheDirectory(context, directory), buildFileName(blobSpec.id));
|
File outputFile = new File(getOrCreateCacheDirectory(context, directory), buildFileName(blobSpec.id));
|
||||||
OutputStream outputStream = ModernEncryptingPartOutputStream.createFor(attachmentSecret, outputFile, true).second;
|
OutputStream outputStream = ModernEncryptingPartOutputStream.createFor(attachmentSecret, outputFile, true).second;
|
||||||
|
|
||||||
|
SignalExecutors.IO.execute(() -> {
|
||||||
|
try {
|
||||||
Util.copy(blobSpec.getData(), outputStream);
|
Util.copy(blobSpec.getData(), outputStream);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (errorListener != null) {
|
||||||
|
errorListener.onError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return buildUri(blobSpec);
|
return buildUri(blobSpec);
|
||||||
}
|
}
|
||||||
@ -249,8 +259,8 @@ public class BlobProvider {
|
|||||||
* period from one {@link Application#onCreate()} to the next.
|
* period from one {@link Application#onCreate()} to the next.
|
||||||
*/
|
*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public Uri createForSingleSessionOnDisk(@NonNull Context context) throws IOException {
|
public Uri createForSingleSessionOnDisk(@NonNull Context context, @Nullable ErrorListener errorListener) throws IOException {
|
||||||
return writeBlobSpecToDisk(context, new BlobSpec(data, id, StorageType.SINGLE_SESSION_DISK, mimeType, fileName, fileSize));
|
return writeBlobSpecToDisk(context, buildBlobSpec(StorageType.SINGLE_SESSION_DISK), errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,8 +268,8 @@ public class BlobProvider {
|
|||||||
* eventually call {@link BlobProvider#delete(Context, Uri)} when the blob is no longer in use.
|
* eventually call {@link BlobProvider#delete(Context, Uri)} when the blob is no longer in use.
|
||||||
*/
|
*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public Uri createForMultipleSessionsOnDisk(@NonNull Context context) throws IOException {
|
public Uri createForMultipleSessionsOnDisk(@NonNull Context context, @Nullable ErrorListener errorListener) throws IOException {
|
||||||
return writeBlobSpecToDisk(context, buildBlobSpec(StorageType.MULTI_SESSION_DISK));
|
return writeBlobSpecToDisk(context, buildBlobSpec(StorageType.MULTI_SESSION_DISK), errorListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +312,11 @@ public class BlobProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ErrorListener {
|
||||||
|
@WorkerThread
|
||||||
|
void onError(IOException e);
|
||||||
|
}
|
||||||
|
|
||||||
private static class BlobSpec {
|
private static class BlobSpec {
|
||||||
|
|
||||||
private final InputStream data;
|
private final InputStream data;
|
||||||
|
@ -321,7 +321,7 @@ public class ScribbleFragment extends Fragment implements ScribbleHud.EventListe
|
|||||||
Uri uri = BlobProvider.getInstance()
|
Uri uri = BlobProvider.getInstance()
|
||||||
.forData(data)
|
.forData(data)
|
||||||
.withMimeType(MediaUtil.IMAGE_JPEG)
|
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||||
.createForSingleSessionOnDisk(requireContext());
|
.createForSingleSessionOnDisk(requireContext(), e -> Log.w(TAG, "Failed to persist image.", e));
|
||||||
|
|
||||||
controller.onImageEditComplete(uri,
|
controller.onImageEditComplete(uri,
|
||||||
result.getWidth(),
|
result.getWidth(),
|
||||||
|
Loading…
Reference in New Issue
Block a user