Individual account management - to be tested

pull/169/head
M66B 6 years ago
parent 35602ef17c
commit 2591dc9011

@ -33,8 +33,6 @@ import androidx.preference.PreferenceManager;
import java.util.List; import java.util.List;
public class ActivityMain extends ActivityBase implements FragmentManager.OnBackStackChangedListener, SharedPreferences.OnSharedPreferenceChangeListener { public class ActivityMain extends ActivityBase implements FragmentManager.OnBackStackChangedListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final String ACTION_REFRESH = BuildConfig.APPLICATION_ID + ".REFRESH";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
getSupportFragmentManager().addOnBackStackChangedListener(this); getSupportFragmentManager().addOnBackStackChangedListener(this);
@ -87,8 +85,6 @@ public class ActivityMain extends ActivityBase implements FragmentManager.OnBack
Intent view = new Intent(ActivityMain.this, ActivityView.class); Intent view = new Intent(ActivityMain.this, ActivityView.class);
view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (ACTION_REFRESH.equals(getIntent().getAction()))
view.putExtra("refresh", true);
Intent saved = args.getParcelable("intent"); Intent saved = args.getParcelable("intent");
if (saved == null) if (saved == null)
@ -101,7 +97,7 @@ public class ActivityMain extends ActivityBase implements FragmentManager.OnBack
startActivity(view); startActivity(view);
} }
ServiceSynchronize.watchdog(ActivityMain.this); ServiceSynchronize.eval(ActivityMain.this, false, "main");
ServiceSend.watchdog(ActivityMain.this); ServiceSend.watchdog(ActivityMain.this);
} else } else
startActivity(new Intent(ActivityMain.this, ActivitySetup.class)); startActivity(new Intent(ActivityMain.this, ActivitySetup.class));

@ -374,7 +374,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
handleImport(data, this.password); handleImport(data, this.password);
break; break;
case REQUEST_IMPORT_OAUTH: case REQUEST_IMPORT_OAUTH:
ServiceSynchronize.reload(this, "oauth"); ServiceSynchronize.eval(this, false, "import/oauth");
break; break;
case REQUEST_IMPORT_CERTIFICATE: case REQUEST_IMPORT_CERTIFICATE:
if (resultCode == RESULT_OK && data != null) if (resultCode == RESULT_OK && data != null)
@ -983,7 +983,6 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
} }
Log.i("Imported data"); Log.i("Imported data");
ServiceSynchronize.reload(context, "import");
return oauth; return oauth;
} }
@ -1005,7 +1004,8 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
requestPermissions(permissions.toArray(new String[0]), REQUEST_IMPORT_OAUTH); requestPermissions(permissions.toArray(new String[0]), REQUEST_IMPORT_OAUTH);
break; break;
} }
} } else
ServiceSynchronize.eval(ActivitySetup.this, false, "import");
} }
@Override @Override

