mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
prepare new-idle
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user