Search in sources :

Example 21 with Data

use of org.thoughtcrime.securesms.jobmanager.Data in project Signal-Android by signalapp.

the class JsonDataSerializerTest method deserialize_dataMatchesExpected.

@Test
public void deserialize_dataMatchesExpected() throws IOException {
    Data data = new JsonDataSerializer().deserialize(StreamUtil.readFullyAsString(ClassLoader.getSystemClassLoader().getResourceAsStream("data/data_serialized.json")));
    assertEquals("s1 value", data.getString("s1"));
    assertEquals("s2 value", data.getString("s2"));
    assertArrayEquals(new String[] { "a", "b", "c" }, data.getStringArray("s_array_1"));
    assertEquals(1, data.getInt("i1"));
    assertEquals(2, data.getInt("i2"));
    assertEquals(Integer.MAX_VALUE, data.getInt("max"));
    assertEquals(Integer.MIN_VALUE, data.getInt("min"));
    assertArrayEquals(new int[] { 1, 2, 3, Integer.MAX_VALUE, Integer.MIN_VALUE }, data.getIntegerArray("i_array_1"));
    assertEquals(10, data.getLong("l1"));
    assertEquals(20, data.getLong("l2"));
    assertEquals(Long.MAX_VALUE, data.getLong("max"));
    assertEquals(Long.MIN_VALUE, data.getLong("min"));
    assertArrayEquals(new long[] { 1, 2, 3, Long.MAX_VALUE, Long.MIN_VALUE }, data.getLongArray("l_array_1"));
    assertEquals(1.2f, data.getFloat("f1"), FloatDelta);
    assertEquals(3.4f, data.getFloat("f2"), FloatDelta);
    assertArrayEquals(new float[] { 5.6f, 7.8f }, data.getFloatArray("f_array_1"), FloatDelta);
    assertEquals(10.2, data.getDouble("d1"), FloatDelta);
    assertEquals(30.4, data.getDouble("d2"), FloatDelta);
    assertArrayEquals(new double[] { 50.6, 70.8 }, data.getDoubleArray("d_array_1"), FloatDelta);
    assertTrue(data.getBoolean("b1"));
    assertFalse(data.getBoolean("b2"));
    assertArrayEquals(new boolean[] { false, true }, data.getBooleanArray("b_array_1"));
}
Also used : Data(org.thoughtcrime.securesms.jobmanager.Data) Test(org.junit.Test)

Example 22 with Data

use of org.thoughtcrime.securesms.jobmanager.Data in project Signal-Android by signalapp.

the class AttachmentUploadJob method onRun.

@Override
public void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    Data inputData = getInputData();
    ResumableUploadSpec resumableUploadSpec;
    if (forceV2) {
        Log.d(TAG, "Forcing utilization of V2");
        resumableUploadSpec = null;
    } else if (inputData != null && inputData.hasString(ResumableUploadSpecJob.KEY_RESUME_SPEC)) {
        Log.d(TAG, "Using attachments V3");
        resumableUploadSpec = ResumableUploadSpec.deserialize(inputData.getString(ResumableUploadSpecJob.KEY_RESUME_SPEC));
    } else {
        Log.d(TAG, "Using attachments V2");
        resumableUploadSpec = null;
    }
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    AttachmentDatabase database = SignalDatabase.attachments();
    DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId);
    if (databaseAttachment == null) {
        throw new InvalidAttachmentException("Cannot find the specified attachment.");
    }
    long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.getUploadTimestamp();
    if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.getLocation())) {
        Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping.");
        return;
    } else if (databaseAttachment.getUploadTimestamp() > 0) {
        Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms");
    }
    Log.i(TAG, "Uploading attachment for message " + databaseAttachment.getMmsId() + " with ID " + databaseAttachment.getAttachmentId());
    try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) {
        SignalServiceAttachment localAttachment = getAttachmentFor(databaseAttachment, notification, resumableUploadSpec);
        SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream());
        Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
        database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment, remoteAttachment.getUploadTimestamp());
    } catch (NonSuccessfulResumableUploadResponseCodeException e) {
        if (e.getCode() == 400) {
            Log.w(TAG, "Failed to upload due to a 400 when getting resumable upload information. Downgrading to attachments v2", e);
            forceV2 = true;
        }
    }
}
Also used : NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) Data(org.thoughtcrime.securesms.jobmanager.Data) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) NonSuccessfulResumableUploadResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) ResumableUploadSpec(org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec) NotificationController(org.thoughtcrime.securesms.service.NotificationController)