@ -770,10 +770,11 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
private void checkIntent() { private void checkIntent() {
Intent intent = getIntent(); Intent intent = getIntent();
// Refresh from widget
if (intent.getBooleanExtra("refresh", false)) { if (intent.getBooleanExtra("refresh", false)) {
intent.removeExtra("refresh"); intent.removeExtra("refresh");
setIntent(intent); setIntent(intent);
ServiceSynchronize.process(this, true); // TODO: sync all
} }
String action = intent.getAction(); String action = intent.getAction();

@ -272,7 +272,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
@Override @Override
protected void onExecuted(Bundle args, Boolean sync) { protected void onExecuted(Bundle args, Boolean sync) {
ServiceSynchronize.reload(context, "account set sync=" + sync); ServiceSynchronize.eval(context, false, "account sync=" + sync);
} }
@Override @Override

@ -547,9 +547,9 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
args.putInt("property", property); args.putInt("property", property);
args.putBoolean("enabled", enabled); args.putBoolean("enabled", enabled);
new SimpleTask<Boolean>() { new SimpleTask<Void>() {
@Override @Override
protected Boolean onExecute(Context context, Bundle args) { protected Void onExecute(Context context, Bundle args) {
long id = args.getLong("id"); long id = args.getLong("id");
int property = args.getInt("property"); int property = args.getInt("property");
boolean enabled = args.getBoolean("enabled"); boolean enabled = args.getBoolean("enabled");
@ -558,25 +558,22 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
switch (property) { switch (property) {
case R.string.title_unified_folder: case R.string.title_unified_folder:
db.folder().setFolderUnified(id, enabled); db.folder().setFolderUnified(id, enabled);
return false; break;
case R.string.title_navigation_folder: case R.string.title_navigation_folder:
db.folder().setFolderNavigation(id, enabled); db.folder().setFolderNavigation(id, enabled);
return false; break;
case R.string.title_notify_folder: case R.string.title_notify_folder:
db.folder().setFolderNotify(id, enabled); db.folder().setFolderNotify(id, enabled);
return false; break;
case R.string.title_synchronize_enabled: case R.string.title_synchronize_enabled:
db.folder().setFolderSynchronize(id, enabled); db.folder().setFolderSynchronize(id, enabled);
return true; ServiceSynchronize.eval(context, true, "folder sync=" + enabled);
break;
default: default:
return false; throw new IllegalArgumentException("Unknown folder property=" + property);
} }
}
@Override return null;
protected void onExecuted(Bundle args, Boolean reload) {
if (reload)
ServiceSynchronize.reload(context, "folder property changed");
} }
@Override @Override

@ -105,7 +105,6 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
} }
private void bindTo(TupleIdentityEx identity) { private void bindTo(TupleIdentityEx identity) {
view.setActivated(identity.tbd != null);
vwColor.setBackgroundColor(identity.color == null ? Color.TRANSPARENT : identity.color); vwColor.setBackgroundColor(identity.color == null ? Color.TRANSPARENT : identity.color);
vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.INVISIBLE); vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.INVISIBLE);
@ -152,8 +151,6 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
return; return;
TupleIdentityEx identity = items.get(pos); TupleIdentityEx identity = items.get(pos);
if (identity.tbd != null)
return;
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
lbm.sendBroadcast( lbm.sendBroadcast(
@ -168,8 +165,6 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
return false; return false;
final TupleIdentityEx identity = items.get(pos); final TupleIdentityEx identity = items.get(pos);
if (identity.tbd != null)
return false;
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, view); PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, view);

@ -3214,14 +3214,13 @@ class Core {
private Semaphore semaphore = new Semaphore(0); private Semaphore semaphore = new Semaphore(0);
private boolean running = true; private boolean running = true;
private boolean recoverable = true; private boolean recoverable = true;
List<State> childs = Collections.synchronizedList(new ArrayList<>());
State(ConnectionHelper.NetworkState networkState) { State(ConnectionHelper.NetworkState networkState) {
this.networkState = networkState; this.networkState = networkState;
} }
State(State parent) { void setNetworkState(ConnectionHelper.NetworkState networkState) {
this(parent.networkState); this.networkState = networkState;
} }
ConnectionHelper.NetworkState getNetworkState() { ConnectionHelper.NetworkState getNetworkState() {

@ -94,16 +94,6 @@ public interface DaoAccount {
@Query("SELECT * FROM account WHERE id = :id") @Query("SELECT * FROM account WHERE id = :id")
LiveData<EntityAccount> liveAccount(long id); LiveData<EntityAccount> liveAccount(long id);
@Query("SELECT" +
" (SELECT COUNT(account.id) FROM account" +
" WHERE synchronize" +
" AND state = 'connected') AS accounts" +
", (SELECT COUNT(operation.id) FROM operation" +
" JOIN folder ON folder.id = operation.folder" +
" JOIN account ON account.id = folder.account" + // not outbox
" WHERE account.synchronize) AS operations")
LiveData<TupleAccountStats> liveStats();
@Query("SELECT account.id" + @Query("SELECT account.id" +
", account.swipe_left, l.type AS left_type, l.name AS left_name" + ", account.swipe_left, l.type AS left_type, l.name AS left_name" +
", account.swipe_right, r.type AS right_type, r.name AS right_name" + ", account.swipe_right, r.type AS right_type, r.name AS right_name" +
@ -152,7 +142,7 @@ public interface DaoAccount {
@Query("UPDATE account SET last_connected = NULL") @Query("UPDATE account SET last_connected = NULL")
int clearAccountConnected(); int clearAccountConnected();
@Query("DELETE FROM account WHERE tbd = 1") @Query("DELETE FROM account WHERE id = :id")
int deleteAccountsTbd(); int deleteAccount(long id);
} }

@ -154,6 +154,11 @@ public interface DaoFolder {
" AND type <> '" + EntityFolder.USER + "'") " AND type <> '" + EntityFolder.USER + "'")
List<EntityFolder> getSystemFolders(long account); List<EntityFolder> getSystemFolders(long account);
@Query("SELECT * FROM folder" +
" WHERE folder.account = :account" +
" AND folder.synchronize")
List<EntityFolder> getSynchronizingFolders(long account);
@Query("SELECT folder.type" + @Query("SELECT folder.type" +
", COUNT(message.id) AS messages" + ", COUNT(message.id) AS messages" +
", SUM(CASE WHEN NOT message.ui_seen THEN 1 ELSE 0 END) AS unseen" + ", SUM(CASE WHEN NOT message.ui_seen THEN 1 ELSE 0 END) AS unseen" +

@ -103,9 +103,6 @@ public interface DaoIdentity {
@Query("UPDATE identity SET `primary` = 0 WHERE account = :account") @Query("UPDATE identity SET `primary` = 0 WHERE account = :account")
void resetPrimary(long account); void resetPrimary(long account);
@Query("UPDATE identity SET tbd = 1 WHERE id = :id") @Query("DELETE FROM identity WHERE id = :id")
int setIdentityTbd(long id); int deleteIdentity(long id);
@Query("DELETE FROM identity WHERE tbd = 1")
int deleteIdentitiesTbd();
} }

@ -71,7 +71,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
@NonNull @NonNull
public Integer port; public Integer port;
@NonNull @NonNull
public Integer auth_type; public Integer auth_type; // immutable
@NonNull @NonNull
public String user; public String user;
@NonNull @NonNull

@ -101,7 +101,7 @@ public class EntityIdentity {
public Long sent_folder = null; // obsolete public Long sent_folder = null; // obsolete
public Long sign_key = null; // OpenPGP public Long sign_key = null; // OpenPGP
public String sign_key_alias = null; // S/MIME public String sign_key_alias = null; // S/MIME
public Boolean tbd; public Boolean tbd; // obsolete
public String state; public String state;
public String error; public String error;
public Long last_connected; public Long last_connected;
@ -258,7 +258,6 @@ public class EntityIdentity {
Objects.equals(this.replyto, other.replyto) && Objects.equals(this.replyto, other.replyto) &&
Objects.equals(this.bcc, other.bcc) && Objects.equals(this.bcc, other.bcc) &&
Objects.equals(this.sign_key, other.sign_key) && Objects.equals(this.sign_key, other.sign_key) &&
Objects.equals(this.tbd, other.tbd) &&
Objects.equals(this.state, other.state) && Objects.equals(this.state, other.state) &&
Objects.equals(this.error, other.error) && Objects.equals(this.error, other.error) &&
Objects.equals(this.last_connected, other.last_connected)); Objects.equals(this.last_connected, other.last_connected));

@ -320,7 +320,7 @@ public class EntityOperation {
if (SEND.equals(name)) if (SEND.equals(name))
ServiceSend.start(context); ServiceSend.start(context);
else else
ServiceSynchronize.process(context, false); ServiceSynchronize.eval(context, false, "operation=" + name);
} }
static void queue(Context context, EntityFolder folder, String name, Object... values) { static void queue(Context context, EntityFolder folder, String name, Object... values) {
@ -360,6 +360,7 @@ public class EntityOperation {
if (folder == null) if (folder == null)
return; return;
// TODO: replace sync parameters?
if (db.operation().getOperationCount(fid, EntityOperation.SYNC) == 0) { if (db.operation().getOperationCount(fid, EntityOperation.SYNC) == 0) {
EntityOperation operation = new EntityOperation(); EntityOperation operation = new EntityOperation();
operation.account = folder.account; operation.account = folder.account;
@ -379,7 +380,7 @@ public class EntityOperation {
if (folder.account == null) // Outbox if (folder.account == null) // Outbox
ServiceSend.start(context); ServiceSend.start(context);
else if (foreground) else if (foreground)
ServiceSynchronize.process(context, true); ServiceSynchronize.eval(context, false, "sync folder=" + fid);
} }
static void subscribe(Context context, long fid, boolean subscribe) { static void subscribe(Context context, long fid, boolean subscribe) {

@ -890,19 +890,16 @@ public class FragmentAccount extends FragmentBase {
String accountRealm = (account == null ? null : account.realm); String accountRealm = (account == null ? null : account.realm);
boolean check = (synchronize && (account == null || boolean check = (synchronize && (account == null ||
!account.synchronize || account.error != null || !account.synchronize ||
account.error != null ||
!account.host.equals(host) ||
!account.starttls.equals(starttls) ||
!account.insecure.equals(insecure) || !account.insecure.equals(insecure) ||
!host.equals(account.host) || starttls != account.starttls || Integer.parseInt(port) != account.port || !account.port.equals(Integer.parseInt(port)) ||
!user.equals(account.user) || !password.equals(account.password) || !account.user.equals(user) ||
!account.password.equals(password) ||
!Objects.equals(realm, accountRealm))); !Objects.equals(realm, accountRealm)));
boolean reload = (check || account == null || Log.i("Account check=" + check);
account.synchronize != synchronize ||
account.notify != notify ||
!account.poll_interval.equals(Integer.parseInt(interval)) ||
account.partial_fetch != partial_fetch ||
account.ignore_size != ignore_size ||
account.use_date != use_date);
Log.i("Account check=" + check + " reload=" + reload);
Long last_connected = null; Long last_connected = null;
if (account != null && synchronize == account.synchronize) if (account != null && synchronize == account.synchronize)
@ -1093,8 +1090,7 @@ public class FragmentAccount extends FragmentBase {
db.endTransaction(); db.endTransaction();
} }
if (reload) ServiceSynchronize.eval(context, false, "save account");
ServiceSynchronize.reload(context, "save account");
if (!synchronize) { if (!synchronize) {
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -1420,7 +1416,7 @@ public class FragmentAccount extends FragmentBase {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
db.account().setAccountTbd(id); db.account().setAccountTbd(id);
ServiceSynchronize.reload(context, "delete account"); ServiceSynchronize.eval(context, false, "delete account");
return null; return null;
} }

@ -486,7 +486,6 @@ public class FragmentFolder extends FragmentBase {
} }
reload = (!folder.name.equals(name) || reload = (!folder.name.equals(name) ||
!folder.synchronize.equals(synchronize) ||
!folder.poll.equals(poll)); !folder.poll.equals(poll));
Log.i("Updating folder=" + folder.name); Log.i("Updating folder=" + folder.name);
@ -506,8 +505,7 @@ public class FragmentFolder extends FragmentBase {
db.endTransaction(); db.endTransaction();
} }
if (reload) ServiceSynchronize.eval(context, reload, "save folder");
ServiceSynchronize.reload(context, "save folder");
return false; return false;
} }
@ -556,7 +554,7 @@ public class FragmentFolder extends FragmentBase {
R.plurals.title_notification_operations, count, count)); R.plurals.title_notification_operations, count, count));
db.folder().setFolderTbd(id); db.folder().setFolderTbd(id);
ServiceSynchronize.reload(context, "delete folder"); ServiceSynchronize.eval(context, true, "delete folder");
return null; return null;
} }

@ -57,6 +57,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import java.util.Collections;
import java.util.List; import java.util.List;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
@ -343,9 +344,14 @@ public class FragmentFolders extends FragmentBase {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean enabled = prefs.getBoolean("enabled", true); boolean enabled = prefs.getBoolean("enabled", true);
if (enabled) if (enabled)
ServiceSynchronize.reload(context, "refresh folders"); ServiceSynchronize.eval(context, true, "refresh folders");
else else {
ServiceSynchronize.process(context, true); List<EntityFolder> folders = db.folder().getSynchronizingFolders(aid);
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(context));
for (EntityFolder folder : folders)
EntityOperation.sync(context, folder.id, false);
}
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();

@ -383,7 +383,7 @@ public class FragmentGmail extends FragmentBase {
db.endTransaction(); db.endTransaction();
} }
ServiceSynchronize.reload(context, "Gmail"); ServiceSynchronize.eval(context, false, "Gmail");
return null; return null;
} }

@ -1092,9 +1092,7 @@ public class FragmentIdentity extends FragmentBase {
long id = args.getLong("id"); long id = args.getLong("id");
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
db.identity().setIdentityTbd(id); db.identity().deleteIdentity(id);
ServiceSynchronize.reload(context, "delete identity");
return null; return null;
} }

