Search in sources :

Example 1 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project Signal-Android by WhisperSystems.

the class AttachmentDownloadJob method createAttachmentPointer.

@VisibleForTesting
SignalServiceAttachmentPointer createAttachmentPointer(MasterSecret masterSecret, Attachment attachment) throws InvalidPartException {
    if (TextUtils.isEmpty(attachment.getLocation())) {
        throw new InvalidPartException("empty content id");
    }
    if (TextUtils.isEmpty(attachment.getKey())) {
        throw new InvalidPartException("empty encrypted key");
    }
    try {
        AsymmetricMasterSecret asymmetricMasterSecret = MasterSecretUtil.getAsymmetricMasterSecret(context, masterSecret);
        long id = Long.parseLong(attachment.getLocation());
        byte[] key = MediaKey.getDecrypted(masterSecret, asymmetricMasterSecret, attachment.getKey());
        String relay = null;
        if (TextUtils.isEmpty(attachment.getRelay())) {
            relay = attachment.getRelay();
        }
        if (attachment.getDigest() != null) {
            Log.w(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.getDigest()));
        } else {
            Log.w(TAG, "Downloading attachment with no digest...");
        }
        return new SignalServiceAttachmentPointer(id, null, key, relay, Optional.fromNullable(attachment.getDigest()));
    } catch (InvalidMessageException | IOException e) {
        Log.w(TAG, e);
        throw new InvalidPartException(e);
    }
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) AsymmetricMasterSecret(org.thoughtcrime.securesms.crypto.AsymmetricMasterSecret) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) IOException(java.io.IOException) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 2 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project k-9 by k9mail.

the class MessagingController method sendPendingMessagesSynchronous.

/**
     * Attempt to send any messages that are sitting in the Outbox.
     */
