Prevent concurrent access to fields in ActivityListener

This commit is contained in:
cketti 2017-08-29 18:04:39 +02:00
parent 74bcc44f3e
commit 349b7bbcee
2 changed files with 100 additions and 48 deletions

View file

@ -35,6 +35,7 @@ dependencies {
compile 'com.github.amlcurran.showcaseview:library:5.4.1' compile 'com.github.amlcurran.showcaseview:library:5.4.1'
compile 'com.squareup.moshi:moshi:1.2.0' compile 'com.squareup.moshi:moshi:1.2.0'
compile "com.jakewharton.timber:timber:${timberVersion}" compile "com.jakewharton.timber:timber:${timberVersion}"
compile 'net.jcip:jcip-annotations:1.0'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

View file

@ -13,18 +13,21 @@ import com.fsck.k9.K9;
import com.fsck.k9.R; import com.fsck.k9.R;
import com.fsck.k9.controller.SimpleMessagingListener; import com.fsck.k9.controller.SimpleMessagingListener;
import com.fsck.k9.service.MailService; import com.fsck.k9.service.MailService;
import net.jcip.annotations.GuardedBy;
public class ActivityListener extends SimpleMessagingListener { public class ActivityListener extends SimpleMessagingListener {
private Account account = null; private final Object lock = new Object();
private String loadingFolderName = null;
private String loadingHeaderFolderName = null; @GuardedBy("lock") private Account account = null;
private String loadingAccountDescription = null; @GuardedBy("lock") private String loadingFolderName = null;
private String sendingAccountDescription = null; @GuardedBy("lock") private String loadingHeaderFolderName = null;
private int folderCompleted = 0; @GuardedBy("lock") private String loadingAccountDescription = null;
private int folderTotal = 0; @GuardedBy("lock") private String sendingAccountDescription = null;
private String processingAccountDescription = null; @GuardedBy("lock") private int folderCompleted = 0;
private String processingCommandTitle = null; @GuardedBy("lock") private int folderTotal = 0;
@GuardedBy("lock") private String processingAccountDescription = null;
@GuardedBy("lock") private String processingCommandTitle = null;
private BroadcastReceiver tickReceiver = new BroadcastReceiver() { private BroadcastReceiver tickReceiver = new BroadcastReceiver() {
@Override @Override
@ -35,12 +38,14 @@ public class ActivityListener extends SimpleMessagingListener {
public String getOperation(Context context) { public String getOperation(Context context) {
synchronized (lock) {
if (loadingAccountDescription != null || if (loadingAccountDescription != null ||
sendingAccountDescription != null || sendingAccountDescription != null ||
loadingHeaderFolderName != null || loadingHeaderFolderName != null ||
processingAccountDescription != null) { processingAccountDescription != null) {
return getActionInProgressOperation(context); return getActionInProgressOperation(context);
} }
}
long nextPollTime = MailService.getNextPollTime(); long nextPollTime = MailService.getNextPollTime();
if (nextPollTime != -1) { if (nextPollTime != -1) {
@ -66,15 +71,16 @@ public class ActivityListener extends SimpleMessagingListener {
} }
} }
@GuardedBy("lock")
private String getActionInProgressOperation(Context context) { private String getActionInProgressOperation(Context context) {
String progress = folderTotal > 0 ? String progress = folderTotal > 0 ?
context.getString(R.string.folder_progress, folderCompleted, folderTotal) : ""; context.getString(R.string.folder_progress, folderCompleted, folderTotal) : "";
if (loadingFolderName != null || loadingHeaderFolderName != null) { if (loadingFolderName != null || loadingHeaderFolderName != null) {
String displayName = null; String displayName;
if (loadingHeaderFolderName != null) { if (loadingHeaderFolderName != null) {
displayName = loadingHeaderFolderName; displayName = loadingHeaderFolderName;
} else if (loadingFolderName != null) { } else {
displayName = loadingFolderName; displayName = loadingFolderName;
} }
if (account != null && account.getInboxFolderName() != null && if (account != null && account.getInboxFolderName() != null &&
@ -116,101 +122,142 @@ public class ActivityListener extends SimpleMessagingListener {
@Override @Override
public void synchronizeMailboxFinished(Account account, String folder, int totalMessagesInMailbox, public void synchronizeMailboxFinished(Account account, String folder, int totalMessagesInMailbox,
int numNewMessages) { int numNewMessages) {
synchronized (lock) {
loadingAccountDescription = null; loadingAccountDescription = null;
loadingFolderName = null; loadingFolderName = null;
this.account = null; this.account = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxStarted(Account account, String folder) { public void synchronizeMailboxStarted(Account account, String folder) {
synchronized (lock) {
loadingAccountDescription = account.getDescription(); loadingAccountDescription = account.getDescription();
loadingFolderName = folder; loadingFolderName = folder;
this.account = account; this.account = account;
folderCompleted = 0; folderCompleted = 0;
folderTotal = 0; folderTotal = 0;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxHeadersStarted(Account account, String folder) { public void synchronizeMailboxHeadersStarted(Account account, String folder) {
synchronized (lock) {
loadingAccountDescription = account.getDescription(); loadingAccountDescription = account.getDescription();
loadingHeaderFolderName = folder; loadingHeaderFolderName = folder;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxHeadersProgress(Account account, String folder, int completed, int total) { public void synchronizeMailboxHeadersProgress(Account account, String folder, int completed, int total) {
synchronized (lock) {
folderCompleted = completed; folderCompleted = completed;
folderTotal = total; folderTotal = total;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxHeadersFinished(Account account, String folder, int total, int completed) { public void synchronizeMailboxHeadersFinished(Account account, String folder, int total, int completed) {
synchronized (lock) {
loadingHeaderFolderName = null; loadingHeaderFolderName = null;
folderCompleted = 0; folderCompleted = 0;
folderTotal = 0; folderTotal = 0;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxProgress(Account account, String folder, int completed, int total) { public void synchronizeMailboxProgress(Account account, String folder, int completed, int total) {
synchronized (lock) {
folderCompleted = completed; folderCompleted = completed;
folderTotal = total; folderTotal = total;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void synchronizeMailboxFailed(Account account, String folder, String message) { public void synchronizeMailboxFailed(Account account, String folder, String message) {
synchronized (lock) {
loadingAccountDescription = null; loadingAccountDescription = null;
loadingHeaderFolderName = null; loadingHeaderFolderName = null;
loadingFolderName = null; loadingFolderName = null;
this.account = null; this.account = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void sendPendingMessagesStarted(Account account) { public void sendPendingMessagesStarted(Account account) {
synchronized (lock) {
sendingAccountDescription = account.getDescription(); sendingAccountDescription = account.getDescription();
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void sendPendingMessagesCompleted(Account account) { public void sendPendingMessagesCompleted(Account account) {
synchronized (lock) {
sendingAccountDescription = null; sendingAccountDescription = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void sendPendingMessagesFailed(Account account) { public void sendPendingMessagesFailed(Account account) {
synchronized (lock) {
sendingAccountDescription = null; sendingAccountDescription = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void pendingCommandsProcessing(Account account) { public void pendingCommandsProcessing(Account account) {
synchronized (lock) {
processingAccountDescription = account.getDescription(); processingAccountDescription = account.getDescription();
folderCompleted = 0; folderCompleted = 0;
folderTotal = 0; folderTotal = 0;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void pendingCommandsFinished(Account account) { public void pendingCommandsFinished(Account account) {
synchronized (lock) {
processingAccountDescription = null; processingAccountDescription = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void pendingCommandStarted(Account account, String commandTitle) { public void pendingCommandStarted(Account account, String commandTitle) {
synchronized (lock) {
processingCommandTitle = commandTitle; processingCommandTitle = commandTitle;
}
informUserOfStatus(); informUserOfStatus();
} }
@Override @Override
public void pendingCommandCompleted(Account account, String commandTitle) { public void pendingCommandCompleted(Account account, String commandTitle) {
synchronized (lock) {
processingCommandTitle = null; processingCommandTitle = null;
}
informUserOfStatus(); informUserOfStatus();
} }
@ -230,10 +277,14 @@ public class ActivityListener extends SimpleMessagingListener {
} }
public int getFolderCompleted() { public int getFolderCompleted() {
synchronized (lock) {
return folderCompleted; return folderCompleted;
} }
}
public int getFolderTotal() { public int getFolderTotal() {
synchronized (lock) {
return folderTotal; return folderTotal;
} }
} }
}