mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-04 11:54:10 +01:00
Warn about account problems
This commit is contained in:
1104
app/schemas/eu.faircode.email.DB/5.json
Normal file
1104
app/schemas/eu.faircode.email.DB/5.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,8 @@ public class ActivitySetup extends ActivityBilling implements FragmentManager.On
|
||||
static final int REQUEST_EXPORT = 3;
|
||||
static final int REQUEST_IMPORT = 4;
|
||||
|
||||
static final int REQUEST_ERROR = 5;
|
||||
|
||||
static final String ACTION_EDIT_ACCOUNT = BuildConfig.APPLICATION_ID + ".EDIT_ACCOUNT";
|
||||
static final String ACTION_EDIT_IDENTITY = BuildConfig.APPLICATION_ID + ".EDIT_IDENTITY";
|
||||
|
||||
|
||||
@@ -113,7 +113,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
||||
|
||||
static final int REQUEST_UNIFIED = 1;
|
||||
static final int REQUEST_THREAD = 2;
|
||||
static final int REQUEST_ERROR = 3;
|
||||
|
||||
static final int REQUEST_ATTACHMENT = 1;
|
||||
static final int REQUEST_INVITE = 2;
|
||||
|
||||
@@ -46,7 +46,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 4,
|
||||
version = 5,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
@@ -147,6 +147,14 @@ public abstract class DB extends RoomDatabase {
|
||||
db.execSQL("CREATE INDEX `index_message_forwarding` ON `message` (`forwarding`)");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(4, 5) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `account` ADD COLUMN `last_connected` INTEGER");
|
||||
db.execSQL("ALTER TABLE `message` ADD COLUMN `last_attempt` INTEGER");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ public interface DaoAccount {
|
||||
@Query("UPDATE account SET state = :state WHERE id = :id")
|
||||
int setAccountState(long id, String state);
|
||||
|
||||
@Query("UPDATE account SET last_connected = :last_connected WHERE id = :id")
|
||||
int setAccountConnected(long id, long last_connected);
|
||||
|
||||
@Query("UPDATE account SET password = :password WHERE id = :id")
|
||||
int setAccountPassword(long id, String password);
|
||||
|
||||
|
||||
@@ -263,6 +263,9 @@ public interface DaoMessage {
|
||||
@Query("UPDATE message SET stored = :stored WHERE id = :id")
|
||||
int setMessageStored(long id, long stored);
|
||||
|
||||
@Query("UPDATE message SET last_attempt = :last_attempt WHERE id = :id")
|
||||
int setMessageLastAttempt(long id, long last_attempt);
|
||||
|
||||
@Query("UPDATE message SET ui_ignored = 1" +
|
||||
" WHERE NOT ui_ignored" +
|
||||
" AND folder IN (SELECT id FROM folder WHERE type = '" + EntityFolder.INBOX + "')")
|
||||
|
||||
@@ -62,6 +62,7 @@ public class EntityAccount {
|
||||
public Long created;
|
||||
public String state;
|
||||
public String error;
|
||||
public Long last_connected;
|
||||
|
||||
public JSONObject toJSON() throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
@@ -81,6 +82,7 @@ public class EntityAccount {
|
||||
// not created
|
||||
// not state
|
||||
// not error
|
||||
// not last connected
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ public class EntityMessage implements Serializable {
|
||||
@NonNull
|
||||
public Boolean ui_ignored;
|
||||
public String error;
|
||||
public Long last_attempt; // send
|
||||
|
||||
static String generateMessageId() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
@@ -650,6 +650,8 @@ public class FragmentAccount extends FragmentEx {
|
||||
if (Color.TRANSPARENT == color)
|
||||
color = null;
|
||||
|
||||
long now = new Date().getTime();
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
EntityAccount account = db.account().getAccount(id);
|
||||
|
||||
@@ -708,7 +710,9 @@ public class FragmentAccount extends FragmentEx {
|
||||
account.primary = (account.synchronize && primary);
|
||||
account.poll_interval = Integer.parseInt(interval);
|
||||
|
||||
account.created = new Date().getTime();
|
||||
account.created = now;
|
||||
if (synchronize)
|
||||
account.last_connected = now;
|
||||
|
||||
if (!synchronize)
|
||||
account.error = null;
|
||||
|
||||
@@ -136,6 +136,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
private static final int DOWNLOAD_BATCH_SIZE = 20;
|
||||
private static final long RECONNECT_BACKOFF = 60 * 1000L; // milliseconds
|
||||
private static final int PREVIEW_SIZE = 250;
|
||||
private static final int ACCOUNT_ERROR_AFTER = 60; // minutes
|
||||
|
||||
static final int PI_WHY = 1;
|
||||
static final int PI_CLEAR = 2;
|
||||
@@ -574,10 +575,10 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
|
||||
private Notification.Builder getNotificationError(String action, Throwable ex) {
|
||||
// Build pending intent
|
||||
Intent intent = new Intent(this, ActivityView.class);
|
||||
Intent intent = new Intent(this, ActivitySetup.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent pi = PendingIntent.getActivity(
|
||||
this, ActivityView.REQUEST_ERROR, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
this, ActivitySetup.REQUEST_ERROR, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
// Build notification
|
||||
Notification.Builder builder;
|
||||
@@ -772,12 +773,19 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
for (EntityFolder folder : db.folder().getFolders(account.id))
|
||||
db.folder().setFolderState(folder.id, null);
|
||||
db.account().setAccountState(account.id, "connecting");
|
||||
|
||||
Helper.connect(this, istore, account);
|
||||
|
||||
final boolean capIdle = istore.hasCapability("IDLE");
|
||||
Log.i(Helper.TAG, account.name + " idle=" + capIdle);
|
||||
|
||||
db.account().setAccountState(account.id, "connected");
|
||||
db.account().setAccountConnected(account.id, new Date().getTime());
|
||||
db.account().setAccountError(account.id, null);
|
||||
|
||||
NotificationManager nm = getSystemService(NotificationManager.class);
|
||||
nm.cancel("receive", account.id.intValue());
|
||||
|
||||
EntityLog.log(this, account.name + " connected");
|
||||
|
||||
// Update folder list
|
||||
@@ -1164,6 +1172,15 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
reportError(account.name, null, ex);
|
||||
|
||||
db.account().setAccountError(account.id, Helper.formatThrowable(ex));
|
||||
|
||||
if (account.last_connected != null) {
|
||||
EntityLog.log(this, account.name + " last connected: " + new Date(account.last_connected));
|
||||
long now = new Date().getTime();
|
||||
if (now - account.last_connected > ACCOUNT_ERROR_AFTER * 60 * 1000L) {
|
||||
NotificationManager nm = getSystemService(NotificationManager.class);
|
||||
nm.notify("receive", account.id.intValue(), getNotificationError(account.name, ex).build());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
EntityLog.log(this, account.name + " closing");
|
||||
db.account().setAccountState(account.id, "closing");
|
||||
@@ -1461,6 +1478,11 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.last_attempt == null) {
|
||||
message.last_attempt = new Date().getTime();
|
||||
db.message().setMessageLastAttempt(message.id, message.last_attempt);
|
||||
}
|
||||
|
||||
// Create session
|
||||
Properties props = MessageHelper.getSessionProperties(ident.auth_type, ident.insecure);
|
||||
props.put("mail.smtp.localhost", ident.host);
|
||||
@@ -1489,9 +1511,13 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
} else
|
||||
throw ex;
|
||||
}
|
||||
|
||||
db.identity().setIdentityState(ident.id, "connected");
|
||||
db.identity().setIdentityError(ident.id, null);
|
||||
|
||||
NotificationManager nm = getSystemService(NotificationManager.class);
|
||||
nm.cancel("send", message.account.intValue());
|
||||
|
||||
// Send message
|
||||
Address[] to = imessage.getAllRecipients();
|
||||
itransport.sendMessage(imessage, to);
|
||||
@@ -1531,6 +1557,15 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
EntityOperation.process(this);
|
||||
} catch (MessagingException ex) {
|
||||
db.identity().setIdentityError(ident.id, Helper.formatThrowable(ex));
|
||||
|
||||
EntityLog.log(this, ident.name + " last attempt: " + new Date(message.last_attempt));
|
||||
|
||||
long now = new Date().getTime();
|
||||
if (now - message.last_attempt > ACCOUNT_ERROR_AFTER * 60 * 1000L) {
|
||||
NotificationManager nm = getSystemService(NotificationManager.class);
|
||||
nm.notify("send", message.account.intValue(), getNotificationError(ident.name, ex).build());
|
||||
}
|
||||
|
||||
throw ex;
|
||||
} finally {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user