@VisibleForTesting
protected void sendPendingMessagesSynchronous(final Account account) {
    LocalFolder localFolder = null;
    Exception lastFailure = null;
    boolean wasPermanentFailure = false;
    try {
        LocalStore localStore = account.getLocalStore();
        localFolder = localStore.getFolder(account.getOutboxFolderName());
        if (!localFolder.exists()) {
            Timber.v("Outbox does not exist");
            return;
        }
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesStarted(account);
        }
        localFolder.open(Folder.OPEN_MODE_RW);
        List<LocalMessage> localMessages = localFolder.getMessages(null);
        int progress = 0;
        int todo = localMessages.size();
        for (MessagingListener l : getListeners()) {
            l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
        }
        /*
             * The profile we will use to pull all of the content
             * for a given local message into memory for sending.
             */
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        fp.add(FetchProfile.Item.BODY);
        Timber.i("Scanning folder '%s' (%d) for messages to send", account.getOutboxFolderName(), localFolder.getId());
        Transport transport = transportProvider.getTransport(K9.app, account);
        for (LocalMessage message : localMessages) {
            if (message.isSet(Flag.DELETED)) {
                message.destroy();
                continue;
            }
            try {
                AtomicInteger count = new AtomicInteger(0);
                AtomicInteger oldCount = sendCount.putIfAbsent(message.getUid(), count);
                if (oldCount != null) {
                    count = oldCount;
                }
                Timber.i("Send count for message %s is %d", message.getUid(), count.get());
                if (count.incrementAndGet() > K9.MAX_SEND_ATTEMPTS) {
                    Timber.e("Send count for message %s can't be delivered after %d attempts. " + "Giving up until the user restarts the device", message.getUid(), MAX_SEND_ATTEMPTS);
                    notificationController.showSendFailedNotification(account, new MessagingException(message.getSubject()));
                    continue;
                }
                localFolder.fetch(Collections.singletonList(message), fp, null);
                try {
                    if (message.getHeader(K9.IDENTITY_HEADER).length > 0) {
                        Timber.v("The user has set the Outbox and Drafts folder to the same thing. " + "This message appears to be a draft, so K-9 will not send it");
                        continue;
                    }
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
                    Timber.i("Sending message with UID %s", message.getUid());
                    transport.sendMessage(message);
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
                    message.setFlag(Flag.SEEN, true);
                    progress++;
                    for (MessagingListener l : getListeners()) {
                        l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
                    }
                    moveOrDeleteSentMessage(account, localStore, localFolder, message);
                } catch (AuthenticationFailedException e) {
                    lastFailure = e;
                    wasPermanentFailure = false;
                    handleAuthenticationFailure(account, false);
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (CertificateValidationException e) {
                    lastFailure = e;
                    wasPermanentFailure = false;
                    notifyUserIfCertificateProblem(account, e, false);
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (MessagingException e) {
                    lastFailure = e;
                    wasPermanentFailure = e.isPermanentFailure();
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                } catch (Exception e) {
                    lastFailure = e;
                    wasPermanentFailure = true;
                    handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure);
                }
            } catch (Exception e) {
                lastFailure = e;
                wasPermanentFailure = false;
                Timber.e(e, "Failed to fetch message for sending");
                addErrorMessage(account, "Failed to fetch message for sending", e);
                notifySynchronizeMailboxFailed(account, localFolder, e);
            }
        }
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesCompleted(account);
        }
        if (lastFailure != null) {
            if (wasPermanentFailure) {
                notificationController.showSendFailedNotification(account, lastFailure);
            } else {
                notificationController.showSendFailedNotification(account, lastFailure);
            }
        }
    } catch (UnavailableStorageException e) {
        Timber.i("Failed to send pending messages because storage is not available - trying again later.");
        throw new UnavailableAccountException(e);
    } catch (Exception e) {
        Timber.v(e, "Failed to send pending messages");
        for (MessagingListener l : getListeners()) {
            l.sendPendingMessagesFailed(account);
        }
        addErrorMessage(account, null, e);
    } finally {
        if (lastFailure == null) {
            notificationController.clearSendFailedNotification(account);
        }
        closeFolder(localFolder);
    }
}
Also used : LocalMessage(com.fsck.k9.mailstore.LocalMessage) FetchProfile(com.fsck.k9.mail.FetchProfile) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) LocalStore(com.fsck.k9.mailstore.LocalStore) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) SuppressLint(android.annotation.SuppressLint) LocalFolder(com.fsck.k9.mailstore.LocalFolder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) Transport(com.fsck.k9.mail.Transport) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 3 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project k-9 by k9mail.

the class MessagingController method searchLocalMessagesSynchronous.

@VisibleForTesting
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
    final AccountStats stats = new AccountStats();
    final Set<String> uuidSet = new HashSet<>(Arrays.asList(search.getAccountUuids()));
    List<Account> accounts = Preferences.getPreferences(context).getAccounts();
    boolean allAccounts = uuidSet.contains(SearchSpecification.ALL_ACCOUNTS);
    // for every account we want to search do the query in the localstore
    for (final Account account : accounts) {
        if (!allAccounts && !uuidSet.contains(account.getUuid())) {
            continue;
        }
        // Collecting statistics of the search result
        MessageRetrievalListener<LocalMessage> retrievalListener = new MessageRetrievalListener<LocalMessage>() {

            @Override
            public void messageStarted(String message, int number, int ofTotal) {
            }

            @Override
            public void messagesFinished(int number) {
            }

            @Override
            public void messageFinished(LocalMessage message, int number, int ofTotal) {
                if (!isMessageSuppressed(message)) {
                    List<LocalMessage> messages = new ArrayList<>();
                    messages.add(message);
                    stats.unreadMessageCount += (!message.isSet(Flag.SEEN)) ? 1 : 0;
                    stats.flaggedMessageCount += (message.isSet(Flag.FLAGGED)) ? 1 : 0;
                    if (listener != null) {
                        listener.listLocalMessagesAddMessages(account, null, messages);
                    }
                }
            }
        };
        // build and do the query in the localstore
        try {
            LocalStore localStore = account.getLocalStore();
            localStore.searchForMessages(retrievalListener, search);
        } catch (Exception e) {
            addErrorMessage(account, null, e);
        }
    }
    // publish the total search statistics
    if (listener != null) {
        listener.searchStats(stats);
    }
}
Also used : SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) LocalMessage(com.fsck.k9.mailstore.LocalMessage) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) MessageRetrievalListener(com.fsck.k9.mail.MessageRetrievalListener) AccountStats(com.fsck.k9.AccountStats) HashSet(java.util.HashSet) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 4 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project k-9 by k9mail.