@ -99,7 +99,6 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("metered", checked).apply(); prefs.edit().putBoolean("metered", checked).apply();
ServiceSynchronize.reload(getContext(), "metered=" + checked);
} }
}); });
@ -120,7 +119,6 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("roaming", checked).apply(); prefs.edit().putBoolean("roaming", checked).apply();
ServiceSynchronize.reload(getContext(), "roaming=" + checked);
} }
}); });
@ -128,7 +126,6 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("rlah", checked).apply(); prefs.edit().putBoolean("rlah", checked).apply();
ServiceSynchronize.reload(getContext(), "rlah=" + checked);
} }
}); });
@ -138,7 +135,6 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
prefs.edit().putBoolean("socks_enabled", checked).apply(); prefs.edit().putBoolean("socks_enabled", checked).apply();
etSocks.setEnabled(checked); etSocks.setEnabled(checked);
btnSocks.setEnabled(checked); btnSocks.setEnabled(checked);
ServiceSynchronize.reload(getContext(), "socks=" + checked);
} }
}); });
@ -150,7 +146,6 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
prefs.edit().remove("socks_proxy").apply(); prefs.edit().remove("socks_proxy").apply();
else else
prefs.edit().putString("socks_proxy", proxy).apply(); prefs.edit().putString("socks_proxy", proxy).apply();
ServiceSynchronize.reload(getContext(), "socks=" + proxy);
} }
}); });

