From c4b1963f806a22160ffeb6a876e51f439a2d5034 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 14 Aug 2018 11:45:12 +0000 Subject: [PATCH] Let outbox show connectivity --- .../java/eu/faircode/email/AdapterFolder.java | 5 +- .../eu/faircode/email/FragmentAccount.java | 4 +- .../eu/faircode/email/FragmentFolder.java | 2 +- .../eu/faircode/email/FragmentIdentity.java | 4 +- .../eu/faircode/email/ServiceSynchronize.java | 195 ++++++++++-------- 5 files changed, 116 insertions(+), 94 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/AdapterFolder.java b/app/src/main/java/eu/faircode/email/AdapterFolder.java index cf78d1dd22..6114d02867 100644 --- a/app/src/main/java/eu/faircode/email/AdapterFolder.java +++ b/app/src/main/java/eu/faircode/email/AdapterFolder.java @@ -84,7 +84,8 @@ public class AdapterFolder extends RecyclerView.Adapter 0) @@ -113,7 +114,7 @@ public class AdapterFolder extends RecyclerView.Adapter threads = new ArrayList<>(); + final ExecutorService executor = Executors.newSingleThreadExecutor(); + Log.i(Helper.TAG, account.name + " start"); final DB db = DB.getInstance(ServiceSynchronize.this); @@ -520,7 +522,7 @@ public class ServiceSynchronize extends LifecycleService { } } - BroadcastReceiver processReceiver = new BroadcastReceiver() { + private BroadcastReceiver processReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final long fid = intent.getLongExtra("folder", -1); @@ -533,41 +535,45 @@ public class ServiceSynchronize extends LifecycleService { final IMAPFolder ffolder = ifolder; Log.i(Helper.TAG, "run operations folder=" + fid + " offline=" + shouldClose); - executor.submit(new Runnable() { - @Override - public void run() { - DB db = DB.getInstance(ServiceSynchronize.this); - EntityFolder folder = db.folder().getFolder(fid); - IMAPFolder ifolder = ffolder; - try { - Log.i(Helper.TAG, folder.name + " start operations"); + try { + executor.submit(new Runnable() { + @Override + public void run() { + DB db = DB.getInstance(ServiceSynchronize.this); + EntityFolder folder = db.folder().getFolder(fid); + IMAPFolder ifolder = ffolder; + try { + Log.i(Helper.TAG, folder.name + " start operations"); - if (ifolder == null) { - // Prevent unnecessary folder connections - if (db.operation().getOperationCount(fid) == 0) - return; + if (ifolder == null) { + // Prevent unnecessary folder connections + if (db.operation().getOperationCount(fid) == 0) + return; - ifolder = (IMAPFolder) fstore.getFolder(folder.name); - ifolder.open(Folder.READ_WRITE); - } + ifolder = (IMAPFolder) fstore.getFolder(folder.name); + ifolder.open(Folder.READ_WRITE); + } - processOperations(folder, isession, fstore, ifolder); - } catch (Throwable ex) { - Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); - reportError(account.name, folder.name, ex); - } finally { - if (shouldClose) - if (ifolder != null && ifolder.isOpen()) { - try { - ifolder.close(false); - } catch (MessagingException ex) { - Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); + processOperations(folder, isession, fstore, ifolder); + } catch (Throwable ex) { + Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); + reportError(account.name, folder.name, ex); + } finally { + if (shouldClose) + if (ifolder != null && ifolder.isOpen()) { + try { + ifolder.close(false); + } catch (MessagingException ex) { + Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); + } } - } - Log.i(Helper.TAG, folder.name + " stop operations"); + Log.i(Helper.TAG, folder.name + " stop operations"); + } } - } - }); + }); + } catch (RejectedExecutionException ex) { + Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); + } } }; }); @@ -642,6 +648,7 @@ public class ServiceSynchronize extends LifecycleService { } } threads.clear(); + executor.shutdown(); Log.i(Helper.TAG, account.name + " stopped"); } @@ -1361,6 +1368,7 @@ public class ServiceSynchronize extends LifecycleService { ServiceState state = new ServiceState(); private Thread main; private EntityFolder outbox = null; + private ExecutorService executor = Executors.newSingleThreadExecutor(); @Override public void onAvailable(Network network) { @@ -1376,57 +1384,71 @@ public class ServiceSynchronize extends LifecycleService { @Override public void run() { DB db = DB.getInstance(ServiceSynchronize.this); + try { + outbox = db.folder().getOutbox(); + if (outbox == null) { + Log.i(Helper.TAG, "No outbox, halt"); + stopSelf(); + return; + } + List accounts = db.account().getAccounts(true); if (accounts.size() == 0) { Log.i(Helper.TAG, "No accounts, halt"); stopSelf(); - } else - for (final EntityAccount account : accounts) { - Log.i(Helper.TAG, account.host + "/" + account.user + " run"); - - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - monitorAccount(account, state); - } catch (Throwable ex) { - // Fall-safe - Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); - } - } - }, "sync.account." + account.id); - t.start(); - threads.add(t); - } - } catch (Throwable ex) { - // Failsafe - Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); - } + return; + } - outbox = db.folder().getOutbox(); - if (outbox != null) try { + // Start monitoring outbox IntentFilter f = new IntentFilter(ACTION_PROCESS_OPERATIONS); f.addDataType("account/outbox"); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(ServiceSynchronize.this); lbm.registerReceiver(outboxReceiver, f); + db.folder().setFolderState(outbox.id, "connected"); lbm.sendBroadcast(new Intent(ACTION_PROCESS_OPERATIONS) .setType("account/outbox") .putExtra("folder", outbox.id)); + + // Start monitoring accounts + for (final EntityAccount account : accounts) { + Log.i(Helper.TAG, account.host + "/" + account.user + " run"); + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + monitorAccount(account, state); + } catch (Throwable ex) { + // Fall-safe + Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); + } + } + }, "sync.account." + account.id); + t.start(); + threads.add(t); + } + + // Stop monitoring accounts + for (Thread t : threads) + try { + Log.i(Helper.TAG, "Joining " + t.getName()); + t.join(); + Log.i(Helper.TAG, "Joined " + t.getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + threads.clear(); + executor.shutdown(); + + // Stop monitoring outbox + lbm.unregisterReceiver(outboxReceiver); + Log.i(Helper.TAG, outbox.name + " unlisten operations"); + db.folder().setFolderState(outbox.id, null); } catch (Throwable ex) { + // Fail-safe Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); } - - for (Thread t : threads) - try { - Log.i(Helper.TAG, "Joining " + t.getName()); - t.join(); - Log.i(Helper.TAG, "Joined " + t.getName()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - threads.clear(); } }, "sync.main"); main.start(); @@ -1441,12 +1463,6 @@ public class ServiceSynchronize extends LifecycleService { state.notifyAll(); } - if (outbox != null) { - LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(ServiceSynchronize.this); - lbm.unregisterReceiver(outboxReceiver); - Log.i(Helper.TAG, outbox.name + " unlisten operations"); - } - try { Log.i(Helper.TAG, "Joining " + main.getName()); main.join(); @@ -1454,27 +1470,32 @@ public class ServiceSynchronize extends LifecycleService { } catch (InterruptedException ex) { Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); } + main = null; } - BroadcastReceiver outboxReceiver = new BroadcastReceiver() { + private BroadcastReceiver outboxReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i(Helper.TAG, outbox.name + " run operations"); - executor.submit(new Runnable() { - @Override - public void run() { - try { - Log.i(Helper.TAG, outbox.name + " start operations"); - processOperations(outbox, null, null, null); - } catch (Throwable ex) { - Log.e(Helper.TAG, outbox.name + " " + ex + "\n" + Log.getStackTraceString(ex)); - reportError(null, outbox.name, ex); - } finally { - Log.i(Helper.TAG, outbox.name + " end operations"); + try { + executor.submit(new Runnable() { + @Override + public void run() { + try { + Log.i(Helper.TAG, outbox.name + " start operations"); + processOperations(outbox, null, null, null); + } catch (Throwable ex) { + Log.e(Helper.TAG, outbox.name + " " + ex + "\n" + Log.getStackTraceString(ex)); + reportError(null, outbox.name, ex); + } finally { + Log.i(Helper.TAG, outbox.name + " end operations"); + } } - } - }); + }); + } catch (RejectedExecutionException ex) { + Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); + } } }; }; @@ -1524,7 +1545,7 @@ public class ServiceSynchronize extends LifecycleService { stopSelf(); } - public static void stopSynchroneous(Context context, String reason) { + public static void stopSynchronous(Context context, String reason) { Log.i(Helper.TAG, "Stop because of '" + reason + "'"); final Object lock = new Object();