Skip to content

Commit

Permalink
Merge upstream 'v5.29.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
valldrac committed Jan 25, 2022
2 parents 29550ec + c7fb0e2 commit a6b1ff4
Show file tree
Hide file tree
Showing 56 changed files with 762 additions and 239 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ ktlint {
version = "0.43.2"
}

def canonicalVersionCode = 988
def canonicalVersionName = "5.29.4"
def canonicalVersionCode = 990
def canonicalVersionName = "5.29.6"
def mollyRevision = 0

def postFixSize = 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.signal.core.util.logging.Log;
import org.signal.core.util.tracing.Tracer;
import org.signal.glide.SignalGlideCodecs;
import org.thoughtcrime.securesms.emoji.JumboEmoji;
import org.thoughtcrime.securesms.mms.SignalGlideModule;
import org.signal.ringrtc.CallManager;
import org.thoughtcrime.securesms.avatar.AvatarPickerStorage;
Expand Down Expand Up @@ -209,6 +210,7 @@ private void onCreateUnlock() {
.addPostRender(() -> DownloadLatestEmojiDataJob.scheduleIfNecessary(this))
.addPostRender(EmojiSearchIndexDownloadJob::scheduleIfNecessary)
.addPostRender(() -> SignalDatabase.messageLog().trimOldMessages(System.currentTimeMillis(), FeatureFlags.retryRespondMaxAge()))
.addPostRender(() -> JumboEmoji.updateCurrentVersion(this))
.execute();

Log.d(TAG, "onCreateUnlock() took " + (System.currentTimeMillis() - startTime) + " ms");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package org.thoughtcrime.securesms.components.emoji;

import androidx.annotation.Nullable;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Emoji {

private final List<String> variations;
private final List<String> rawVariations;

public Emoji(String... variations) {
this.variations = Arrays.asList(variations);
this(Arrays.asList(variations), Collections.emptyList());
}

public Emoji(List<String> variations) {
this(variations, Collections.emptyList());
}

public Emoji(List<String> variations, List<String> rawVariations) {
this.variations = variations;
this.rawVariations = rawVariations;
}

public String getValue() {
Expand All @@ -26,4 +35,11 @@ public List<String> getVariations() {
public boolean hasMultipleVariations() {
return variations.size() > 1;
}

public @Nullable String getRawVariation(int variationIndex) {
if (rawVariations != null && variationIndex >= 0 && variationIndex < rawVariations.size()) {
return rawVariations.get(variationIndex);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ public void onFailure(ExecutionException exception) {
throw new IllegalStateException("Unexpected subclass " + loadResult.getClass());
}

if (jumboEmoji) {
JumboEmoji.LoadResult result = JumboEmoji.loadJumboEmoji(context, drawInfo.getRawEmoji());
if (jumboEmoji && drawInfo.getJumboSheet() != null) {
JumboEmoji.LoadResult result = JumboEmoji.loadJumboEmoji(context, drawInfo);
if (result instanceof JumboEmoji.LoadResult.Immediate) {
ThreadUtil.runOnMain(() -> {
jumboLoaded.set(true);
Expand All @@ -171,7 +171,11 @@ public void onSuccess(Bitmap result) {

@Override
public void onFailure(ExecutionException exception) {
Log.d(TAG, "Failed to load jumbo emoji bitmap resource", exception);
if (exception.getCause() instanceof JumboEmoji.CannotAutoDownload) {
Log.i(TAG, "Download restrictions are preventing jumbomoji use");
} else {
Log.d(TAG, "Failed to load jumbo emoji bitmap resource", exception);
}
}
});
}
Expand Down Expand Up @@ -200,15 +204,19 @@ public void onFailure(ExecutionException exception) {

Bitmap bitmap = null;

if (jumboEmoji) {
JumboEmoji.LoadResult result = JumboEmoji.loadJumboEmoji(context, drawInfo.getRawEmoji());
if (jumboEmoji && drawInfo.getJumboSheet() != null) {
JumboEmoji.LoadResult result = JumboEmoji.loadJumboEmoji(context, drawInfo);
if (result instanceof JumboEmoji.LoadResult.Immediate) {
bitmap = ((JumboEmoji.LoadResult.Immediate) result).getBitmap();
} else if (result instanceof JumboEmoji.LoadResult.Async) {
try {
bitmap = ((JumboEmoji.LoadResult.Async) result).getTask().get(10, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException exception) {
Log.d(TAG, "Failed to load jumbo emoji bitmap resource", exception);
if (exception.getCause() instanceof JumboEmoji.CannotAutoDownload) {
Log.i(TAG, "Download restrictions are preventing jumbomoji use");
} else {
Log.d(TAG, "Failed to load jumbo emoji bitmap resource", exception);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
import org.thoughtcrime.securesms.components.mention.MentionRendererDelegate;
import org.thoughtcrime.securesms.emoji.JumboEmoji;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.util.guava.Optional;
Expand All @@ -43,7 +44,8 @@ public class EmojiTextView extends AppCompatTextView {

private final boolean scaleEmojis;

private static final char ELLIPSIS = '…';
private static final char ELLIPSIS = '…';
private static final float JUMBOMOJI_SCALE = 0.8f;

private boolean forceCustom;
private CharSequence previousText;
Expand Down Expand Up @@ -113,13 +115,13 @@ protected void onDraw(Canvas canvas) {
public void setText(@Nullable CharSequence text, BufferType type) {
EmojiParser.CandidateList candidates = isInEditMode() ? null : EmojiProvider.getCandidates(text);

if (scaleEmojis && candidates != null && candidates.allEmojis) {
if (scaleEmojis && candidates != null && candidates.allEmojis && (candidates.hasJumboForAll() || JumboEmoji.canDownloadJumbo(getContext()))) {
int emojis = candidates.size();
float scale = 1.0f;

if (emojis <= 5) scale += 0.9f;
if (emojis <= 4) scale += 0.9f;
if (emojis <= 2) scale += 0.9f;
if (emojis <= 5) scale += JUMBOMOJI_SCALE;
if (emojis <= 4) scale += JUMBOMOJI_SCALE;
if (emojis <= 2) scale += JUMBOMOJI_SCALE;

isJumbomoji = scale > 1.0f;
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, originalFontSize * scale);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
package org.thoughtcrime.securesms.components.emoji.parsing

import org.thoughtcrime.securesms.emoji.EmojiPage
import org.thoughtcrime.securesms.util.Hex
import java.nio.charset.Charset

data class EmojiDrawInfo(val page: EmojiPage, val index: Int, private val emoji: String) {
val rawEmoji: String
get() {
val emojiBytes: ByteArray = emoji.toByteArray(Charset.forName("UTF-16"))
return Hex.toStringCondensed(emojiBytes.slice(2 until emojiBytes.size).toByteArray())
}
}
data class EmojiDrawInfo(val page: EmojiPage, val index: Int, private val emoji: String, val rawEmoji: String?, val jumboSheet: String?)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.thoughtcrime.securesms.emoji.JumboEmoji;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -127,6 +129,15 @@ public int size() {
return list.size();
}

public boolean hasJumboForAll() {
for (Candidate candidate : list) {
if (!JumboEmoji.hasJumboEmoji(candidate.drawInfo)) {
return false;
}
}
return true;
}

@Override
public @NonNull Iterator<Candidate> iterator() {
return list.iterator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3560,14 +3560,14 @@ public void handleReaction(@NonNull ConversationMessage conversationMessage,

@Override
public void onMessageWithErrorClicked(@NonNull MessageRecord messageRecord) {
if (messageRecord.hasFailedWithNetworkFailures()) {
if (messageRecord.isIdentityMismatchFailure()) {
SafetyNumberChangeDialog.show(this, messageRecord);
} else if (messageRecord.hasFailedWithNetworkFailures()) {
new AlertDialog.Builder(this)
.setMessage(R.string.conversation_activity__message_could_not_be_sent)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.conversation_activity__send, (dialog, which) -> MessageSender.resend(this, messageRecord))
.show();
} else if (messageRecord.isIdentityMismatchFailure()) {
SafetyNumberChangeDialog.show(this, messageRecord);
} else {
startActivity(MessageDetailsActivity.getIntentForMessageDetails(this, messageRecord, messageRecord.getRecipient().getId(), messageRecord.getThreadId()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -849,9 +849,11 @@ public void markAsRemoteDelete(long messageId) {
deletedAttachments = SignalDatabase.attachments().deleteAttachmentsForMessage(messageId);
SignalDatabase.mentions().deleteMentionsForMessage(messageId);
SignalDatabase.messageLog().deleteAllRelatedToMessage(messageId, true);
SignalDatabase.reactions().deleteReactions(new MessageId(messageId, true));

threadId = getThreadIdForMessage(messageId);
SignalDatabase.threads().update(threadId, false);

db.setTransactionSuccessful();
} finally {
db.endTransaction();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ class ReactionDatabase(context: Context, databaseHelper: SignalDatabase) : Datab
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(messageId)
}

fun deleteReactions(messageId: MessageId) {
writableDatabase.delete(TABLE_NAME, "$MESSAGE_ID = ? AND $IS_MMS = ?", SqlUtil.buildArgs(messageId.id, if (messageId.mms) 1 else 0))
}

fun hasReaction(messageId: MessageId, reaction: ReactionRecord): Boolean {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ? AND $AUTHOR_ID = ? AND $EMOJI = ?"
val args = SqlUtil.buildArgs(messageId.id, if (messageId.mms) 1 else 0, reaction.author, reaction.emoji)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ public void markAsRemoteDelete(long id) {

threadId = getThreadIdForMessage(id);

SignalDatabase.reactions().deleteReactions(new MessageId(id, false));
SignalDatabase.threads().update(threadId, false);
SignalDatabase.messageLog().deleteAllRelatedToMessage(id, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ object SignalDatabaseMigrations {
private const val NOTIFICATION_PROFILES = 123
private const val NOTIFICATION_PROFILES_END_FIX = 124
private const val REACTION_BACKUP_CLEANUP = 125
private const val REACTION_REMOTE_DELETE_CLEANUP = 126

const val DATABASE_VERSION = 125
const val DATABASE_VERSION = 126

@JvmStatic
fun migrate(context: Context, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
Expand Down Expand Up @@ -1643,6 +1644,19 @@ object SignalDatabaseMigrations {
""".trimIndent()
)
}

if (oldVersion < REACTION_REMOTE_DELETE_CLEANUP) {
db.execSQL(
// language=sql
"""
DELETE FROM reaction
WHERE
(is_mms = 0 AND message_id IN (SELECT _id from sms WHERE remote_deleted = 1))
OR
(is_mms = 1 AND message_id IN (SELECT _id from mms WHERE remote_deleted = 1))
""".trimIndent()
)
}
}

@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ public boolean isJumbomoji(Context context) {
if (isJumboji == null) {
if (getBody().length() <= EmojiSource.getLatest().getMaxEmojiLength() * JumboEmoji.MAX_JUMBOJI_COUNT) {
EmojiParser.CandidateList candidates = EmojiProvider.getCandidates(getDisplayBody(context));
isJumboji = candidates != null && candidates.allEmojis && candidates.size() <= JumboEmoji.MAX_JUMBOJI_COUNT;
isJumboji = candidates != null && candidates.allEmojis && candidates.size() <= JumboEmoji.MAX_JUMBOJI_COUNT && (candidates.hasJumboForAll() || JumboEmoji.canDownloadJumbo(context));
} else {
isJumboji = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.Consumer;

import com.mobilecoin.lib.util.Hex;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.UUID;
Expand Down Expand Up @@ -44,6 +46,16 @@ public class EmojiDownloader {
() -> new EmojiFiles.Name(imagePath, UUID.randomUUID()));
}

public static void streamFileFromRemote(@NonNull EmojiFiles.Version version,
@NonNull String bucket,
@NonNull String path,
@NonNull Consumer<InputStream> streamConsumer)
throws IOException
{
streamFromRemote(() -> EmojiRemote.getObject(new EmojiFileRequest(version.getVersion(), bucket, path)),
streamConsumer);
}

private static @NonNull EmojiFiles.Name downloadAndVerifyFromRemote(@NonNull Context context,
@NonNull EmojiFiles.Version version,
@NonNull Producer<Response> responseProducer,
Expand Down Expand Up @@ -90,6 +102,23 @@ public class EmojiDownloader {
}
}

private static void streamFromRemote(@NonNull Producer<Response> responseProducer,
@NonNull Consumer<InputStream> streamConsumer) throws IOException
{
try (Response response = responseProducer.produce()) {
if (!response.isSuccessful()) {
throw new IOException("Unsuccessful response " + response.code());
}

ResponseBody responseBody = response.body();
if (responseBody == null) {
throw new IOException("No response body");
}

streamConsumer.accept(Okio.buffer(responseBody.source()).inputStream());
}
}

private static @Nullable String getMD5FromResponse(@NonNull Response response) {
Pattern pattern = Pattern.compile(".*([a-f0-9]{32}).*");
String header = response.header("etag");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typealias UriFactory = (sprite: String, format: String) -> Uri
*/
object EmojiJsonParser {
private val OBJECT_MAPPER = ObjectMapper()
private const val ESTIMATED_EMOJI_COUNT = 3500

@JvmStatic
fun verify(body: InputStream) {
Expand All @@ -36,11 +37,12 @@ object EmojiJsonParser {
val format: String = node["format"].textValue()
val obsolete: List<ObsoleteEmoji> = node["obsolete"].toObseleteList()
val dataPages: List<EmojiPageModel> = getDataPages(format, node["emoji"], uriFactory)
val jumboPages: Map<String, String> = getJumboPages(node["jumbomoji"])
val displayPages: List<EmojiPageModel> = mergeToDisplayPages(dataPages)
val metrics: EmojiMetrics = node["metrics"].toEmojiMetrics()
val densities: List<String> = node["densities"].toDensityList()

return ParsedEmojiData(metrics, densities, format, displayPages, dataPages, obsolete)
return ParsedEmojiData(metrics, densities, format, displayPages, dataPages, jumboPages, obsolete)
}

private fun getDataPages(format: String, emoji: JsonNode, uriFactory: UriFactory): List<EmojiPageModel> {
Expand All @@ -64,13 +66,33 @@ object EmojiJsonParser {
.toList()
}

private fun getJumboPages(jumbo: JsonNode?): Map<String, String> {
if (jumbo != null) {
return jumbo.fields()
.asSequence()
.map { (page: String, node: JsonNode) ->
node.associate { it.textValue() to page }
}
.flatMap { it.entries }
.associateTo(HashMap(ESTIMATED_EMOJI_COUNT)) { it.key to it.value }
}
return emptyMap()
}

private fun createPage(pageName: String, format: String, page: JsonNode, uriFactory: UriFactory): EmojiPageModel {
val category = EmojiCategory.forKey(pageName.asCategoryKey())
val pageList = page.mapIndexed { i, data ->
if (data.size() == 0) {
throw IllegalStateException("Page index $pageName.$i had no data")
} else {
Emoji(data.map { it.textValue().encodeAsUtf16() })
val variations: MutableList<String> = mutableListOf()
val rawVariations: MutableList<String> = mutableListOf()
data.forEach {
variations += it.textValue().encodeAsUtf16()
rawVariations += it.textValue()
}

Emoji(variations, rawVariations)
}
}

Expand Down Expand Up @@ -111,5 +133,6 @@ data class ParsedEmojiData(
override val format: String,
override val displayPages: List<EmojiPageModel>,
override val dataPages: List<EmojiPageModel>,
override val jumboPages: Map<String, String>,
override val obsolete: List<ObsoleteEmoji>
) : EmojiData
Loading

0 comments on commit a6b1ff4

Please sign in to comment.