@ -164,7 +164,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("debug", checked).apply(); prefs.edit().putBoolean("debug", checked).apply();
grpDebug.setVisibility(checked || BuildConfig.DEBUG ? View.VISIBLE : View.GONE); grpDebug.setVisibility(checked || BuildConfig.DEBUG ? View.VISIBLE : View.GONE);
ServiceSynchronize.reload(getContext(), "debug=" + checked);
} }
}); });

@ -177,7 +177,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("badge", checked).apply(); prefs.edit().putBoolean("badge", checked).apply();
ServiceSynchronize.reload(getContext(), "badge"); ServiceSynchronize.restart(getContext(), "badge");
} }
}); });
@ -185,7 +185,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("unseen_ignored", checked).apply(); prefs.edit().putBoolean("unseen_ignored", checked).apply();
ServiceSynchronize.reload(getContext(), "unseen_ignored"); ServiceSynchronize.restart(getContext(), "unseen_ignored");
} }
}); });

@ -106,7 +106,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("enabled", checked).apply(); prefs.edit().putBoolean("enabled", checked).apply();
ServiceSynchronize.reload(getContext(), true, "enabled=" + checked); ServiceSynchronize.eval(getContext(), false, "enabled=" + checked);
} }
}); });
@ -120,16 +120,18 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
if (value != current) { if (value != current) {
adapterView.setTag(value); adapterView.setTag(value);
prefs.edit().putInt("poll_interval", value).apply(); prefs.edit().putInt("poll_interval", value).apply();
if (value == 0)
ServiceSynchronize.eval(getContext(), false, "poll_interval");
WorkerPoll.init(getContext()); WorkerPoll.init(getContext());
ServiceSynchronize.reload(getContext(), "poll");
} }
} }
@Override @Override
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected(AdapterView<?> adapterView) {
adapterView.setTag(null);
prefs.edit().remove("poll_interval").apply(); prefs.edit().remove("poll_interval").apply();
ServiceSynchronize.eval(getContext(), false, "poll_interval");
WorkerPoll.init(getContext()); WorkerPoll.init(getContext());
ServiceSynchronize.reload(getContext(), "poll");
} }
}); });
@ -170,7 +172,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("sync_unseen", checked).apply(); prefs.edit().putBoolean("sync_unseen", checked).apply();
ServiceSynchronize.reload(getContext(), false, "sync_unseen=" + checked); ServiceSynchronize.eval(getContext(), true, "sync_unseen=" + checked);
} }
}); });
@ -178,7 +180,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("sync_flagged", checked).apply(); prefs.edit().putBoolean("sync_flagged", checked).apply();
ServiceSynchronize.reload(getContext(), false, "sync_flagged=" + checked); ServiceSynchronize.eval(getContext(), true, "sync_flagged=" + checked);
} }
}); });
@ -186,7 +188,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("delete_unseen", checked).apply(); prefs.edit().putBoolean("delete_unseen", checked).apply();
ServiceSynchronize.reload(getContext(), false, "delete_unseen=" + checked); ServiceSynchronize.eval(getContext(), true, "delete_unseen=" + checked);
} }
}); });
@ -194,7 +196,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("sync_kept", checked).apply(); prefs.edit().putBoolean("sync_kept", checked).apply();
ServiceSynchronize.reload(getContext(), false, "sync_kept=" + checked); ServiceSynchronize.eval(getContext(), true, "sync_kept=" + checked);
} }
}); });
@ -202,7 +204,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("sync_folders", checked).apply(); prefs.edit().putBoolean("sync_folders", checked).apply();
ServiceSynchronize.reload(getContext(), false, "sync_folders=" + checked); ServiceSynchronize.eval(getContext(), true, "sync_folders=" + checked);
} }
}); });
@ -219,7 +221,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("subscribed_only", checked).apply(); prefs.edit().putBoolean("subscribed_only", checked).apply();
ServiceSynchronize.reload(getContext(), "subscribed_only"); ServiceSynchronize.eval(getContext(), true, "subscribed_only");
} }
}); });