Example 23 with Data

use of org.thoughtcrime.securesms.jobmanager.Data in project Signal-Android by WhisperSystems.

the class StorageForcePushJob method onRun.

@Override
protected void onRun() throws IOException, RetryLaterException {
    if (SignalStore.account().isLinkedDevice()) {
        Log.i(TAG, "Only the primary device can force push");
        return;
    }
    StorageKey storageServiceKey = SignalStore.storageService().getOrCreateStorageKey();
    SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds();
    long currentVersion = accountManager.getStorageManifestVersion();
    Map<RecipientId, StorageId> oldContactStorageIds = recipientDatabase.getContactStorageSyncIdsMap();
    long newVersion = currentVersion + 1;
    Map<RecipientId, StorageId> newContactStorageIds = generateContactStorageIds(oldContactStorageIds);
    List<SignalStorageRecord> inserts = Stream.of(oldContactStorageIds.keySet()).map(recipientDatabase::getRecordForSync).withoutNulls().map(s -> StorageSyncModels.localToRemoteRecord(s, Objects.requireNonNull(newContactStorageIds.get(s.getId())).getRaw())).toList();
    SignalStorageRecord accountRecord = StorageSyncHelper.buildAccountRecord(context, Recipient.self().fresh());
    List<StorageId> allNewStorageIds = new ArrayList<>(newContactStorageIds.values());
    inserts.add(accountRecord);
    allNewStorageIds.add(accountRecord.getId());
    SignalStorageManifest manifest = new SignalStorageManifest(newVersion, allNewStorageIds);
    StorageSyncValidations.validateForcePush(manifest, inserts, Recipient.self().fresh());
    try {
        if (newVersion > 1) {
            Log.i(TAG, String.format(Locale.ENGLISH, "Force-pushing data. Inserting %d IDs.", inserts.size()));
            if (accountManager.resetStorageRecords(storageServiceKey, manifest, inserts).isPresent()) {
                Log.w(TAG, "Hit a conflict. Trying again.");
                throw new RetryLaterException();
            }
        } else {
            Log.i(TAG, String.format(Locale.ENGLISH, "First version, normal push. Inserting %d IDs.", inserts.size()));
            if (accountManager.writeStorageRecords(storageServiceKey, manifest, inserts, Collections.emptyList()).isPresent()) {
                Log.w(TAG, "Hit a conflict. Trying again.");
                throw new RetryLaterException();
            }
        }
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Hit an invalid key exception, which likely indicates a conflict.");
        throw new RetryLaterException(e);
    }
    Log.i(TAG, "Force push succeeded. Updating local manifest version to: " + newVersion);
    SignalStore.storageService().setManifest(manifest);
    recipientDatabase.applyStorageIdUpdates(newContactStorageIds);
    recipientDatabase.applyStorageIdUpdates(Collections.singletonMap(Recipient.self().getId(), accountRecord.getId()));
    storageIdDatabase.deleteAll();
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) StorageSyncValidations(org.thoughtcrime.securesms.storage.StorageSyncValidations) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) Stream(com.annimon.stream.Stream) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) StorageSyncModels(org.thoughtcrime.securesms.storage.StorageSyncModels) HashMap(java.util.HashMap) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ArrayList(java.util.ArrayList) StorageKey(org.whispersystems.signalservice.api.storage.StorageKey) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) Locale(java.util.Locale) Map(java.util.Map) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalStorageManifest(org.whispersystems.signalservice.api.storage.SignalStorageManifest) StorageId(org.whispersystems.signalservice.api.storage.StorageId) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) UnknownStorageIdDatabase(org.thoughtcrime.securesms.database.UnknownStorageIdDatabase) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) Job(org.thoughtcrime.securesms.jobmanager.Job) SignalStorageRecord(org.whispersystems.signalservice.api.storage.SignalStorageRecord) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SignalStorageManifest(org.whispersystems.signalservice.api.storage.SignalStorageManifest) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) ArrayList(java.util.ArrayList) SignalStorageRecord(org.whispersystems.signalservice.api.storage.SignalStorageRecord) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) StorageId(org.whispersystems.signalservice.api.storage.StorageId) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) UnknownStorageIdDatabase(org.thoughtcrime.securesms.database.UnknownStorageIdDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) StorageKey(org.whispersystems.signalservice.api.storage.StorageKey)

