Search in sources :

Example 31 with VisibleForTesting

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

the class ContactPictureLoader method calcUnknownContactLetter.

@VisibleForTesting
protected static String calcUnknownContactLetter(Address address) {
    String letter = null;
    String personal = address.getPersonal();
    String str = (personal != null) ? personal : address.getAddress();
    Matcher m = EXTRACT_LETTER_PATTERN.matcher(str);
    if (m.find()) {
        letter = m.group(0).toUpperCase(Locale.US);
    }
    return (TextUtils.isEmpty(letter)) ? FALLBACK_CONTACT_LETTER : letter;
}
Also used : Matcher(java.util.regex.Matcher) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 32 with VisibleForTesting

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

the class MessagingController method synchronizeMailboxSynchronous.

/**
     * Start foreground synchronization of the specified folder. This is generally only called
     * by synchronizeMailbox.
     * <p>
     * TODO Break this method up into smaller chunks.
     */
@VisibleForTesting
void synchronizeMailboxSynchronous(final Account account, final String folder, final MessagingListener listener, Folder providedRemoteFolder) {
    Folder remoteFolder = null;
    LocalFolder tLocalFolder = null;
    Timber.i("Synchronizing folder %s:%s", account.getDescription(), folder);
    for (MessagingListener l : getListeners(listener)) {
        l.synchronizeMailboxStarted(account, folder);
    }
    /*
         * We don't ever sync the Outbox or errors folder
         */
    if (folder.equals(account.getOutboxFolderName()) || folder.equals(account.getErrorFolderName())) {
        for (MessagingListener l : getListeners(listener)) {
            l.synchronizeMailboxFinished(account, folder, 0, 0);
        }
        return;
    }
    Exception commandException = null;
    try {
        Timber.d("SYNC: About to process pending commands for account %s", account.getDescription());
        try {
            processPendingCommandsSynchronous(account);
        } catch (Exception e) {
            addErrorMessage(account, null, e);
            Timber.e(e, "Failure processing command, but allow message sync attempt");
            commandException = e;
        }
        /*
             * Get the message list from the local store and create an index of
             * the uids within the list.
             */
        Timber.v("SYNC: About to get local folder %s", folder);
        final LocalStore localStore = account.getLocalStore();
        tLocalFolder = localStore.getFolder(folder);
        final LocalFolder localFolder = tLocalFolder;
        localFolder.open(Folder.OPEN_MODE_RW);
        localFolder.updateLastUid();
        Map<String, Long> localUidMap = localFolder.getAllMessagesAndEffectiveDates();
        if (providedRemoteFolder != null) {
            Timber.v("SYNC: using providedRemoteFolder %s", folder);
            remoteFolder = providedRemoteFolder;
        } else {
            Store remoteStore = account.getRemoteStore();
            Timber.v("SYNC: About to get remote folder %s", folder);
            remoteFolder = remoteStore.getFolder(folder);
            if (!verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener)) {
                return;
            }
            /*
                 * Synchronization process:
                 *
                Open the folder
                Upload any local messages that are marked as PENDING_UPLOAD (Drafts, Sent, Trash)
                Get the message count
                Get the list of the newest K9.DEFAULT_VISIBLE_LIMIT messages
                getMessages(messageCount - K9.DEFAULT_VISIBLE_LIMIT, messageCount)
                See if we have each message locally, if not fetch it's flags and envelope
                Get and update the unread count for the folder
                Update the remote flags of any messages we have locally with an internal date newer than the remote message.
                Get the current flags for any messages we have locally but did not just download
                Update local flags
                For any message we have locally but not remotely, delete the local message to keep cache clean.
                Download larger parts of any new messages.
                (Optional) Download small attachments in the background.
                 */
            /*
                 * Open the remote folder. This pre-loads certain metadata like message count.
                 */
            Timber.v("SYNC: About to open remote folder %s", folder);
            remoteFolder.open(Folder.OPEN_MODE_RW);
            if (Expunge.EXPUNGE_ON_POLL == account.getExpungePolicy()) {
                Timber.d("SYNC: Expunging folder %s:%s", account.getDescription(), folder);
                remoteFolder.expunge();
            }
        }
        notificationController.clearAuthenticationErrorNotification(account, true);
        /*
             * Get the remote message count.
             */
        int remoteMessageCount = remoteFolder.getMessageCount();
        int visibleLimit = localFolder.getVisibleLimit();
        if (visibleLimit < 0) {
            visibleLimit = K9.DEFAULT_VISIBLE_LIMIT;
        }
        final List<Message> remoteMessages = new ArrayList<>();
        Map<String, Message> remoteUidMap = new HashMap<>();
        Timber.v("SYNC: Remote message count for folder %s is %d", folder, remoteMessageCount);
        final Date earliestDate = account.getEarliestPollDate();
        long earliestTimestamp = earliestDate != null ? earliestDate.getTime() : 0L;
        int remoteStart = 1;
        if (remoteMessageCount > 0) {
            /* Message numbers start at 1.  */
            if (visibleLimit > 0) {
                remoteStart = Math.max(0, remoteMessageCount - visibleLimit) + 1;
            } else {
                remoteStart = 1;
            }
            Timber.v("SYNC: About to get messages %d through %d for folder %s", remoteStart, remoteMessageCount, folder);
            final AtomicInteger headerProgress = new AtomicInteger(0);
            for (MessagingListener l : getListeners(listener)) {
                l.synchronizeMailboxHeadersStarted(account, folder);
            }
            List<? extends Message> remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteMessageCount, earliestDate, null);
            int messageCount = remoteMessageArray.size();
            for (Message thisMess : remoteMessageArray) {
                headerProgress.incrementAndGet();
                for (MessagingListener l : getListeners(listener)) {
                    l.synchronizeMailboxHeadersProgress(account, folder, headerProgress.get(), messageCount);
                }
                Long localMessageTimestamp = localUidMap.get(thisMess.getUid());
                if (localMessageTimestamp == null || localMessageTimestamp >= earliestTimestamp) {
                    remoteMessages.add(thisMess);
                    remoteUidMap.put(thisMess.getUid(), thisMess);
                }
            }
            Timber.v("SYNC: Got %d messages for folder %s", remoteUidMap.size(), folder);
            for (MessagingListener l : getListeners(listener)) {
                l.synchronizeMailboxHeadersFinished(account, folder, headerProgress.get(), remoteUidMap.size());
            }
        } else if (remoteMessageCount < 0) {
            throw new Exception("Message count " + remoteMessageCount + " for folder " + folder);
        }
        /*
             * Remove any messages that are in the local store but no longer on the remote store or are too old
             */
        MoreMessages moreMessages = localFolder.getMoreMessages();
        if (account.syncRemoteDeletions()) {
            List<String> destroyMessageUids = new ArrayList<>();
            for (String localMessageUid : localUidMap.keySet()) {
                if (remoteUidMap.get(localMessageUid) == null) {
                    destroyMessageUids.add(localMessageUid);
                }
            }
            List<LocalMessage> destroyMessages = localFolder.getMessagesByUids(destroyMessageUids);
            if (!destroyMessageUids.isEmpty()) {
                moreMessages = MoreMessages.UNKNOWN;
                localFolder.destroyMessages(destroyMessages);
                for (Message destroyMessage : destroyMessages) {
                    for (MessagingListener l : getListeners(listener)) {
                        l.synchronizeMailboxRemovedMessage(account, folder, destroyMessage);
                    }
                }
            }
        }
        // noinspection UnusedAssignment, free memory early? (better break up the method!)
        localUidMap = null;
        if (moreMessages == MoreMessages.UNKNOWN) {
            updateMoreMessages(remoteFolder, localFolder, earliestDate, remoteStart);
        }
        /*
             * Now we download the actual content of messages.
             */
        int newMessages = downloadMessages(account, remoteFolder, localFolder, remoteMessages, false, true);
        int unreadMessageCount = localFolder.getUnreadMessageCount();
        for (MessagingListener l : getListeners()) {
            l.folderStatusChanged(account, folder, unreadMessageCount);
        }
        /* Notify listeners that we're finally done. */
        localFolder.setLastChecked(System.currentTimeMillis());
        localFolder.setStatus(null);
        Timber.d("Done synchronizing folder %s:%s @ %tc with %d new messages", account.getDescription(), folder, System.currentTimeMillis(), newMessages);
        for (MessagingListener l : getListeners(listener)) {
            l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages);
        }
        if (commandException != null) {
            String rootMessage = getRootCauseMessage(commandException);
            Timber.e("Root cause failure in %s:%s was '%s'", account.getDescription(), tLocalFolder.getName(), rootMessage);
            localFolder.setStatus(rootMessage);
            for (MessagingListener l : getListeners(listener)) {
                l.synchronizeMailboxFailed(account, folder, rootMessage);
            }
        }
        Timber.i("Done synchronizing folder %s:%s", account.getDescription(), folder);
    } catch (AuthenticationFailedException e) {
        handleAuthenticationFailure(account, true);
        for (MessagingListener l : getListeners(listener)) {
            l.synchronizeMailboxFailed(account, folder, "Authentication failure");
        }
    } catch (Exception e) {
        Timber.e(e, "synchronizeMailbox");
        // If we don't set the last checked, it can try too often during
        // failure conditions
        String rootMessage = getRootCauseMessage(e);
        if (tLocalFolder != null) {
            try {
                tLocalFolder.setStatus(rootMessage);
                tLocalFolder.setLastChecked(System.currentTimeMillis());
            } catch (MessagingException me) {
                Timber.e(e, "Could not set last checked on folder %s:%s", account.getDescription(), tLocalFolder.getName());
            }
        }
        for (MessagingListener l : getListeners(listener)) {
            l.synchronizeMailboxFailed(account, folder, rootMessage);
        }
        notifyUserIfCertificateProblem(account, e, true);
        addErrorMessage(account, null, e);
        Timber.e("Failed synchronizing folder %s:%s @ %tc", account.getDescription(), folder, System.currentTimeMillis());
    } finally {
        if (providedRemoteFolder == null) {
            closeFolder(remoteFolder);
        }
        closeFolder(tLocalFolder);
    }
}
Also used : LocalMessage(com.fsck.k9.mailstore.LocalMessage) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Message(com.fsck.k9.mail.Message) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) Store(com.fsck.k9.mail.Store) Pop3Store(com.fsck.k9.mail.store.pop3.Pop3Store) LocalStore(com.fsck.k9.mailstore.LocalStore) Folder(com.fsck.k9.mail.Folder) LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) MessagingException(com.fsck.k9.mail.MessagingException) 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) Date(java.util.Date) LocalFolder(com.fsck.k9.mailstore.LocalFolder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MoreMessages(com.fsck.k9.mailstore.LocalFolder.MoreMessages) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 33 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project BottomBar by roughike.

the class BottomBarTab method saveState.

@VisibleForTesting
Bundle saveState() {
    Bundle outState = new Bundle();
    outState.putInt(STATE_BADGE_COUNT + getIndexInTabContainer(), badge.getCount());
    return outState;
}
Also used : Bundle(android.os.Bundle) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 34 with VisibleForTesting

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

the class AttachmentDatabase method updateAttachmentThumbnail.

@VisibleForTesting
protected void updateAttachmentThumbnail(MasterSecret masterSecret, AttachmentId attachmentId, InputStream in, float aspectRatio) throws MmsException {
    Log.w(TAG, "updating part thumbnail for #" + attachmentId);
    Pair<File, Long> thumbnailFile = setAttachmentData(masterSecret, in);
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    ContentValues values = new ContentValues(2);
    values.put(THUMBNAIL, thumbnailFile.first.getAbsolutePath());
    values.put(THUMBNAIL_ASPECT_RATIO, aspectRatio);
    database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings());
    Cursor cursor = database.query(TABLE_NAME, new String[] { MMS_ID }, PART_ID_WHERE, attachmentId.toStrings(), null, null, null);
    try {
        if (cursor != null && cursor.moveToFirst()) {
            notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID))));
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
}
Also used : ContentValues(android.content.ContentValues) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) Cursor(android.database.Cursor) File(java.io.File) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 35 with VisibleForTesting

