Search in sources :

Example 51 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class UnreadPaymentsRepository method markPaymentSeenInternal.

@WorkerThread
private void markPaymentSeenInternal(@NonNull UUID paymentId) {
    Context context = ApplicationDependencies.getApplication();
    SignalDatabase.payments().markPaymentSeen(paymentId);
}
Also used : Context(android.content.Context) WorkerThread(androidx.annotation.WorkerThread)

Example 52 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class FileStorage method read.

@WorkerThread
@NonNull
public static InputStream read(@NonNull Context context, @NonNull String directoryName, @NonNull String filename) throws IOException {
    File directory = context.getDir(directoryName, Context.MODE_PRIVATE);
    File file = new File(directory, filename);
    return getInputStream(context, file);
}
Also used : File(java.io.File) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 53 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class DirectoryHelper method refreshDirectory.

@WorkerThread
public static void refreshDirectory(@NonNull Context context, boolean notifyOfNewUsers) throws IOException {
    if (TextUtils.isEmpty(SignalStore.account().getE164())) {
        Log.w(TAG, "Have not yet set our own local number. Skipping.");
        return;
    }
    if (!Permissions.hasAll(context, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)) {
        Log.w(TAG, "No contact permissions. Skipping.");
        return;
    }
    if (!SignalStore.registrationValues().isRegistrationComplete()) {
        Log.w(TAG, "Registration is not yet complete. Skipping, but running a routine to possibly mark it complete.");
        RegistrationUtil.maybeMarkRegistrationComplete(context);
        return;
    }
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    Set<String> databaseNumbers = sanitizeNumbers(recipientDatabase.getAllPhoneNumbers());
    Set<String> systemNumbers = sanitizeNumbers(ContactAccessor.getInstance().getAllContactsWithNumbers(context));
    refreshNumbers(context, databaseNumbers, systemNumbers, notifyOfNewUsers, true);
    StorageSyncHelper.scheduleSyncForDataChange();
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) WorkerThread(androidx.annotation.WorkerThread)

Example 54 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class DirectoryHelper method refreshNumbers.

@WorkerThread
private static void refreshNumbers(@NonNull Context context, @NonNull Set<String> databaseNumbers, @NonNull Set<String> systemNumbers, boolean notifyOfNewUsers, boolean removeSystemContactEntryForMissing) throws IOException {
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
    if (allNumbers.isEmpty()) {
        Log.w(TAG, "No numbers to refresh!");
        return;
    }
    Stopwatch stopwatch = new Stopwatch("refresh");
    DirectoryResult result;
    if (FeatureFlags.cdsh()) {
        result = ContactDiscoveryV3.getDirectoryResult(databaseNumbers, systemNumbers);
    } else {
        result = ContactDiscoveryV2.getDirectoryResult(context, databaseNumbers, systemNumbers);
    }
    stopwatch.split("network");
    if (result.getNumberRewrites().size() > 0) {
        Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
        recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
    }
    Map<RecipientId, ACI> aciMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers());
    Set<String> activeNumbers = result.getRegisteredNumbers().keySet();
    Set<RecipientId> activeIds = aciMap.keySet();
    Set<RecipientId> inactiveIds = Stream.of(allNumbers).filterNot(activeNumbers::contains).filterNot(n -> result.getNumberRewrites().containsKey(n)).filterNot(n -> result.getIgnoredNumbers().contains(n)).map(recipientDatabase::getOrInsertFromE164).collect(Collectors.toSet());
    stopwatch.split("process-cds");
    UnlistedResult unlistedResult = filterForUnlistedUsers(context, inactiveIds);
    inactiveIds.removeAll(unlistedResult.getPossiblyActive());
    if (unlistedResult.getRetries().size() > 0) {
        Log.i(TAG, "Some profile fetches failed to resolve. Assuming not-inactive for now and scheduling a retry.");
        RetrieveProfileJob.enqueue(unlistedResult.getRetries());
    }
    stopwatch.split("handle-unlisted");
    Set<RecipientId> preExistingRegisteredUsers = new HashSet<>(recipientDatabase.getRegistered());
    recipientDatabase.bulkUpdatedRegisteredStatus(aciMap, inactiveIds);
    stopwatch.split("update-registered");
    updateContactsDatabase(context, activeIds, removeSystemContactEntryForMissing, result.getNumberRewrites());
    stopwatch.split("contacts-db");
    if (TextSecurePreferences.isMultiDevice(context)) {
        ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
    }
    if (TextSecurePreferences.hasSuccessfullyRetrievedDirectory(context) && notifyOfNewUsers) {
        Set<RecipientId> systemContacts = new HashSet<>(recipientDatabase.getSystemContacts());
        Set<RecipientId> newlyRegisteredSystemContacts = new HashSet<>(activeIds);
        newlyRegisteredSystemContacts.removeAll(preExistingRegisteredUsers);
        newlyRegisteredSystemContacts.retainAll(systemContacts);
        notifyNewUsers(context, newlyRegisteredSystemContacts);
    } else {
        TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
    }
    stopwatch.stop(TAG);
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) NonNull(androidx.annotation.NonNull) R(org.thoughtcrime.securesms.R) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) Manifest(android.Manifest) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) ContactsContract(android.provider.ContactsContract) BulkOperationsHandle(org.thoughtcrime.securesms.database.RecipientDatabase.BulkOperationsHandle) RegisteredState(org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) ContentResolver(android.content.ContentResolver) Map(java.util.Map) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient) AccountManager(android.accounts.AccountManager) ACI(org.whispersystems.signalservice.api.push.ACI) Account(android.accounts.Account) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) Set(java.util.Set) SetUtil(org.thoughtcrime.securesms.util.SetUtil) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) FeatureFlags(org.thoughtcrime.securesms.util.FeatureFlags) List(java.util.List) Nullable(androidx.annotation.Nullable) StorageSyncJob(org.thoughtcrime.securesms.jobs.StorageSyncJob) ProfileService(org.whispersystems.signalservice.api.services.ProfileService) BuildConfig(org.thoughtcrime.securesms.BuildConfig) InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) WorkerThread(androidx.annotation.WorkerThread) RemoteException(android.os.RemoteException) RetrieveProfileJob(org.thoughtcrime.securesms.jobs.RetrieveProfileJob) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) HashSet(java.util.HashSet) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) Pair(org.whispersystems.libsignal.util.Pair) NotificationChannels(org.thoughtcrime.securesms.notifications.NotificationChannels) ProfileUtil(org.thoughtcrime.securesms.util.ProfileUtil) Calendar(java.util.Calendar) Observable(io.reactivex.rxjava3.core.Observable) RegistrationUtil(org.thoughtcrime.securesms.registration.RegistrationUtil) ContactsDatabase(org.thoughtcrime.securesms.contacts.ContactsDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) Cursor(android.database.Cursor) Collectors(com.annimon.stream.Collectors) Permissions(org.thoughtcrime.securesms.permissions.Permissions) UuidUtil(org.whispersystems.signalservice.api.util.UuidUtil) TextUtils(android.text.TextUtils) IOException(java.io.IOException) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) OperationApplicationException(android.content.OperationApplicationException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) IncomingJoinedMessage(org.thoughtcrime.securesms.sms.IncomingJoinedMessage) ContactAccessor(org.thoughtcrime.securesms.contacts.ContactAccessor) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) PhoneNumberFormatter(org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ACI(org.whispersystems.signalservice.api.push.ACI) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread)