@ -253,15 +253,15 @@ public class FragmentPop extends FragmentBase {
EntityAccount account = db.account().getAccount(id); EntityAccount account = db.account().getAccount(id);
boolean check = (synchronize && (account == null || boolean check = (synchronize && (account == null ||
!account.synchronize || account.error != null || !account.synchronize ||
account.error != null ||
!account.host.equals(host) ||
!account.starttls.equals(starttls) ||
!account.insecure.equals(insecure) || !account.insecure.equals(insecure) ||
!host.equals(account.host) || Integer.parseInt(port) != account.port || !account.port.equals(Integer.parseInt(port)) ||
!user.equals(account.user) || !password.equals(account.password))); !account.user.equals(user) ||
boolean reload = (check || account == null || !account.password.equals(password)));
account.synchronize != synchronize || Log.i("Account check=" + check);
account.browse != leave ||
!account.poll_interval.equals(Integer.parseInt(interval)));
Log.i("Account check=" + check + " reload=" + reload);
Long last_connected = null; Long last_connected = null;
if (account != null && synchronize == account.synchronize) if (account != null && synchronize == account.synchronize)
@ -374,8 +374,7 @@ public class FragmentPop extends FragmentBase {
db.endTransaction(); db.endTransaction();
} }
if (reload) ServiceSynchronize.eval(context, false, "save account");
ServiceSynchronize.reload(context, "save account");
if (!synchronize) { if (!synchronize) {
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -563,7 +562,7 @@ public class FragmentPop extends FragmentBase {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
db.account().setAccountTbd(id); db.account().setAccountTbd(id);
ServiceSynchronize.reload(context, "delete account"); ServiceSynchronize.eval(context, false, "delete account");
return null; return null;
} }

@ -350,7 +350,7 @@ public class FragmentQuickSetup extends FragmentBase {
db.endTransaction(); db.endTransaction();
} }
ServiceSynchronize.reload(context, "quick setup"); ServiceSynchronize.eval(context, false, "quick setup");
return null; return null;
} }

