From d709ace71c8ebadcf4eb96bd4294f07d5922a3cf Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 9 Jun 2018 00:53:19 +0200 Subject: [PATCH] prepare new-idle --- MessengerProj/jni/mrwrapper.c | 41 ++---- .../com/b44t/messenger/ApplicationLoader.java | 118 ++++++------------ .../Components/ForegroundDetector.java | 6 +- .../java/com/b44t/messenger/MrMailbox.java | 8 +- .../com/b44t/messenger/ScreenReceiver.java | 2 +- .../messenger/SettingsAccountFragment.java | 2 +- .../com/b44t/messenger/TimerReceiver.java | 47 +++---- .../com/b44t/messenger/WelcomeActivity.java | 3 +- 8 files changed, 74 insertions(+), 153 deletions(-) diff --git a/MessengerProj/jni/mrwrapper.c b/MessengerProj/jni/mrwrapper.c index 2a8ff3cfa..0069e4661 100644 --- a/MessengerProj/jni/mrwrapper.c +++ b/MessengerProj/jni/mrwrapper.c @@ -90,31 +90,6 @@ static void s_init_globals(JNIEnv *env, jclass MrMailbox_class) } -/* setup threads, only called directly by the backed */ - -int mrosnative_setup_thread(mrmailbox_t* mailbox) -{ - if( s_jvm == NULL ) { - mrmailbox_log_error(mailbox, 0, "Not ready, cannot setup thread."); - return 0; - } - - mrmailbox_log_info(mailbox, 0, "Attaching C-thread to Java VM..."); - JNIEnv* env = NULL; - (*s_jvm)->AttachCurrentThread(s_jvm, &env, NULL); - mrmailbox_log_info(mailbox, 0, "Attaching ok."); - return 1; -} - - -void mrosnative_unsetup_thread(mrmailbox_t* mailbox) -{ - mrmailbox_log_info(mailbox, 0, "Detaching C-thread from Java VM..."); - (*s_jvm)->DetachCurrentThread(s_jvm); - mrmailbox_log_info(mailbox, 0, "DeltaChat", "Detaching done."); -} - - /* tools */ static jintArray mrarray2jintArray_n_mrarray_unref(JNIEnv *env, mrarray_t* ca) @@ -278,27 +253,27 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_isConfigured(JNIEnv *env, jclas } -JNIEXPORT jboolean Java_com_b44t_messenger_MrMailbox_idle(JNIEnv *env, jclass cls) +JNIEXPORT void Java_com_b44t_messenger_MrMailbox_performJobs(JNIEnv *env, jclass cls) { - return (jboolean)mrmailbox_idle(get_mrmailbox_t(env, cls)); + mrmailbox_perform_jobs(get_mrmailbox_t(env, cls)); } -JNIEXPORT jboolean Java_com_b44t_messenger_MrMailbox_isIdle(JNIEnv *env, jclass cls) +JNIEXPORT void Java_com_b44t_messenger_MrMailbox_performIdle(JNIEnv *env, jclass cls) { - return (jboolean)mrmailbox_is_idle(get_mrmailbox_t(env, cls)); + mrmailbox_perform_idle(get_mrmailbox_t(env, cls)); } -JNIEXPORT jboolean Java_com_b44t_messenger_MrMailbox_interruptIdle(JNIEnv *env, jclass cls) +JNIEXPORT void Java_com_b44t_messenger_MrMailbox_interruptIdle(JNIEnv *env, jclass cls) { - return (jboolean)mrmailbox_interrupt_idle(get_mrmailbox_t(env, cls)); + mrmailbox_interrupt_idle(get_mrmailbox_t(env, cls)); } -JNIEXPORT jboolean Java_com_b44t_messenger_MrMailbox_poll(JNIEnv *env, jclass cls) +JNIEXPORT void Java_com_b44t_messenger_MrMailbox_performPoll(JNIEnv *env, jclass cls) { - return (jboolean)mrmailbox_poll(get_mrmailbox_t(env, cls)); + mrmailbox_perform_poll(get_mrmailbox_t(env, cls)); } diff --git a/MessengerProj/src/main/java/com/b44t/messenger/ApplicationLoader.java b/MessengerProj/src/main/java/com/b44t/messenger/ApplicationLoader.java index d4e05e821..deaddbbb5 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/ApplicationLoader.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/ApplicationLoader.java @@ -147,8 +147,8 @@ public class ApplicationLoader extends Application { try { PowerManager pm = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE); - s_idleWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "idleWakeLock"); - s_idleWakeLock.setReferenceCounted(false); // if the idle-thread is killed for any reasons, it is better not to rely on reference counting + imapWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "idleWakeLock"); + imapWakeLock.setReferenceCounted(false); // if the idle-thread is killed for any reasons, it is better not to rely on reference counting wakeupWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wakeupWakeLock" /*any name*/); wakeupWakeLock.setReferenceCounted(false); @@ -217,7 +217,8 @@ public class ApplicationLoader extends Application { File dbfile = new File(getFilesDirFixed(), "messenger.db"); MrMailbox.open(dbfile.getAbsolutePath()); if( MrMailbox.isConfigured()!=0 && ApplicationLoader.getPermanentPush() ) { - ApplicationLoader.startIdleThread(); + ApplicationLoader.imapForeground = true; + ApplicationLoader.startImapThread(); } // create other default objects @@ -288,103 +289,64 @@ public class ApplicationLoader extends Application { if( permanentPush ) { applicationContext.startService(new Intent(applicationContext, KeepAliveService.class)); - stopIdleThreadPhysically(); - startIdleThread(); // restart the idleThread to ensure we set a wake lock } else { applicationContext.stopService(new Intent(applicationContext, KeepAliveService.class)); } } - private static final Object s_idleThreadCritical = new Object(); - private static Thread s_idleThread = null; - private static PowerManager.WakeLock s_idleWakeLock = null; - private static boolean s_switchFromIdleToPoll = false; + private static final Object imapThreadCritical = new Object(); + public static Thread imapThread = null; + private static PowerManager.WakeLock imapWakeLock = null; + public static boolean imapForeground = false; + public static boolean imapSwitchToBackground = false; - public static void startIdleThread() + public static void startImapThread() { - synchronized (s_idleThreadCritical) { - s_switchFromIdleToPoll = false; + imapSwitchToBackground = false; - if (s_idleThread != null && s_idleThread.isAlive() && MrMailbox.isIdle()) { - Log.i("DeltaChat", "Idle thread already started."); + synchronized(imapThreadCritical) { + + if( imapThread != null && imapThread.isAlive() ) { + Log.i("DeltaChat", "*** IMAP-Thread is already active, doing nothing."); return; } - if( s_idleThread != null ) { - try { - MrMailbox.interruptIdle(); - s_idleThread.join(1000); - s_idleThread.interrupt(); - } catch (Exception e) { - e.printStackTrace(); - } - s_idleThread = null; - } - - s_idleThread = new Thread(new Runnable() { + imapThread = new Thread(new Runnable() { @Override public void run() { - boolean permanentPush = getPermanentPush(); - if( permanentPush ) { - s_idleWakeLock.acquire(); + + Log.i("DeltaChat", "*** IMAP-Thread started."); + + + while( true ) { + imapWakeLock.acquire(); + MrMailbox.performJobs(); + imapWakeLock.release(); + + if( imapForeground ) { + MrMailbox.performIdle(); + } + else { + imapWakeLock.acquire(); + MrMailbox.performPoll(); + imapWakeLock.release(); + break; + } } - try { - MrMailbox.idle(); // this may run hours ... - } catch (Exception e) { - e.printStackTrace(); - } - if( permanentPush ) { - s_idleWakeLock.release(); - } + Log.i("DeltaChat", "*** IMAP-Thread stopped."); } - }, "idleThread"); - s_idleThread.start(); + }, "imapThread"); + imapThread.start(); } } - public static void scheduleStopIdleThread() + public static void scheduleStopImapThread() { - synchronized (s_idleThreadCritical) { - if (MrMailbox.isIdle()) { - s_switchFromIdleToPoll = true; - Log.i("DeltaChat", "Will switch from idle to poll on next timer event."); - } - } - } + Log.i("DeltaChat", "*** IMAP-thread scheduled to stop."); - public static void stopIdleThreadPhysically() - { - synchronized (s_idleThreadCritical) { - s_switchFromIdleToPoll = false; - - if( s_idleThread==null) { - Log.i("DeltaChat", "No idle thread to stop."); - return; - } - - try { - MrMailbox.interruptIdle(); - s_idleThread.join(1000); - s_idleThread.interrupt(); - } catch (Exception e) { - e.printStackTrace(); - } - s_idleThread = null; - } - } - - public static boolean getAndResetSwitchFromIdleToPoll() - { - boolean doSwitch = false; - synchronized (s_idleThreadCritical) { - if (s_switchFromIdleToPoll && MrMailbox.isIdle()) { - doSwitch = true; - } - s_switchFromIdleToPoll = false; - } - return doSwitch; + imapSwitchToBackground = true; } } diff --git a/MessengerProj/src/main/java/com/b44t/messenger/Components/ForegroundDetector.java b/MessengerProj/src/main/java/com/b44t/messenger/Components/ForegroundDetector.java index d02fdb5cf..695a82ee6 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/Components/ForegroundDetector.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/Components/ForegroundDetector.java @@ -69,7 +69,9 @@ public class ForegroundDetector implements Application.ActivityLifecycleCallback } } - ApplicationLoader.startIdleThread(); // 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) + ApplicationLoader.imapSwitchToBackground = false; + ApplicationLoader.imapForeground = true; + ApplicationLoader.startImapThread(); // 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) } public boolean isWasInBackground(boolean reset) { @@ -98,7 +100,7 @@ public class ForegroundDetector implements Application.ActivityLifecycleCallback wasInBackground = true; if( !ApplicationLoader.getPermanentPush() ) { - ApplicationLoader.scheduleStopIdleThread();; + ApplicationLoader.scheduleStopImapThread();; } } else { diff --git a/MessengerProj/src/main/java/com/b44t/messenger/MrMailbox.java b/MessengerProj/src/main/java/com/b44t/messenger/MrMailbox.java index 4c9fb83b2..6e7a01c19 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/MrMailbox.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/MrMailbox.java @@ -56,10 +56,10 @@ public class MrMailbox { public native static int isConfigured(); - public native static boolean idle(); - public native static boolean isIdle(); - public native static boolean interruptIdle(); - public native static boolean poll(); + public native static void performJobs(); + public native static void performIdle(); + public native static void interruptIdle(); + public native static void performPoll(); public native static void setConfig(String key, String value); public native static void setConfigInt(String key, int value); diff --git a/MessengerProj/src/main/java/com/b44t/messenger/ScreenReceiver.java b/MessengerProj/src/main/java/com/b44t/messenger/ScreenReceiver.java index 6d9003be3..b5778c772 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/ScreenReceiver.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/ScreenReceiver.java @@ -38,7 +38,7 @@ public class ScreenReceiver extends BroadcastReceiver { // also stop the idle-thread when the screen goes off, this is not always in sync with the ForegroundDetector if( !ApplicationLoader.getPermanentPush() ) { - ApplicationLoader.scheduleStopIdleThread(); + ApplicationLoader.scheduleStopImapThread(); } } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { MrMailbox.log_i("DeltaChat", "*** Screen on"); diff --git a/MessengerProj/src/main/java/com/b44t/messenger/SettingsAccountFragment.java b/MessengerProj/src/main/java/com/b44t/messenger/SettingsAccountFragment.java index 833e9dac1..d26dcf123 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/SettingsAccountFragment.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/SettingsAccountFragment.java @@ -360,7 +360,7 @@ public class SettingsAccountFragment extends BaseFragment implements Notificatio public void run() { final int res = MrMailbox.configure(); if( res != 0 ) { - ApplicationLoader.startIdleThread(); + ApplicationLoader.startImapThread(); } AndroidUtilities.runOnUIThread(new Runnable() { @Override diff --git a/MessengerProj/src/main/java/com/b44t/messenger/TimerReceiver.java b/MessengerProj/src/main/java/com/b44t/messenger/TimerReceiver.java index fc1523bcc..14e309791 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/TimerReceiver.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/TimerReceiver.java @@ -31,46 +31,27 @@ import android.content.Intent; import android.os.Build; import android.util.Log; +import com.coremedia.iso.boxes.apple.AppleItemListBox; + public class TimerReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { - // for a discussion about the different approaches to save batter, see https://github.com/deltachat/deltachat-android/issues/104#issuecomment-331670326 + if( ApplicationLoader.imapSwitchToBackground ) { - try { - ApplicationLoader.wakeupWakeLock.acquire(); // do this first! - MrMailbox.log_i("DeltaChat", "*** TimerReceiver.onReceive()"); + Log.i("DeltaChat", "IMAP-Thread set to background mode."); - // we assume, the IMAP thread is alive. I cannot imagine, the thread was killed with the App being running. - // (if the whole App was killed, the IMAP thread is already started by MrMailbox.connect() if we're here) - // (the thread itself will reconnect to the IMAP server as needed) - // however, it seems as if the threads sleep longer than ususal, check this by calling heartbeat() manually - // - // CAVE: MrMailbox.heartbeat() must not be called from the mainthread - otherwise eg. when the network hangs, - // this function returns only after the network timeout and the ui thread may hang for minutes ... - new Thread(new Runnable() { - @Override - public void run() { - if( ApplicationLoader.getPermanentPush() ) { - MrMailbox.heartbeat(); - } - else { - if( ApplicationLoader.getAndResetSwitchFromIdleToPoll() ) { - ApplicationLoader.stopIdleThreadPhysically(); - } - else { - MrMailbox.poll(); - } - } - } - }).start(); - - // create the next alarm in about a minute - scheduleNextAlarm(); - } finally { - // Always release the wakelock, _if_ there is more to do, the backend acquires an additional wakelock using MR_EVENT_WAKE_LOCK - ApplicationLoader.wakeupWakeLock.release(); + ApplicationLoader.imapForeground = false; + MrMailbox.interruptIdle(); } + else { + Log.i("DeltaChat", "IMAP-Thread starting from timer."); + + ApplicationLoader.startImapThread(); // do not change imapForeground before; may or may not be in foreground + } + + + scheduleNextAlarm(); } public static void scheduleNextAlarm() diff --git a/MessengerProj/src/main/java/com/b44t/messenger/WelcomeActivity.java b/MessengerProj/src/main/java/com/b44t/messenger/WelcomeActivity.java index 0c6c21caa..28eac9795 100644 --- a/MessengerProj/src/main/java/com/b44t/messenger/WelcomeActivity.java +++ b/MessengerProj/src/main/java/com/b44t/messenger/WelcomeActivity.java @@ -382,7 +382,8 @@ public class WelcomeActivity extends Activity implements NotificationCenter.Noti } if( (int)args[0]==1 ) { - ApplicationLoader.startIdleThread(); // import does not automatically connect + ApplicationLoader.imapForeground = true; + ApplicationLoader.startImapThread(); // import does not automatically connect KeepAliveService kas = KeepAliveService.getInstance(); if( kas != null ) { kas.updateForegroundNotification();