Example 55 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class DirectoryHelper method refreshDirectoryFor.

@WorkerThread
public static RegisteredState refreshDirectoryFor(@NonNull Context context, @NonNull Recipient recipient, boolean notifyOfNewUsers) throws IOException {
    Stopwatch stopwatch = new Stopwatch("single");
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
    RegisteredState newRegisteredState;
    if (recipient.hasServiceId() && !recipient.hasE164()) {
        boolean isRegistered = ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId());
        stopwatch.split("aci-network");
        if (isRegistered) {
            boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
            if (idChanged) {
                Log.w(TAG, "ID changed during refresh by UUID.");
            }
        } else {
            recipientDatabase.markUnregistered(recipient.getId());
        }
        stopwatch.split("aci-disk");
        stopwatch.stop(TAG);
        return isRegistered ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
    }
    if (!recipient.getE164().isPresent()) {
        Log.w(TAG, "No ACI or E164?");
        return RegisteredState.NOT_REGISTERED;
    }
    DirectoryResult result = ContactDiscoveryV2.getDirectoryResult(context, recipient.getE164().get());
    stopwatch.split("e164-network");
    if (result.getNumberRewrites().size() > 0) {
        Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
        recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
    }
    if (result.getRegisteredNumbers().size() > 0) {
        ACI aci = result.getRegisteredNumbers().values().iterator().next();
        if (aci != null) {
            boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci);
            if (idChanged) {
                recipient = Recipient.resolved(recipientDatabase.getByServiceId(aci).get());
            }
        } else {
            Log.w(TAG, "Registered number set had a null ACI!");
        }
    } else if (recipient.hasServiceId() && recipient.isRegistered() && hasCommunicatedWith(recipient)) {
        if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId())) {
            recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
        } else {
            recipientDatabase.markUnregistered(recipient.getId());
        }
        stopwatch.split("e164-unlisted-network");
    } else {
        recipientDatabase.markUnregistered(recipient.getId());
    }
    if (Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) {
        updateContactsDatabase(context, Collections.singletonList(recipient.getId()), false, result.getNumberRewrites());
    }
    newRegisteredState = result.getRegisteredNumbers().size() > 0 ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
    if (newRegisteredState != originalRegisteredState) {
        ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
        ApplicationDependencies.getJobManager().add(new StorageSyncJob());
        if (notifyOfNewUsers && newRegisteredState == RegisteredState.REGISTERED && recipient.resolve().isSystemContact()) {
            notifyNewUsers(context, Collections.singletonList(recipient.getId()));
        }
        StorageSyncHelper.scheduleSyncForDataChange();
    }
    stopwatch.split("e164-disk");
    stopwatch.stop(TAG);
    return newRegisteredState;
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) StorageSyncJob(org.thoughtcrime.securesms.jobs.StorageSyncJob) RegisteredState(org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState) ACI(org.whispersystems.signalservice.api.push.ACI) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) WorkerThread(androidx.annotation.WorkerThread)

Aggregations

WorkerThread (androidx.annotation.WorkerThread)365 NonNull (androidx.annotation.NonNull)151 IOException (java.io.IOException)83 Recipient (org.thoughtcrime.securesms.recipients.Recipient)82 Nullable (androidx.annotation.Nullable)51 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)46 Cursor (android.database.Cursor)41 ArrayList (java.util.ArrayList)41 Context (android.content.Context)39 Uri (android.net.Uri)32 LinkedList (java.util.LinkedList)30 List (java.util.List)30 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)28 Stream (com.annimon.stream.Stream)26 HashMap (java.util.HashMap)26 Log (org.signal.core.util.logging.Log)26 HashSet (java.util.HashSet)24 Map (java.util.Map)21 Collections (java.util.Collections)20 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)20