@ -76,7 +76,7 @@ public class ServiceExternal extends Service {
String action = intent.getAction(); String action = intent.getAction();
if (ACTION_POLL.equals(action)) { if (ACTION_POLL.equals(action)) {
ServiceSynchronize.process(this, true); // TODO: sync all
return START_NOT_STICKY; return START_NOT_STICKY;
} }
@ -97,7 +97,7 @@ public class ServiceExternal extends Service {
boolean previous = prefs.getBoolean("enabled", true); boolean previous = prefs.getBoolean("enabled", true);
if (!enabled.equals(previous)) { if (!enabled.equals(previous)) {
prefs.edit().putBoolean("enabled", enabled).apply(); prefs.edit().putBoolean("enabled", enabled).apply();
ServiceSynchronize.reload(this, "external"); ServiceSynchronize.eval(this, false, "external");
} }
} else { } else {
final Context context = getApplicationContext(); final Context context = getApplicationContext();
@ -108,7 +108,7 @@ public class ServiceExternal extends Service {
EntityAccount account = db.account().getAccount(accountName); EntityAccount account = db.account().getAccount(accountName);
if (account != null) { if (account != null) {
db.account().setAccountSynchronize(account.id, enabled); db.account().setAccountSynchronize(account.id, enabled);
ServiceSynchronize.reload(context, "account enabled=" + enabled); ServiceSynchronize.eval(context, false, "account enabled=" + enabled);
} }
} }
}); });

