mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 20:58:26 +00:00
remove unused jobs and wrap up old job refactoring
This commit is contained in:
parent
375815c719
commit
2b48b52df0
@ -355,7 +355,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
||||
private void initializeJobManager() {
|
||||
this.jobManager = new JobManager(this, new JobManager.Configuration.Builder()
|
||||
.setDataSerializer(new JsonDataSerializer())
|
||||
.setJobFactories(JobManagerFactories.getJobFactories(this))
|
||||
.setJobFactories(JobManagerFactories.getJobFactories())
|
||||
.setConstraintFactories(JobManagerFactories.getConstraintFactories(this))
|
||||
.setConstraintObservers(JobManagerFactories.getConstraintObservers(this))
|
||||
.setJobStorage(new FastJobStorage(jobDatabase))
|
||||
|
@ -1,133 +0,0 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.messaging.utilities.Data;
|
||||
import org.session.libsession.utilities.DownloadUtilities;
|
||||
import org.session.libsession.utilities.GroupRecord;
|
||||
import org.session.libsignal.exceptions.InvalidMessageException;
|
||||
import org.session.libsignal.exceptions.NonSuccessfulResponseCodeException;
|
||||
import org.session.libsignal.messages.SignalServiceAttachmentPointer;
|
||||
import org.session.libsignal.streams.AttachmentCipherInputStream;
|
||||
import org.session.libsignal.utilities.Hex;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.session.libsignal.utilities.guava.Optional;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AvatarDownloadJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "AvatarDownloadJob";
|
||||
|
||||
private static final String TAG = AvatarDownloadJob.class.getSimpleName();
|
||||
|
||||
private static final int MAX_AVATAR_SIZE = 20 * 1024 * 1024;
|
||||
|
||||
private static final String KEY_GROUP_ID = "group_id";
|
||||
|
||||
private String groupId;
|
||||
|
||||
public AvatarDownloadJob(@NonNull String groupId) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setMaxAttempts(10)
|
||||
.build(),
|
||||
groupId);
|
||||
}
|
||||
|
||||
private AvatarDownloadJob(@NonNull Job.Parameters parameters, @NonNull String groupId) {
|
||||
super(parameters);
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return new Data.Builder().putString(KEY_GROUP_ID, groupId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
GroupDatabase database = DatabaseComponent.get(context).groupDatabase();
|
||||
Optional<GroupRecord> record = database.getGroup(groupId);
|
||||
File attachment = null;
|
||||
|
||||
try {
|
||||
if (record.isPresent()) {
|
||||
long avatarId = record.get().getAvatarId();
|
||||
String contentType = record.get().getAvatarContentType();
|
||||
byte[] key = record.get().getAvatarKey();
|
||||
String relay = record.get().getRelay();
|
||||
Optional<byte[]> digest = Optional.fromNullable(record.get().getAvatarDigest());
|
||||
Optional<String> fileName = Optional.absent();
|
||||
String url = record.get().getUrl();
|
||||
|
||||
if (avatarId == -1 || key == null || url.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (digest.isPresent()) {
|
||||
Log.i(TAG, "Downloading group avatar with digest: " + Hex.toString(digest.get()));
|
||||
}
|
||||
|
||||
attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
|
||||
attachment.deleteOnExit();
|
||||
|
||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), url);
|
||||
|
||||
if (pointer.getUrl().isEmpty()) throw new InvalidMessageException("Missing attachment URL.");
|
||||
DownloadUtilities.downloadFile(attachment, pointer.getUrl());
|
||||
|
||||
// Assume we're retrieving an attachment for an open group server if the digest is not set
|
||||
InputStream inputStream;
|
||||
if (!pointer.getDigest().isPresent()) {
|
||||
inputStream = new FileInputStream(attachment);
|
||||
} else {
|
||||
inputStream = AttachmentCipherInputStream.createForAttachment(attachment, pointer.getSize().or(0), pointer.getKey(), pointer.getDigest().get());
|
||||
}
|
||||
|
||||
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500);
|
||||
|
||||
database.updateProfilePicture(groupId, avatar);
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (BitmapDecodingException | NonSuccessfulResponseCodeException | InvalidMessageException e) {
|
||||
Log.w(TAG, e);
|
||||
} finally {
|
||||
if (attachment != null)
|
||||
attachment.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(@NonNull Exception exception) {
|
||||
if (exception instanceof IOException) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final class Factory implements Job.Factory<AvatarDownloadJob> {
|
||||
@Override
|
||||
public @NonNull AvatarDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new AvatarDownloadJob(parameters, data.getString(KEY_GROUP_ID));
|
||||
}
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@ import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.messaging.jobs.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
@ -28,11 +28,9 @@ public final class JobManagerFactories {
|
||||
|
||||
public static Map<String, Job.Factory> getJobFactories(@NonNull Application application) {
|
||||
HashMap<String, Job.Factory> factoryHashMap = new HashMap<String, Job.Factory>() {{
|
||||
put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory());
|
||||
put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory());
|
||||
put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application));
|
||||
put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory());
|
||||
put(PrepareAttachmentAudioExtrasJob.KEY, new PrepareAttachmentAudioExtrasJob.Factory());
|
||||
put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory());
|
||||
put(RetrieveProfileAvatarJob.Companion.getKEY(), new RetrieveProfileAvatarJob.Factory());
|
||||
put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory());
|
||||
}};
|
||||
factoryKeys.addAll(factoryHashMap.keySet());
|
||||
return factoryHashMap;
|
||||
|
@ -1,133 +0,0 @@
|
||||
package org.thoughtcrime.securesms.jobs
|
||||
|
||||
import android.os.Build
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachmentAudioExtras
|
||||
import org.session.libsession.messaging.utilities.Data
|
||||
import org.session.libsession.utilities.DecodedAudio
|
||||
import org.session.libsession.utilities.InputStreamMediaDataSource
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobs.PrepareAttachmentAudioExtrasJob.AudioExtrasUpdatedEvent
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Decodes the audio content of the related attachment entry
|
||||
* and caches the result with [DatabaseAttachmentAudioExtras] data.
|
||||
*
|
||||
* It only process attachments with "audio" mime types.
|
||||
*
|
||||
* Due to [DecodedAudio] implementation limitations, it only works for API 23+.
|
||||
* For any lower targets fake data will be generated.
|
||||
*
|
||||
* You can subscribe to [AudioExtrasUpdatedEvent] to be notified about the successful result.
|
||||
*/
|
||||
//TODO AC: Rewrite to WorkManager API when
|
||||
// https://github.com/loki-project/session-android/pull/354 is merged.
|
||||
class PrepareAttachmentAudioExtrasJob : BaseJob {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AttachAudioExtrasJob"
|
||||
|
||||
const val KEY = "PrepareAttachmentAudioExtrasJob"
|
||||
const val DATA_ATTACH_ID = "attachment_id"
|
||||
|
||||
const val VISUAL_RMS_FRAMES = 32 // The amount of values to be computed for the visualization.
|
||||
}
|
||||
|
||||
private val attachmentId: AttachmentId
|
||||
|
||||
constructor(attachmentId: AttachmentId) : this(Parameters.Builder()
|
||||
.setQueue(KEY)
|
||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||
.build(),
|
||||
attachmentId)
|
||||
|
||||
private constructor(parameters: Parameters, attachmentId: AttachmentId) : super(parameters) {
|
||||
this.attachmentId = attachmentId
|
||||
}
|
||||
|
||||
override fun serialize(): Data {
|
||||
return Data.Builder().putParcelable(DATA_ATTACH_ID, attachmentId).build();
|
||||
}
|
||||
|
||||
override fun getFactoryKey(): String { return KEY
|
||||
}
|
||||
|
||||
override fun onShouldRetry(e: Exception): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onCanceled() { }
|
||||
|
||||
override fun onRun() {
|
||||
Log.v(TAG, "Processing attachment: $attachmentId")
|
||||
|
||||
val attachDb = DatabaseComponent.get(context).attachmentDatabase()
|
||||
val attachment = attachDb.getAttachment(attachmentId)
|
||||
|
||||
if (attachment == null) {
|
||||
throw IllegalStateException("Cannot find attachment with the ID $attachmentId")
|
||||
}
|
||||
if (!attachment.contentType.startsWith("audio/")) {
|
||||
throw IllegalStateException("Attachment $attachmentId is not of audio type.")
|
||||
}
|
||||
|
||||
// Check if the audio extras already exist.
|
||||
if (attachDb.getAttachmentAudioExtras(attachmentId) != null) return
|
||||
|
||||
fun extractAttachmentRandomSeed(attachment: Attachment): Int {
|
||||
return when {
|
||||
attachment.digest != null -> attachment.digest!!.sum()
|
||||
attachment.fileName != null -> attachment.fileName.hashCode()
|
||||
else -> attachment.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
fun generateFakeRms(seed: Int, frames: Int = VISUAL_RMS_FRAMES): ByteArray {
|
||||
return ByteArray(frames).apply { Random(seed.toLong()).nextBytes(this) }
|
||||
}
|
||||
|
||||
var rmsValues: ByteArray
|
||||
var totalDurationMs: Long = DatabaseAttachmentAudioExtras.DURATION_UNDEFINED
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
// Due to API version incompatibility, we just display some random waveform for older API.
|
||||
rmsValues = generateFakeRms(extractAttachmentRandomSeed(attachment))
|
||||
} else {
|
||||
try {
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
val decodedAudio = PartAuthority.getAttachmentStream(context, attachment.dataUri!!).use {
|
||||
DecodedAudio.create(InputStreamMediaDataSource(it))
|
||||
}
|
||||
rmsValues = decodedAudio.calculateRms(VISUAL_RMS_FRAMES)
|
||||
totalDurationMs = (decodedAudio.totalDuration / 1000.0).toLong()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Failed to decode sample values for the audio attachment \"${attachment.fileName}\".", e)
|
||||
rmsValues = generateFakeRms(extractAttachmentRandomSeed(attachment))
|
||||
}
|
||||
}
|
||||
|
||||
attachDb.setAttachmentAudioExtras(DatabaseAttachmentAudioExtras(
|
||||
attachmentId,
|
||||
rmsValues,
|
||||
totalDurationMs
|
||||
))
|
||||
|
||||
EventBus.getDefault().post(AudioExtrasUpdatedEvent(attachmentId))
|
||||
}
|
||||
|
||||
class Factory : Job.Factory<PrepareAttachmentAudioExtrasJob> {
|
||||
override fun create(parameters: Parameters, data: Data): PrepareAttachmentAudioExtrasJob {
|
||||
return PrepareAttachmentAudioExtrasJob(parameters, data.getParcelable(DATA_ATTACH_ID, AttachmentId.CREATOR))
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets dispatched once the audio extras have been updated. */
|
||||
data class AudioExtrasUpdatedEvent(val attachmentId: AttachmentId)
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.app.Application;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.avatars.AvatarHelper;
|
||||
import org.session.libsession.messaging.utilities.Data;
|
||||
import org.session.libsession.utilities.Address;
|
||||
import org.session.libsession.utilities.DownloadUtilities;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.session.libsession.utilities.Util;
|
||||
import org.session.libsession.utilities.recipients.Recipient;
|
||||
import org.session.libsignal.exceptions.PushNetworkException;
|
||||
import org.session.libsignal.streams.ProfileCipherInputStream;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RetrieveProfileAvatarJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "RetrieveProfileAvatarJob";
|
||||
|
||||
private static final String TAG = RetrieveProfileAvatarJob.class.getSimpleName();
|
||||
|
||||
private static final int MAX_PROFILE_SIZE_BYTES = 10 * 1024 * 1024;
|
||||
|
||||
private static final String KEY_PROFILE_AVATAR = "profile_avatar";
|
||||
private static final String KEY_ADDRESS = "address";
|
||||
|
||||
|
||||
private String profileAvatar;
|
||||
private Recipient recipient;
|
||||
|
||||
public RetrieveProfileAvatarJob(Recipient recipient, String profileAvatar) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.setQueue("RetrieveProfileAvatarJob" + recipient.getAddress().serialize())
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setLifespan(TimeUnit.HOURS.toMillis(1))
|
||||
.setMaxAttempts(2)
|
||||
.setMaxInstances(1)
|
||||
.build(),
|
||||
recipient,
|
||||
profileAvatar);
|
||||
}
|
||||
|
||||
private RetrieveProfileAvatarJob(@NonNull Job.Parameters parameters, @NonNull Recipient recipient, String profileAvatar) {
|
||||
super(parameters);
|
||||
this.recipient = recipient;
|
||||
this.profileAvatar = profileAvatar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull
|
||||
Data serialize() {
|
||||
return new Data.Builder()
|
||||
.putString(KEY_PROFILE_AVATAR, profileAvatar)
|
||||
.putString(KEY_ADDRESS, recipient.getAddress().serialize())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
RecipientDatabase database = DatabaseComponent.get(context).recipientDatabase();
|
||||
byte[] profileKey = recipient.resolve().getProfileKey();
|
||||
|
||||
if (profileKey == null || (profileKey.length != 32 && profileKey.length != 16)) {
|
||||
Log.w(TAG, "Recipient profile key is gone!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AvatarHelper.avatarFileExists(context, recipient.resolve().getAddress()) && Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
|
||||
Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(profileAvatar)) {
|
||||
Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize());
|
||||
AvatarHelper.delete(context, recipient.getAddress());
|
||||
database.setProfileAvatar(recipient, profileAvatar);
|
||||
return;
|
||||
}
|
||||
|
||||
File downloadDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir());
|
||||
|
||||
try {
|
||||
DownloadUtilities.downloadFile(downloadDestination, profileAvatar);
|
||||
InputStream avatarStream = new ProfileCipherInputStream(new FileInputStream(downloadDestination), profileKey);
|
||||
File decryptDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir());
|
||||
|
||||
Util.copy(avatarStream, new FileOutputStream(decryptDestination));
|
||||
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.getAddress()));
|
||||
} finally {
|
||||
if (downloadDestination != null) downloadDestination.delete();
|
||||
}
|
||||
|
||||
if (recipient.isLocalNumber()) {
|
||||
TextSecurePreferences.setProfileAvatarId(context, new SecureRandom().nextInt());
|
||||
}
|
||||
database.setProfileAvatar(recipient, profileAvatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(@NonNull Exception e) {
|
||||
if (e instanceof PushNetworkException) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {
|
||||
}
|
||||
|
||||
public static final class Factory implements Job.Factory<RetrieveProfileAvatarJob> {
|
||||
|
||||
private final Application application;
|
||||
|
||||
public Factory(Application application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RetrieveProfileAvatarJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new RetrieveProfileAvatarJob(parameters,
|
||||
Recipient.from(application, Address.fromSerialized(data.getString(KEY_ADDRESS)), true),
|
||||
data.getString(KEY_PROFILE_AVATAR));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package org.thoughtcrime.securesms.jobs
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import org.session.libsession.avatars.AvatarHelper
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
import org.session.libsession.messaging.jobs.JobDelegate
|
||||
import org.session.libsession.messaging.utilities.Data
|
||||
import org.session.libsession.utilities.DownloadUtilities.downloadFile
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfileAvatarId
|
||||
import org.session.libsession.utilities.Util.copy
|
||||
import org.session.libsession.utilities.Util.equals
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.streams.ProfileCipherInputStream
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.security.SecureRandom
|
||||
|
||||
class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: Address): Job {
|
||||
override var delegate: JobDelegate? = null
|
||||
override var id: String? = null
|
||||
override var failureCount: Int = 0
|
||||
override val maxFailureCount: Int = 0
|
||||
|
||||
lateinit var context: Context
|
||||
|
||||
companion object {
|
||||
val TAG = RetrieveProfileAvatarJob::class.simpleName
|
||||
val KEY: String = "RetrieveProfileAvatarJob"
|
||||
|
||||
// Keys used for database storage
|
||||
private val PROFILE_AVATAR_KEY = "profileAvatar"
|
||||
private val RECEIPIENT_ADDRESS_KEY = "recipient"
|
||||
}
|
||||
|
||||
override fun execute(dispatcherName: String) {
|
||||
val recipient = Recipient.from(context, recipientAddress, true)
|
||||
val database = get(context).recipientDatabase()
|
||||
val profileKey = recipient.resolve().profileKey
|
||||
|
||||
if (profileKey == null || (profileKey.size != 32 && profileKey.size != 16)) {
|
||||
Log.w(TAG, "Recipient profile key is gone!")
|
||||
return
|
||||
}
|
||||
|
||||
if (AvatarHelper.avatarFileExists(context, recipient.resolve().address) && equals(profileAvatar, recipient.resolve().profileAvatar)) {
|
||||
Log.w(TAG, "Already retrieved profile avatar: $profileAvatar")
|
||||
return
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(profileAvatar)) {
|
||||
Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize())
|
||||
AvatarHelper.delete(context, recipient.address)
|
||||
database.setProfileAvatar(recipient, profileAvatar)
|
||||
return
|
||||
}
|
||||
|
||||
val downloadDestination = File.createTempFile("avatar", ".jpg", context.cacheDir)
|
||||
|
||||
try {
|
||||
downloadFile(downloadDestination, profileAvatar)
|
||||
val avatarStream: InputStream = ProfileCipherInputStream(FileInputStream(downloadDestination), profileKey)
|
||||
val decryptDestination = File.createTempFile("avatar", ".jpg", context.cacheDir)
|
||||
copy(avatarStream, FileOutputStream(decryptDestination))
|
||||
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address))
|
||||
} finally {
|
||||
downloadDestination.delete()
|
||||
}
|
||||
|
||||
if (recipient.isLocalNumber) {
|
||||
setProfileAvatarId(context, SecureRandom().nextInt())
|
||||
}
|
||||
database.setProfileAvatar(recipient, profileAvatar)
|
||||
}
|
||||
|
||||
override fun serialize(): Data {
|
||||
return Data.Builder()
|
||||
.putString(PROFILE_AVATAR_KEY, profileAvatar)
|
||||
.putString(RECEIPIENT_ADDRESS_KEY, recipientAddress.serialize())
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun getFactoryKey(): String {
|
||||
return KEY
|
||||
}
|
||||
|
||||
class Factory: Job.Factory<RetrieveProfileAvatarJob> {
|
||||
override fun create(data: Data): RetrieveProfileAvatarJob {
|
||||
val profileAvatar = data.getString(PROFILE_AVATAR_KEY)
|
||||
val recipientAddress = Address.fromSerialized(data.getString(RECEIPIENT_ADDRESS_KEY))
|
||||
return RetrieveProfileAvatarJob(profileAvatar, recipientAddress)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user