use of android.support.annotation.VisibleForTesting in project platform_frameworks_base by android.

the class RootsCache method getMatchingRoots.

@VisibleForTesting
static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
    final List<RootInfo> matching = new ArrayList<>();
    for (RootInfo root : roots) {
        if (DEBUG)
            Log.d(TAG, "Evaluating " + root);
        if (state.action == State.ACTION_CREATE && !root.supportsCreate()) {
            if (DEBUG)
                Log.d(TAG, "Excluding read-only root because: ACTION_CREATE.");
            continue;
        }
        if (state.action == State.ACTION_PICK_COPY_DESTINATION && !root.supportsCreate()) {
            if (DEBUG)
                Log.d(TAG, "Excluding read-only root because: ACTION_PICK_COPY_DESTINATION.");
            continue;
        }
        if (state.action == State.ACTION_OPEN_TREE && !root.supportsChildren()) {
            if (DEBUG)
                Log.d(TAG, "Excluding root !supportsChildren because: ACTION_OPEN_TREE.");
            continue;
        }
        if (!state.showAdvanced && root.isAdvanced()) {
            if (DEBUG)
                Log.d(TAG, "Excluding root because: unwanted advanced device.");
            continue;
        }
        if (state.localOnly && !root.isLocalOnly()) {
            if (DEBUG)
                Log.d(TAG, "Excluding root because: unwanted non-local device.");
            continue;
        }
        if (state.directoryCopy && root.isDownloads()) {
            if (DEBUG)
                Log.d(TAG, "Excluding downloads root because: unsupported directory copy.");
            continue;
        }
        if (state.action == State.ACTION_OPEN && root.isEmpty()) {
            if (DEBUG)
                Log.d(TAG, "Excluding empty root because: ACTION_OPEN.");
            continue;
        }
        if (state.action == State.ACTION_GET_CONTENT && root.isEmpty()) {
            if (DEBUG)
                Log.d(TAG, "Excluding empty root because: ACTION_GET_CONTENT.");
            continue;
        }
        final boolean overlap = MimePredicate.mimeMatches(root.derivedMimeTypes, state.acceptMimes) || MimePredicate.mimeMatches(state.acceptMimes, root.derivedMimeTypes);
        if (!overlap) {
            if (DEBUG)
                Log.d(TAG, "Excluding root because: unsupported content types > " + state.acceptMimes);
            continue;
        }
        if (state.excludedAuthorities.contains(root.authority)) {
            if (DEBUG)
                Log.d(TAG, "Excluding root because: owned by calling package.");
            continue;
        }
        if (DEBUG)
            Log.d(TAG, "Including " + root);
        matching.add(root);
    }
    return matching;
}
Also used : RootInfo(com.android.documentsui.model.RootInfo) ArrayList(java.util.ArrayList) VisibleForTesting(android.support.annotation.VisibleForTesting)

Aggregations

VisibleForTesting (android.support.annotation.VisibleForTesting)63 File (java.io.File)24 FileNotFoundException (java.io.FileNotFoundException)15 Intent (android.content.Intent)11 IOException (java.io.IOException)11 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 HashMap (java.util.HashMap)5 SuppressLint (android.annotation.SuppressLint)4 LocalMessage (com.fsck.k9.mailstore.LocalMessage)4 Bundle (android.os.Bundle)3 Nullable (android.support.annotation.Nullable)3 Folder (com.fsck.k9.mail.Folder)3