Optimize uploads during media composition.

By uploading in advance (when on unmetered connections), media messages
can send almost instantly.
This commit is contained in:
Greyson Parrelli
2020-01-08 15:56:51 -05:00
parent 92e97e61c1
commit fadcc606f8
37 changed files with 1413 additions and 452 deletions

View File

@@ -0,0 +1,44 @@
package org.thoughtcrime.securesms.util;
import androidx.annotation.NonNull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Helps determine the difference between two collections based on their {@link #equals(Object)}
* implementations.
*/
public class DiffHelper {
/**
* @return Result indicating the differences between the two collections. Important: The iteration
* order of the result will not necessarily match the iteration order of the original
* collection.
*/
public static <E> Result<E> calculate(@NonNull Collection<E> oldList, @NonNull Collection<E> newList) {
Set<E> inserted = SetUtil.difference(newList, oldList);
Set<E> removed = SetUtil.difference(oldList, newList);
return new Result<>(inserted, removed);
}
public static class Result<E> {
private final Collection<E> inserted;
private final Collection<E> removed;
public Result(@NonNull Collection<E> inserted, @NonNull Collection<E> removed) {
this.removed = removed;
this.inserted = inserted;
}
public @NonNull Collection<E> getInserted() {
return inserted;
}
public @NonNull Collection<E> getRemoved() {
return removed;
}
}
}

View File

@@ -0,0 +1,63 @@
package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.net.Uri;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.mms.TextSlide;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.whispersystems.libsignal.util.guava.Optional;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public final class MessageUtil {
private MessageUtil() {}
/**
* @return If the message is longer than the allowed text size, this will return trimmed text with
* an accompanying TextSlide. Otherwise it'll just return the original text.
*/
public static SplitResult getSplitMessage(@NonNull Context context, @NonNull String rawText, int maxPrimaryMessageSize) {
String bodyText = rawText;
Optional<TextSlide> textSlide = Optional.absent();
if (bodyText.length() > maxPrimaryMessageSize) {
bodyText = rawText.substring(0, maxPrimaryMessageSize);
byte[] textData = rawText.getBytes();
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HHmmss", Locale.US).format(new Date());
String filename = String.format("signal-%s.txt", timestamp);
Uri textUri = BlobProvider.getInstance()
.forData(textData)
.withMimeType(MediaUtil.LONG_TEXT)
.withFileName(filename)
.createForSingleSessionInMemory();
textSlide = Optional.of(new TextSlide(context, textUri, filename, textData.length));
}
return new SplitResult(bodyText, textSlide);
}
public static class SplitResult {
private final String body;
private final Optional<TextSlide> textSlide;
private SplitResult(@NonNull String body, @NonNull Optional<TextSlide> textSlide) {
this.body = body;
this.textSlide = textSlide;
}
public @NonNull String getBody() {
return body;
}
public @NonNull Optional<TextSlide> getTextSlide() {
return textSlide;
}
}
}

View File

@@ -3,6 +3,15 @@ package org.thoughtcrime.securesms.util;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ParcelUtil {
public static byte[] serialize(Parcelable parceable) {
@@ -25,4 +34,31 @@ public class ParcelUtil {
return creator.createFromParcel(parcel);
}
public static void writeStringCollection(@NonNull Parcel dest, @NonNull Collection<String> collection) {
dest.writeStringList(new ArrayList<>(collection));
}
public static @NonNull Collection<String> readStringCollection(@NonNull Parcel in) {
List<String> list = new ArrayList<>();
in.readStringList(list);
return list;
}
public static void writeParcelableCollection(@NonNull Parcel dest, @NonNull Collection<? extends Parcelable> collection) {
Parcelable[] values = collection.toArray(new Parcelable[0]);
dest.writeParcelableArray(values, 0);
}
public static @NonNull <E> Collection<E> readParcelableCollection(@NonNull Parcel in, Class<E> clazz) {
//noinspection unchecked
return Arrays.asList((E[]) in.readParcelableArray(clazz.getClassLoader()));
}
public static void writeBoolean(@NonNull Parcel dest, boolean value) {
dest.writeByte(value ? (byte) 1 : 0);
}
public static boolean readBoolean(@NonNull Parcel in) {
return in.readByte() != 0;
}
}

View File

@@ -1,19 +1,19 @@
package org.thoughtcrime.securesms.util;
import java.util.HashSet;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
public final class SetUtil {
private SetUtil() {}
public static <E> Set<E> intersection(Set<E> a, Set<E> b) {
public static <E> Set<E> intersection(Collection<E> a, Collection<E> b) {
Set<E> intersection = new LinkedHashSet<>(a);
intersection.retainAll(b);
return intersection;
}
public static <E> Set<E> difference(Set<E> a, Set<E> b) {
public static <E> Set<E> difference(Collection<E> a, Collection<E> b) {
Set<E> difference = new LinkedHashSet<>(a);
difference.removeAll(b);
return difference;