Example 24 with Data

use of org.thoughtcrime.securesms.jobmanager.Data in project Signal-Android by WhisperSystems.

the class DonationReceiptRedemptionJob method onRun.

@Override
protected void onRun() throws Exception {
    Data inputData = getInputData();
    if (inputData == null) {
        Log.w(TAG, "No input data. Exiting.", null, true);
        return;
    }
    byte[] presentationBytes = inputData.getStringAsBlob(INPUT_RECEIPT_CREDENTIAL_PRESENTATION);
    if (presentationBytes == null) {
        Log.d(TAG, "No response data. Exiting.", null, true);
        return;
    }
    ReceiptCredentialPresentation presentation = new ReceiptCredentialPresentation(presentationBytes);
    Log.d(TAG, "Attempting to redeem token... isForSubscription: " + isForSubscription(), true);
    ServiceResponse<EmptyResponse> response = ApplicationDependencies.getDonationsService().redeemReceipt(presentation, SignalStore.donationsValues().getDisplayBadgesOnProfile(), false).blockingGet();
    if (response.getApplicationError().isPresent()) {
        if (response.getStatus() >= 500) {
            Log.w(TAG, "Encountered a server exception " + response.getStatus(), response.getApplicationError().get(), true);
            throw new RetryableException();
        } else {
            Log.w(TAG, "Encountered a non-recoverable exception " + response.getStatus(), response.getApplicationError().get(), true);
            DonationError.routeDonationError(context, DonationError.genericBadgeRedemptionFailure(errorSource));
            throw new IOException(response.getApplicationError().get());
        }
    } else if (response.getExecutionError().isPresent()) {
        Log.w(TAG, "Encountered a retryable exception", response.getExecutionError().get(), true);
        throw new RetryableException();
    }
    Log.i(TAG, "Successfully redeemed token with response code " + response.getStatus() + "... isForSubscription: " + isForSubscription(), true);
    if (isForSubscription()) {
        Log.d(TAG, "Clearing subscription failure", true);
        SignalStore.donationsValues().clearSubscriptionRedemptionFailed();
    }
}
Also used : ReceiptCredentialPresentation(org.signal.zkgroup.receipts.ReceiptCredentialPresentation) Data(org.thoughtcrime.securesms.jobmanager.Data) IOException(java.io.IOException) EmptyResponse(org.whispersystems.signalservice.internal.EmptyResponse)

Example 25 with Data

use of org.thoughtcrime.securesms.jobmanager.Data in project Signal-Android by WhisperSystems.

the class RecipientIdJobMigration method migrateSendDeliveryReceiptJob.

@NonNull
private JobData migrateSendDeliveryReceiptJob(@NonNull JobData jobData) {
    String address = jobData.getData().getString("address");
    Recipient recipient = Recipient.external(application, address);
    Data updatedData = new Data.Builder().putString("recipient", recipient.getId().serialize()).putLong("message_id", jobData.getData().getLong("message_id")).putLong("timestamp", jobData.getData().getLong("timestamp")).build();
    return jobData.withData(updatedData);
}
Also used : Recipient(org.thoughtcrime.securesms.recipients.Recipient) Data(org.thoughtcrime.securesms.jobmanager.Data) NonNull(androidx.annotation.NonNull)

Aggregations

Data (org.thoughtcrime.securesms.jobmanager.Data)42 NonNull (androidx.annotation.NonNull)34 Recipient (org.thoughtcrime.securesms.recipients.Recipient)26 IOException (java.io.IOException)10 Stream (com.annimon.stream.Stream)6 List (java.util.List)6 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)6 Job (org.thoughtcrime.securesms.jobmanager.Job)6 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)6 Context (android.content.Context)4 TimeUnit (java.util.concurrent.TimeUnit)4 Test (org.junit.Test)4 Log (org.signal.core.util.logging.Log)4 NetworkConstraint (org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint)4 SignalStore (org.thoughtcrime.securesms.keyvalue.SignalStore)4 WorkerThread (androidx.annotation.WorkerThread)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 Set (java.util.Set)2 Assert.assertEquals (org.junit.Assert.assertEquals)2