File diff suppressed because it is too large Load Diff

@ -69,6 +69,6 @@ public class ServiceTileSynchronize extends TileService implements SharedPrefere
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean enabled = !prefs.getBoolean("enabled", true); boolean enabled = !prefs.getBoolean("enabled", true);
prefs.edit().putBoolean("enabled", enabled).apply(); prefs.edit().putBoolean("enabled", enabled).apply();
ServiceSynchronize.reload(this, true, "tile=" + enabled); ServiceSynchronize.eval(this, false, "tile=" + enabled);
} }
} }

@ -94,6 +94,6 @@ public class ServiceTileUnseen extends TileService {
public void onClick() { public void onClick() {
Log.i("Click tile unseen"); Log.i("Click tile unseen");
ServiceSynchronize.process(this, true); // TODO: sync all
} }
} }

@ -23,19 +23,20 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
public class TupleAccountNetworkState { public class TupleAccountNetworkState {
public boolean enabled;
public boolean reload; public boolean reload;
public ConnectionHelper.NetworkState networkState; public ConnectionHelper.NetworkState networkState;
public TupleAccountState accountState; public TupleAccountState accountState;
public TupleAccountNetworkState(boolean reload, ConnectionHelper.NetworkState networkState, TupleAccountState accountState) { public TupleAccountNetworkState(boolean enabled, boolean reload, ConnectionHelper.NetworkState networkState, TupleAccountState accountState) {
this.enabled = enabled;
this.reload = reload; this.reload = reload;
this.networkState = networkState; this.networkState = networkState;
this.accountState = accountState; this.accountState = accountState;
} }
public boolean shouldRun() { public boolean canRun() {
return (this.networkState.isSuitable() && return (this.networkState.isSuitable() && this.accountState.shouldRun(enabled));
this.accountState.shouldRun());
} }
@Override @Override

@ -22,7 +22,7 @@ package eu.faircode.email;
import java.util.Objects; import java.util.Objects;
public class TupleAccountState extends EntityAccount { public class TupleAccountState extends EntityAccount {
// TODO: folder property changes (name, synchronize, poll) // TODO: folder property changes (name, poll)
public int folders; public int folders;
public int operations; public int operations;
@ -31,24 +31,28 @@ public class TupleAccountState extends EntityAccount {
if (obj instanceof TupleAccountState) { if (obj instanceof TupleAccountState) {
TupleAccountState other = (TupleAccountState) obj; TupleAccountState other = (TupleAccountState) obj;
return (this.host.equals(other.host) && return (this.host.equals(other.host) &&
this.starttls == other.starttls && this.starttls.equals(other.starttls) &&
this.insecure == other.insecure && this.insecure.equals(other.insecure) &&
this.port.equals(other.port) && this.port.equals(other.port) &&
// auth_type
this.user.equals(other.user) && this.user.equals(other.user) &&
this.password.equals(other.password) && this.password.equals(other.password) &&
Objects.equals(this.realm, other.realm) && Objects.equals(this.realm, other.realm) &&
this.notify == other.notify && this.notify.equals(other.notify) &&
this.poll_interval.equals(other.poll_interval) && this.poll_interval.equals(other.poll_interval) &&
this.partial_fetch == other.partial_fetch && this.partial_fetch.equals(other.partial_fetch) &&
this.ignore_size == other.ignore_size && this.ignore_size.equals(other.ignore_size) &&
this.use_date == other.use_date && this.use_date.equals(other.use_date) &&
this.folders == other.folders); this.folders == other.folders &&
Objects.equals(this.tbd, other.tbd));
} else } else
return false; return false;
} }
boolean shouldRun() { boolean isEnabled(boolean enabled) {
return (synchronize && (folders > 0 || operations > 0)); return (enabled && synchronize && folders > 0 && tbd == null);
}
boolean shouldRun(boolean enabled) {
return (isEnabled(enabled) || operations > 0);
} }
} }

@ -1,39 +0,0 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import androidx.annotation.Nullable;
import java.util.Objects;
public class TupleAccountStats {
public Integer accounts = 0;
public Integer operations = 0;
@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof TupleAccountStats) {
TupleAccountStats other = (TupleAccountStats) obj;
return (Objects.equals(this.accounts, other.accounts) &&
Objects.equals(this.operations, other.operations));
} else
return false;
}
}