the class AttachmentResolver method buildCidToAttachmentUriMap.

@VisibleForTesting
static Map<String, Uri> buildCidToAttachmentUriMap(AttachmentInfoExtractor attachmentInfoExtractor, Part rootPart) {
    HashMap<String, Uri> result = new HashMap<>();
    Stack<Part> partsToCheck = new Stack<>();
    partsToCheck.push(rootPart);
    while (!partsToCheck.isEmpty()) {
        Part part = partsToCheck.pop();
        Body body = part.getBody();
        if (body instanceof Multipart) {
            Multipart multipart = (Multipart) body;
            for (Part bodyPart : multipart.getBodyParts()) {
                partsToCheck.push(bodyPart);
            }
        } else {
            try {
                String contentId = part.getContentId();
                if (contentId != null) {
                    AttachmentViewInfo attachmentInfo = attachmentInfoExtractor.extractAttachmentInfo(part);
                    result.put(contentId, attachmentInfo.internalUri);
                }
            } catch (MessagingException e) {
                Timber.e(e, "Error extracting attachment info");
            }
        }
    }
    return Collections.unmodifiableMap(result);
}
Also used : Multipart(com.fsck.k9.mail.Multipart) HashMap(java.util.HashMap) MessagingException(com.fsck.k9.mail.MessagingException) Part(com.fsck.k9.mail.Part) Uri(android.net.Uri) Body(com.fsck.k9.mail.Body) Stack(java.util.Stack) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 5 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project k-9 by k9mail.

the class MessagingController method clearFolderSynchronous.

@VisibleForTesting
protected void clearFolderSynchronous(Account account, String folderName, MessagingListener listener) {
    LocalFolder localFolder = null;
    try {
        localFolder = account.getLocalStore().getFolder(folderName);
        localFolder.open(Folder.OPEN_MODE_RW);
        localFolder.clearAllMessages();
    } catch (UnavailableStorageException e) {
        Timber.i("Failed to clear folder because storage is not available - trying again later.");
        throw new UnavailableAccountException(e);
    } catch (Exception e) {
        Timber.e(e, "clearFolder failed");
        addErrorMessage(account, null, e);
    } finally {
        closeFolder(localFolder);
    }
    listFoldersSynchronous(account, false, listener);
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) VisibleForTesting(android.support.annotation.VisibleForTesting)

Aggregations

VisibleForTesting (android.support.annotation.VisibleForTesting)59 File (java.io.File)23 FileNotFoundException (java.io.FileNotFoundException)15 Intent (android.content.Intent)11 IOException (java.io.IOException)10 MessagingException (com.fsck.k9.mail.MessagingException)8 ArrayList (java.util.ArrayList)8 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)6 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)6 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)6 Shared.getQuantityString (com.android.documentsui.Shared.getQuantityString)5 RootInfo (com.android.documentsui.model.RootInfo)5 LocalFolder (com.fsck.k9.mailstore.LocalFolder)5 LocalStore (com.fsck.k9.mailstore.LocalStore)5 SuppressLint (android.annotation.SuppressLint)4 LocalMessage (com.fsck.k9.mailstore.LocalMessage)4 HashMap (java.util.HashMap)4 Bundle (android.os.Bundle)3 Folder (com.fsck.k9.mail.Folder)3 Message (com.fsck.k9.mail.Message)3