diff --git a/app/src/main/java/eu/faircode/email/ConnectionHelper.java b/app/src/main/java/eu/faircode/email/ConnectionHelper.java index 78d763204d..1d333161de 100644 --- a/app/src/main/java/eu/faircode/email/ConnectionHelper.java +++ b/app/src/main/java/eu/faircode/email/ConnectionHelper.java @@ -11,6 +11,7 @@ import android.os.Build; import android.provider.Settings; import android.telephony.TelephonyManager; +import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; import org.xbill.DNS.Lookup; @@ -24,6 +25,7 @@ import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import javax.mail.Address; import javax.mail.internet.InternetAddress; @@ -94,6 +96,19 @@ public class ConnectionHelper { connected = newState.connected; unmetered = newState.unmetered; suitable = newState.suitable; + roaming = newState.roaming; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (obj instanceof NetworkState) { + NetworkState other = (NetworkState) obj; + return (Objects.equals(this.connected, other.connected) && + Objects.equals(this.suitable, other.suitable) && + Objects.equals(this.unmetered, other.unmetered) && + Objects.equals(this.roaming, other.roaming)); + } else + return false; } } diff --git a/app/src/main/java/eu/faircode/email/DaoAccount.java b/app/src/main/java/eu/faircode/email/DaoAccount.java index 5eae0382de..109dfb7ba0 100644 --- a/app/src/main/java/eu/faircode/email/DaoAccount.java +++ b/app/src/main/java/eu/faircode/email/DaoAccount.java @@ -69,6 +69,16 @@ public interface DaoAccount { ", account.name COLLATE NOCASE") LiveData> liveAccountsEx(boolean all); + @Query("SELECT account.*" + + ", SUM(folder.synchronize) AS folders" + + ", COUNT(operation.id) AS operations" + + " FROM account" + + " LEFT JOIN folder ON folder.account = account.id" + + " LEFT JOIN operation ON operation.folder = folder.id" + + " GROUP BY account.id" + + " ORDER BY account.id") + LiveData> liveAccountState(); + @Query("SELECT * FROM account WHERE id = :id") EntityAccount getAccount(long id); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index fe80cee88c..2894a4302c 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -41,6 +41,8 @@ import androidx.annotation.Nullable; import androidx.core.app.AlarmManagerCompat; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Observer; import androidx.preference.PreferenceManager; @@ -110,6 +112,34 @@ public class ServiceSynchronize extends ServiceBase { static final int PI_ALARM = 1; static final int PI_ONESHOT = 2; + private MutableLiveData liveNetworkState = new MutableLiveData<>(); + private MutableLiveData> liveAccountState = new MutableLiveData<>(); + private MediatorState liveAccountNetworkState = new MediatorState(); + + private class MediatorState extends MediatorLiveData> { + private ConnectionHelper.NetworkState lastNetworkState = null; + private List lastAccountStates = null; + + private void post(ConnectionHelper.NetworkState networkState) { + lastNetworkState = networkState; + post(lastNetworkState, lastAccountStates); + } + + private void post(List accountStates) { + lastAccountStates = accountStates; + post(lastNetworkState, lastAccountStates); + } + + private void post(ConnectionHelper.NetworkState networkState, List accountStates) { + if (networkState != null && accountStates != null) { + List result = new ArrayList<>(); + for (TupleAccountState accountState : accountStates) + result.add(new TupleAccountNetworkState(networkState, accountState)); + postValue(result); + } + } + } + @Override public void onCreate() { EntityLog.log(this, "Service create version=" + BuildConfig.VERSION_NAME); @@ -132,6 +162,34 @@ public class ServiceSynchronize extends ServiceBase { DB db = DB.getInstance(this); + db.account().liveAccountState().observe(this, new Observer>() { + @Override + public void onChanged(List accountStates) { + liveAccountState.postValue(accountStates); + } + }); + + liveAccountNetworkState.addSource(liveNetworkState, new Observer() { + @Override + public void onChanged(ConnectionHelper.NetworkState networkState) { + liveAccountNetworkState.post(networkState); + } + }); + + liveAccountNetworkState.addSource(liveAccountState, new Observer>() { + @Override + public void onChanged(List accountStates) { + liveAccountNetworkState.post(accountStates); + } + }); + + liveAccountNetworkState.observe(this, new Observer>() { + @Override + public void onChanged(List accountNetworkStates) { + Log.i("Account network states=" + accountNetworkStates.size()); + } + }); + db.account().liveStats().observe(this, new Observer() { private TupleAccountStats lastStats = null; @@ -1416,7 +1474,9 @@ public class ServiceSynchronize extends ServiceBase { } private void updateState() { - networkState.update(ConnectionHelper.getNetworkState(ServiceSynchronize.this)); + ConnectionHelper.NetworkState ns = ConnectionHelper.getNetworkState(ServiceSynchronize.this); + liveNetworkState.postValue(ns); + networkState.update(ns); if (lastSuitable == null || lastSuitable != networkState.isSuitable()) { lastSuitable = networkState.isSuitable(); diff --git a/app/src/main/java/eu/faircode/email/TupleAccountNetworkState.java b/app/src/main/java/eu/faircode/email/TupleAccountNetworkState.java new file mode 100644 index 0000000000..e1f14bae9c --- /dev/null +++ b/app/src/main/java/eu/faircode/email/TupleAccountNetworkState.java @@ -0,0 +1,31 @@ +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 . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +public class TupleAccountNetworkState { + public ConnectionHelper.NetworkState networkState; + public TupleAccountState accountState; + + public TupleAccountNetworkState(ConnectionHelper.NetworkState networkState, TupleAccountState accountState) { + this.networkState = networkState; + this.accountState = accountState; + } +} + diff --git a/app/src/main/java/eu/faircode/email/TupleAccountState.java b/app/src/main/java/eu/faircode/email/TupleAccountState.java new file mode 100644 index 0000000000..9ad9a06fc9 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/TupleAccountState.java @@ -0,0 +1,36 @@ +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 . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +public class TupleAccountState extends EntityAccount { + public int folders; + public int operations; + + @Override + public boolean equals(Object obj) { + if (obj instanceof TupleAccountState) { + TupleAccountState other = (TupleAccountState) obj; + return (super.equals(obj) && // TODO selected attributes + this.folders == other.folders && + this.operations == other.operations); + } else + return false; + } +}