@ -30,6 +30,8 @@ import androidx.work.WorkManager;
import androidx.work.Worker; import androidx.work.Worker;
import androidx.work.WorkerParameters; import androidx.work.WorkerParameters;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class WorkerPoll extends Worker { public class WorkerPoll extends Worker {
@ -42,7 +44,25 @@ public class WorkerPoll extends Worker {
@Override @Override
public Result doWork() { public Result doWork() {
Log.i("Running " + getName()); Log.i("Running " + getName());
ServiceSynchronize.process(getApplicationContext(), true);
DB db = DB.getInstance(getApplicationContext());
try {
db.beginTransaction();
List<EntityAccount> accounts = db.account().getSynchronizingAccounts();
for (EntityAccount account : accounts) {
List<EntityFolder> folders = db.folder().getSynchronizingFolders(account.id);
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(getApplicationContext()));
for (EntityFolder folder : folders)
EntityOperation.sync(getApplicationContext(), folder.id, false);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return Result.success(); return Result.success();
} }

@ -44,7 +44,7 @@ public class WorkerWatchdog extends Worker {
@Override @Override
public Result doWork() { public Result doWork() {
Log.i("Running " + getName()); Log.i("Running " + getName());
ServiceSynchronize.watchdog(getApplicationContext()); ServiceSynchronize.eval(getApplicationContext(), false, "watchdog");
ServiceSend.watchdog(getApplicationContext()); ServiceSend.watchdog(getApplicationContext());
return Result.success(); return Result.success();
} }

Loading…
Cancel
Save