package org.thoughtcrime.securesms.jobs; import android.content.Context; import android.support.annotation.NonNull; import android.util.Log; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientReader; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.jobmanager.JobParameters; import org.thoughtcrime.securesms.jobmanager.SafeData; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import java.io.IOException; import java.util.LinkedList; import java.util.List; import javax.inject.Inject; import androidx.work.Data; public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements InjectableType { private static final long serialVersionUID = 1L; @SuppressWarnings("unused") private static final String TAG = MultiDeviceBlockedUpdateJob.class.getSimpleName(); @Inject transient SignalServiceMessageSender messageSender; public MultiDeviceBlockedUpdateJob() { super(null, null); } public MultiDeviceBlockedUpdateJob(Context context) { super(context, JobParameters.newBuilder() .withNetworkRequirement() .withMasterSecretRequirement() .withGroupId(MultiDeviceBlockedUpdateJob.class.getSimpleName()) .create()); } @Override protected void initialize(@NonNull SafeData data) { } @Override protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) { return dataBuilder.build(); } @Override public void onRun(MasterSecret masterSecret) throws IOException, UntrustedIdentityException { if (!TextSecurePreferences.isMultiDevice(context)) { Log.i(TAG, "Not multi device, aborting..."); return; } RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); try (RecipientReader reader = database.readerForBlocked(database.getBlocked())) { List blockedIndividuals = new LinkedList<>(); List blockedGroups = new LinkedList<>(); Recipient recipient; while ((recipient = reader.getNext()) != null) { if (recipient.isGroupRecipient()) { blockedGroups.add(GroupUtil.getDecodedId(recipient.getAddress().toGroupString())); } else { blockedIndividuals.add(recipient.getAddress().serialize()); } } messageSender.sendMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(blockedIndividuals, blockedGroups)), UnidentifiedAccessUtil.getAccessForSync(context)); } } @Override public boolean onShouldRetryThrowable(Exception exception) { if (exception instanceof PushNetworkException) return true; return false; } @Override public void onCanceled() { } }