Fix Emoji crashes when downloaded bitmap files cannot be found.
This commit is contained in:
parent
276b757e2d
commit
1f3e131690
4 changed files with 59 additions and 15 deletions
|
@ -156,7 +156,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
|||
.addNonBlocking(StorageSyncHelper::scheduleRoutineSync)
|
||||
.addNonBlocking(() -> ApplicationDependencies.getJobManager().beginJobLoop())
|
||||
.addNonBlocking(EmojiSource::refresh)
|
||||
.addNonBlocking(DownloadLatestEmojiDataJob::scheduleIfNecessary)
|
||||
.addNonBlocking(() -> DownloadLatestEmojiDataJob.scheduleIfNecessary(this))
|
||||
.addPostRender(() -> RateLimitUtil.retryAllRateLimitedMessages(this))
|
||||
.addPostRender(this::initializeExpiringMessageManager)
|
||||
.execute();
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
|||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
||||
import okio.HashingSink
|
||||
import okio.Okio
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider
|
||||
|
@ -96,8 +97,12 @@ object EmojiFiles {
|
|||
val file = version.getFile(context, uuid)
|
||||
|
||||
try {
|
||||
getInputStream(context, file).use {
|
||||
return Okio.buffer(Okio.source(it)).buffer.md5().toByteArray()
|
||||
HashingSink.md5(Okio.blackhole()).use { hashingSink ->
|
||||
Okio.buffer(Okio.source(getInputStream(context, file))).use { source ->
|
||||
source.readAll(hashingSink)
|
||||
|
||||
return hashingSink.hash().toByteArray()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.i(TAG, "Could not read emoji data file md5", e)
|
||||
|
@ -129,18 +134,21 @@ object EmojiFiles {
|
|||
|
||||
private val objectMapper = ObjectMapper().registerKotlinModule()
|
||||
|
||||
@JvmStatic
|
||||
fun exists(context: Context): Boolean = context.getVersionFile().exists()
|
||||
|
||||
@JvmStatic
|
||||
fun readVersion(context: Context): Version? {
|
||||
try {
|
||||
val version = try {
|
||||
getInputStream(context, context.getVersionFile()).use {
|
||||
return objectMapper.readValue(it, Version::class.java)
|
||||
objectMapper.readValue(it, Version::class.java)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Could not read current emoji version from disk.")
|
||||
return null
|
||||
null
|
||||
}
|
||||
|
||||
return if (isVersionValid(context, version)) {
|
||||
version
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +168,30 @@ object EmojiFiles {
|
|||
Log.w(TAG, "Could not write current emoji version from disk.")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isVersionValid(context: Context, version: Version?): Boolean {
|
||||
if (version == null) {
|
||||
Log.d(TAG, "Version does not exist.")
|
||||
return false
|
||||
}
|
||||
|
||||
val nameCollection = NameCollection.read(context, version)
|
||||
|
||||
return if (nameCollection.names.isEmpty()) {
|
||||
Log.d(TAG, "NameCollection file is empty.")
|
||||
false
|
||||
} else {
|
||||
Log.d(TAG, "Verifying all name files exist.")
|
||||
val allNamesExist = nameCollection.names
|
||||
.map { version.getFile(context, it.uuid) }
|
||||
.all { it.exists() }
|
||||
|
||||
Log.d(TAG, "All names exist? $allNamesExist")
|
||||
|
||||
allNamesExist
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,12 @@ object EmojiPageCache {
|
|||
|
||||
SimpleTask.run(newTask::run) {
|
||||
try {
|
||||
cache[emojiPageRequest] = newTask.get()
|
||||
val newBitmap: Bitmap? = newTask.get()
|
||||
if (newBitmap == null) {
|
||||
Log.w(TAG, "Failed to load emoji bitmap for request $emojiPageRequest")
|
||||
} else {
|
||||
cache[emojiPageRequest] = newBitmap
|
||||
}
|
||||
} finally {
|
||||
tasks.remove(emojiPageRequest)
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import okhttp3.Response;
|
|||
import okhttp3.ResponseBody;
|
||||
import okio.HashingSink;
|
||||
import okio.Okio;
|
||||
import okio.Sink;
|
||||
import okio.Source;
|
||||
|
||||
/**
|
||||
|
@ -62,15 +63,17 @@ public class DownloadLatestEmojiDataJob extends BaseJob {
|
|||
|
||||
private EmojiFiles.Version targetVersion;
|
||||
|
||||
public static void scheduleIfNecessary() {
|
||||
public static void scheduleIfNecessary(@NonNull Context context) {
|
||||
long nextScheduledCheck = SignalStore.emojiValues().getNextScheduledCheck();
|
||||
|
||||
if (nextScheduledCheck <= System.currentTimeMillis()) {
|
||||
Log.i(TAG, "Scheduling DownloadLatestEmojiDataJob.");
|
||||
ApplicationDependencies.getJobManager().add(new DownloadLatestEmojiDataJob(false));
|
||||
|
||||
EmojiFiles.Version version = EmojiFiles.Version.readVersion(context);
|
||||
|
||||
long interval;
|
||||
if (EmojiFiles.Version.exists(ApplicationDependencies.getApplication())) {
|
||||
if (EmojiFiles.Version.isVersionValid(context, version)) {
|
||||
interval = INTERVAL_WITH_REMOTE_DOWNLOAD;
|
||||
} else {
|
||||
interval = INTERVAL_WITHOUT_REMOTE_DOWNLOAD;
|
||||
|
@ -365,11 +368,15 @@ public class DownloadLatestEmojiDataJob extends BaseJob {
|
|||
|
||||
try (OutputStream outputStream = EmojiFiles.openForWriting(context, version, name.getUuid())) {
|
||||
Source source = response.body().source();
|
||||
HashingSink sink = HashingSink.md5(Okio.sink(outputStream));
|
||||
Sink sink = Okio.sink(outputStream);
|
||||
|
||||
Okio.buffer(source).readAll(sink);
|
||||
outputStream.flush();
|
||||
|
||||
savedMd5 = sink.hash().toByteArray();
|
||||
source.close();
|
||||
sink.close();
|
||||
|
||||
savedMd5 = EmojiFiles.getMd5(context, version, name.getUuid());
|
||||
}
|
||||
|
||||
if (!Arrays.equals(savedMd5, Hex.toByteArray(responseMD5))) {
|
||||
|
|
Loading…
Add table
Reference in a new issue