From 0e8912714e4228a2b13425cda007a01af792e4b8 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sun, 19 Aug 2018 01:32:15 +0200 Subject: [PATCH] start imap- and smtp-threads when creating context --- .../securesms/ApplicationDcContext.java | 143 +++++++++++++++++- .../securesms/ForegroundDetector.java | 8 +- 2 files changed, 144 insertions(+), 7 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ApplicationDcContext.java b/src/org/thoughtcrime/securesms/ApplicationDcContext.java index 4026e7257..cb9bb269f 100644 --- a/src/org/thoughtcrime/securesms/ApplicationDcContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationDcContext.java @@ -17,6 +17,7 @@ package org.thoughtcrime.securesms; import android.content.Context; +import android.os.PowerManager; import android.util.Log; import android.widget.Toast; @@ -34,18 +35,152 @@ import java.net.URL; public class ApplicationDcContext extends DcContext { - public static final Object lastErrorLock = new Object(); - public static int lastErrorCode = 0; - public static String lastErrorString = ""; - public static boolean showNextErrorAsToast = true; public Context context; public ApplicationDcContext(Context context) { super("Android"); this.context = context; + + // create wake locks + try { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + + imapWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "imapWakeLock"); + imapWakeLock.setReferenceCounted(false); // if the idle-thread is killed for any reasons, it is better not to rely on reference counting + + smtpWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "smtpWakeLock"); + smtpWakeLock.setReferenceCounted(false); // if the idle-thread is killed for any reasons, it is better not to rely on reference counting + + afterForgroundWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "afterForegroundWakeLock"); + afterForgroundWakeLock.setReferenceCounted(false); + + } catch (Exception e) { + Log.e("DeltaChat", "Cannot create wakeLocks"); + } + new ForegroundDetector(ApplicationContext.getInstance(context)); + startThreads(); } + + /*********************************************************************************************** + * Working Threads + **********************************************************************************************/ + + + private final Object threadsCritical = new Object(); + + private boolean imapThreadStartedVal; + private final Object imapThreadStartedCond = new Object(); + public Thread imapThread = null; + private PowerManager.WakeLock imapWakeLock = null; + + private boolean smtpThreadStartedVal; + private final Object smtpThreadStartedCond = new Object(); + public Thread smtpThread = null; + private PowerManager.WakeLock smtpWakeLock = null; + + public PowerManager.WakeLock afterForgroundWakeLock = null; + + public void startThreads() + { + synchronized(threadsCritical) { + + if (imapThread == null || !imapThread.isAlive()) { + + synchronized (imapThreadStartedCond) { + imapThreadStartedVal = false; + } + + imapThread = new Thread(new Runnable() { + @Override + public void run() { + // raise the starting condition + // after acquiring a wakelock so that the process is not terminated. + // as imapWakeLock is not reference counted that would result in a wakelock-gap is not needed here. + imapWakeLock.acquire(); + synchronized (imapThreadStartedCond) { + imapThreadStartedVal = true; + imapThreadStartedCond.notifyAll(); + } + + Log.i("DeltaChat", "###################### IMAP-Thread started. ######################"); + + + while (true) { + imapWakeLock.acquire(); + performJobs(); + fetch(); + imapWakeLock.release(); + idle(); + } + } + }, "imapThread"); + imapThread.start(); + } + + if (smtpThread == null || !smtpThread.isAlive()) { + + synchronized (smtpThreadStartedCond) { + smtpThreadStartedVal = false; + } + + smtpThread = new Thread(new Runnable() { + @Override + public void run() { + smtpWakeLock.acquire(); + synchronized (smtpThreadStartedCond) { + smtpThreadStartedVal = true; + smtpThreadStartedCond.notifyAll(); + } + + Log.i("DeltaChat", "###################### SMTP-Thread started. ######################"); + + + while (true) { + smtpWakeLock.acquire(); + performSmtpJobs(); + smtpWakeLock.release(); + performSmtpIdle(); + } + } + }, "smtpThread"); + smtpThread.start(); + } + } + } + + public void waitForThreadsRunning() + { + try { + synchronized( imapThreadStartedCond ) { + while( !imapThreadStartedVal ) { + imapThreadStartedCond.wait(); + } + } + + synchronized( smtpThreadStartedCond ) { + while( !smtpThreadStartedVal ) { + smtpThreadStartedCond.wait(); + } + } + } + catch( Exception e ) { + e.printStackTrace(); + } + } + + + /*********************************************************************************************** + * Event Handling + **********************************************************************************************/ + + + public final Object lastErrorLock = new Object(); + public int lastErrorCode = 0; + public String lastErrorString = ""; + public boolean showNextErrorAsToast = true; + @Override public long handleEvent(final int event, final long data1, final long data2) { switch(event) { case DC_EVENT_INFO: diff --git a/src/org/thoughtcrime/securesms/ForegroundDetector.java b/src/org/thoughtcrime/securesms/ForegroundDetector.java index 8775566ae..cb8546d8b 100644 --- a/src/org/thoughtcrime/securesms/ForegroundDetector.java +++ b/src/org/thoughtcrime/securesms/ForegroundDetector.java @@ -27,13 +27,15 @@ public class ForegroundDetector implements Application.ActivityLifecycleCallback private int refs = 0; private static ForegroundDetector Instance = null; + ApplicationContext application; public static ForegroundDetector getInstance() { return Instance; } - public ForegroundDetector(Application application) { + public ForegroundDetector(ApplicationContext application) { Instance = this; + this.application = application; application.registerActivityLifecycleCallbacks(this); } @@ -50,7 +52,7 @@ public class ForegroundDetector implements Application.ActivityLifecycleCallback refs++; //applicationContext.stopService(new Intent(applicationContext, KeepAliveService.class)); - //ApplicationLoader.startThreads(); // we call this without checking getPermanentPush() to have a simple guarantee that push is always active when the app is in foregroud (startIdleThread makes sure the thread is not started twice) + application.dcContext.startThreads(); // we call this without checking getPermanentPush() to have a simple guarantee that push is always active when the app is in foregroud (startIdleThread makes sure the thread is not started twice) } @@ -62,7 +64,7 @@ public class ForegroundDetector implements Application.ActivityLifecycleCallback refs--; if (refs == 0) { - //ApplicationLoader.afterForgroundWakeLock.acquire(60*1000); + application.dcContext.afterForgroundWakeLock.acquire(60*1000); } }