@Override public void refresh() { synchronized (folderPushers) { for (ImapFolderPusher folderPusher : folderPushers) { try { folderPusher.refresh(); } catch (Exception e) { Timber.e(e, "Got exception while refreshing for %s", folderPusher.getServerId()); } } } }
@Override public void stop() { if (K9MailLib.isDebug()) { Timber.i("Requested stop of IMAP pusher"); } synchronized (folderPushers) { for (ImapFolderPusher folderPusher : folderPushers) { try { if (K9MailLib.isDebug()) { Timber.i("Requesting stop of IMAP folderPusher %s", folderPusher.getServerId()); } folderPusher.stop(); } catch (Exception e) { Timber.e(e, "Got exception while stopping %s", folderPusher.getServerId()); } } folderPushers.clear(); } }
ImapFolderPusher createImapFolderPusher(String folderName) { return new ImapFolderPusher(store, folderName, pushReceiver, powerManager); }
private long getOldUidNext() { long oldUidNext = -1L; try { String serializedPushState = pushReceiver.getPushState(getServerId()); ImapPushState pushState = ImapPushState.parse(serializedPushState); oldUidNext = pushState.uidNext; if (K9MailLib.isDebug()) { Timber.i("Got oldUidNext %d for %s", oldUidNext, getLogId()); } } catch (Exception e) { Timber.e(e, "Unable to get oldUidNext for %s", getLogId()); } return oldUidNext; } }
@Override public void start(List<String> folderServerIds) { synchronized (folderPushers) { stop(); setLastRefresh(currentTimeMillis()); for (String folderName : folderServerIds) { ImapFolderPusher pusher = createImapFolderPusher(folderName); folderPushers.add(pusher); pusher.start(); } } }
@Test public void stop_withImapFolderPusherThrowing_shouldNotThrow() throws Exception { List<String> folderNames = Collections.singletonList("Archive"); imapPusher.start(folderNames); ImapFolderPusher imapFolderPusher = imapPusher.getImapFolderPushers().get(0); doThrow(RuntimeException.class).when(imapFolderPusher).stop(); imapPusher.stop(); }
Timber.i("Pusher starting for %s", getLogId()); Timber.i("About to IDLE for %s", getLogId()); pushReceiver.pushError("Push error for " + getServerId(), e); } catch (Exception e) { reacquireWakeLockAndCleanUp(); Timber.i("Got exception while idling, but stop is set for %s", getLogId()); } else { pushReceiver.pushError("Push error for " + getServerId(), e); Timber.e("Got exception while idling for %s", getLogId()); Timber.e("Disabling pusher for %s after %d consecutive errors", getLogId(), idleFailureCount); pushReceiver.pushError("Push disabled for " + getServerId() + " after " + idleFailureCount + " consecutive errors", e); stop = true; pushReceiver.setPushActive(getServerId(), false); Timber.i("Pusher for %s is exiting", getLogId()); close(); } catch (Exception me) { Timber.e(me, "Got exception while closing for %s", getLogId()); } finally { wakeLock.release();
@Test public void refresh_withImapFolderPusherThrowing_shouldNotThrow() throws Exception { List<String> folderNames = Collections.singletonList("Folder"); imapPusher.start(folderNames); ImapFolderPusher imapFolderPusher = imapPusher.getImapFolderPushers().get(0); doThrow(RuntimeException.class).when(imapFolderPusher).refresh(); imapPusher.refresh(); }
public void stop() { synchronized (threadLock) { if (listeningThread == null) { throw new IllegalStateException("stop() called twice"); } stop = true; listeningThread.interrupt(); listeningThread = null; } ImapConnection conn = connection; if (conn != null) { if (K9MailLib.isDebug()) { Timber.v("Closing connection to stop pushing for %s", getLogId()); } conn.close(); } else { Timber.w("Attempt to interrupt null connection to stop pushing on folderPusher for %s", getLogId()); } }
private void syncMessages(int end) throws MessagingException { long oldUidNext = getOldUidNext(); List<ImapMessage> messageList = getMessages(end, end, null, true, null); if (messageList != null && messageList.size() > 0) { long newUid = Long.parseLong(messageList.get(0).getUid()); if (K9MailLib.isDebug()) { Timber.i("Got newUid %s for message %d on %s", newUid, end, getLogId()); } long startUid = oldUidNext; if (startUid < newUid - 10) { startUid = newUid - 10; } if (startUid < 1) { startUid = 1; } if (newUid >= startUid) { if (K9MailLib.isDebug()) { Timber.i("Needs sync from uid %d to %d for %s", startUid, newUid, getLogId()); } List<Message> messages = new ArrayList<>(); for (long uid = startUid; uid <= newUid; uid++) { ImapMessage message = new ImapMessage(Long.toString(uid), ImapFolderPusher.this); messages.add(message); } if (!messages.isEmpty()) { pushReceiver.messagesArrived(ImapFolderPusher.this, messages); } } } }
private void prepareForIdle() { pushReceiver.setPushActive(getServerId(), true); idling = true; }
private void syncMessages(List<Long> flagSyncMsgSeqs) { try { Set<Long> messageSeqSet = new HashSet<>(flagSyncMsgSeqs); List<? extends Message> messageList = getMessages(messageSeqSet, true, null); List<Message> messages = new ArrayList<>(messageList); pushReceiver.messagesFlagsChanged(ImapFolderPusher.this, messages); } catch (Exception e) { pushReceiver.pushError("Exception while processing Push untagged responses", e); } }
private void removeMessages(List<String> removeUids) { List<Message> messages = new ArrayList<>(removeUids.size()); try { List<ImapMessage> existingMessages = getMessagesFromUids(removeUids); for (Message existingMessage : existingMessages) { needsPoll = true; msgSeqUidMap.clear(); String existingUid = existingMessage.getUid(); Timber.w("Message with UID %s still exists on server, not expunging", existingUid); removeUids.remove(existingUid); } for (String uid : removeUids) { ImapMessage message = new ImapMessage(uid, ImapFolderPusher.this); try { message.setFlagInternal(Flag.DELETED, true); } catch (MessagingException me) { Timber.e("Unable to set DELETED flag on message %s", message.getUid()); } messages.add(message); } pushReceiver.messagesRemoved(ImapFolderPusher.this, messages); } catch (Exception e) { Timber.e("Cannot remove EXPUNGEd messages"); } }
private long getNewUidNext() throws MessagingException { long newUidNext = uidNext; if (newUidNext != -1L) { return newUidNext; } if (K9MailLib.isDebug()) { Timber.d("uidNext is -1, using search to find highest UID"); } long highestUid = getHighestUid(); if (highestUid == -1L) { return -1L; } newUidNext = highestUid + 1; if (K9MailLib.isDebug()) { Timber.d("highest UID = %d, set newUidNext to %d", highestUid, newUidNext); } return newUidNext; }
@Test public void start_withTwoFolderNames_shouldCreateTwoImapFolderPushersAndCallStart() throws Exception { List<String> folderNames = Arrays.asList("Important", "Drafts"); imapPusher.start(folderNames); List<ImapFolderPusher> imapFolderPushers = imapPusher.getImapFolderPushers(); assertEquals(2, imapFolderPushers.size()); ImapFolderPusher imapFolderPusherOne = imapFolderPushers.get(0); ImapFolderPusher imapFolderPusherTwo = imapFolderPushers.get(1); verify(imapFolderPusherOne).start(); verify(imapFolderPusherTwo).start(); }
@Test public void start_calledAfterStart_shouldStopFirstImapFolderPusher() throws Exception { imapPusher.start(Collections.singletonList("Drafts")); imapPusher.start(Collections.singletonList("INBOX")); ImapFolderPusher draftsPusher = imapPusher.getImapFolderPushers().get(0); verify(draftsPusher).stop(); }
@Test public void refresh_shouldCallRefreshOnStartedImapFolderPusher() throws Exception { List<String> folderNames = Collections.singletonList("Trash"); imapPusher.start(folderNames); imapPusher.refresh(); List<ImapFolderPusher> imapFolderPushers = imapPusher.getImapFolderPushers(); assertEquals(1, imapFolderPushers.size()); ImapFolderPusher imapFolderPusher = imapFolderPushers.get(0); verify(imapFolderPusher).refresh(); }
private void reacquireWakeLockAndCleanUp() { wakeLock.acquire(PUSH_WAKE_LOCK_TIMEOUT); clearStoredUntaggedResponses(); idling = false; pushReceiver.setPushActive(getServerId(), false); try { connection.close(); } catch (Exception me) { Timber.e(me, "Got exception while closing for exception for %s", getLogId()); } connection = null; }
private void notifyMessagesArrived(long startUid, long uidNext) { if (K9MailLib.isDebug()) { Timber.i("Needs sync from uid %d to %d for %s", startUid, uidNext, getLogId()); } int count = (int) (uidNext - startUid); List<Message> messages = new ArrayList<>(count); for (long uid = startUid; uid < uidNext; uid++) { ImapMessage message = new ImapMessage(Long.toString(uid), ImapFolderPusher.this); messages.add(message); } pushReceiver.messagesArrived(ImapFolderPusher.this, messages); }
public ImapFolderPusher(ImapStore store, String serverId, PushReceiver pushReceiver, PowerManager powerManager) { super(store, serverId); this.pushReceiver = pushReceiver; String tag = "ImapFolderPusher " + store.getStoreConfig().toString() + ":" + getServerId(); wakeLock = powerManager.newWakeLock(tag); wakeLock.setReferenceCounted(false); }