mirror of
https://github.com/M66B/FairEmail.git
synced 2026-04-01 14:46:31 +02:00
Replaced foreground operations by oneshot mode
This commit is contained in:
@@ -41,9 +41,6 @@ import com.sun.mail.imap.IMAPFolder;
|
||||
import com.sun.mail.imap.IMAPMessage;
|
||||
import com.sun.mail.imap.IMAPStore;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -100,9 +97,11 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
private static final long RECONNECT_BACKOFF = 90 * 1000L; // milliseconds
|
||||
private static final int ACCOUNT_ERROR_AFTER = 90; // minutes
|
||||
private static final int BACKOFF_ERROR_AFTER = 16; // seconds
|
||||
private static final long ONESHOT_DURATION = 60 * 1000L; // milliseconds
|
||||
private static final long STOP_DELAY = 5000L; // milliseconds
|
||||
|
||||
static final int PI_ALARM = 1;
|
||||
static final int PI_ONESHOT = 2;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@@ -184,6 +183,14 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
serviceManager.service_reload(intent.getStringExtra("reason"));
|
||||
break;
|
||||
|
||||
case "oneshot_start":
|
||||
serviceManager.service_oneshot(true);
|
||||
break;
|
||||
|
||||
case "oneshot_end":
|
||||
serviceManager.service_oneshot(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.w("Unknown action: " + action);
|
||||
}
|
||||
@@ -924,7 +931,9 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
|
||||
private boolean isEnabled() {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceSynchronize.this);
|
||||
return prefs.getBoolean("enabled", true);
|
||||
boolean enabled = prefs.getBoolean("enabled", true);
|
||||
boolean oneshot = prefs.getBoolean("oneshot", false);
|
||||
return (enabled || oneshot);
|
||||
}
|
||||
|
||||
private void service_init() {
|
||||
@@ -947,6 +956,32 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
}
|
||||
}
|
||||
|
||||
private void service_oneshot(boolean start) {
|
||||
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
|
||||
Intent alarm = new Intent(ServiceSynchronize.this, ServiceSynchronize.class);
|
||||
alarm.setAction("oneshot_end");
|
||||
PendingIntent piOneshot;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
||||
piOneshot = PendingIntent.getService(ServiceSynchronize.this, PI_ONESHOT, alarm, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
else
|
||||
piOneshot = PendingIntent.getForegroundService(ServiceSynchronize.this, PI_ONESHOT, alarm, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
am.cancel(piOneshot);
|
||||
|
||||
if (start) {
|
||||
// Network events will manage the service
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
|
||||
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ONESHOT_DURATION, piOneshot);
|
||||
else
|
||||
am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ONESHOT_DURATION, piOneshot);
|
||||
} else {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceSynchronize.this);
|
||||
prefs.edit().putBoolean("oneshot", false).apply();
|
||||
queue_reload(false, "oneshot");
|
||||
}
|
||||
}
|
||||
|
||||
private void service_destroy() {
|
||||
synchronized (this) {
|
||||
EntityLog.log(ServiceSynchronize.this, "Service destroy");
|
||||
@@ -1105,21 +1140,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
Thread.sleep(STOP_DELAY);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
if (queued == 0 && !isEnabled()) {
|
||||
EntityLog.log(ServiceSynchronize.this, "Service stop");
|
||||
List<EntityOperation> ops = db.operation().getOperations(EntityOperation.SYNC);
|
||||
for (EntityOperation op : ops)
|
||||
try {
|
||||
JSONArray jargs = new JSONArray(op.args);
|
||||
if (!jargs.getBoolean(3) /* foreground */) {
|
||||
Log.i("Deleting bacground SYNC args=" + jargs);
|
||||
db.operation().deleteOperation(op.id);
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
stopSelf();
|
||||
}
|
||||
if (queued == 0 && !isEnabled())
|
||||
stopService();
|
||||
}
|
||||
|
||||
wl.release();
|
||||
@@ -1127,12 +1149,27 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stopService() {
|
||||
EntityLog.log(ServiceSynchronize.this, "Service stop");
|
||||
|
||||
DB db = DB.getInstance(ServiceSynchronize.this);
|
||||
List<EntityOperation> ops = db.operation().getOperations(EntityOperation.SYNC);
|
||||
for (EntityOperation op : ops)
|
||||
db.folder().setFolderSyncState(op.folder, null);
|
||||
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
private static void schedule(Context context) {
|
||||
Intent alarm = new Intent(context, ServiceSynchronize.class);
|
||||
alarm.setAction("alarm");
|
||||
PendingIntent piAlarm = PendingIntent.getService(context, PI_ALARM, alarm, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent piAlarm;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
||||
piAlarm = PendingIntent.getService(context, PI_ALARM, alarm, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
else
|
||||
piAlarm = PendingIntent.getForegroundService(context, PI_ALARM, alarm, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
am.cancel(piAlarm);
|
||||
@@ -1193,6 +1230,18 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
try {
|
||||
DB db = DB.getInstance(context);
|
||||
|
||||
// Reset state
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs.edit().remove("oneshot").apply();
|
||||
|
||||
for (EntityAccount account : db.account().getAccounts())
|
||||
db.account().setAccountState(account.id, null);
|
||||
|
||||
for (EntityFolder folder : db.folder().getFolders()) {
|
||||
db.folder().setFolderState(folder.id, null);
|
||||
db.folder().setFolderSyncState(folder.id, null);
|
||||
}
|
||||
|
||||
// Restore snooze timers
|
||||
for (EntityMessage message : db.message().getSnoozed())
|
||||
EntityMessage.snooze(context, message.id, message.ui_snoozed);
|
||||
@@ -1201,11 +1250,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
schedule(context);
|
||||
|
||||
// Conditionally init service
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean enabled = prefs.getBoolean("enabled", true);
|
||||
|
||||
int accounts = db.account().getSynchronizingAccounts().size();
|
||||
|
||||
if (enabled && accounts > 0)
|
||||
ContextCompat.startForegroundService(context,
|
||||
new Intent(context, ServiceSynchronize.class)
|
||||
@@ -1231,4 +1277,16 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
.setAction("reload")
|
||||
.putExtra("reason", reason));
|
||||
}
|
||||
|
||||
static void process(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean enabled = prefs.getBoolean("enabled", true);
|
||||
boolean oneshot = prefs.getBoolean("oneshot", false);
|
||||
if (!enabled && !oneshot) {
|
||||
prefs.edit().putBoolean("oneshot", true).apply();
|
||||
ContextCompat.startForegroundService(context,
|
||||
new Intent(context, ServiceSynchronize.class)
|
||||
.setAction("oneshot_start"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user