From bca8f11c9c2d3df9dcfc2253bc108fc6e9a241ef Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 8 Nov 2016 12:20:07 +0100 Subject: [PATCH] add frequent restart detection --- .../java/eu/siacs/conversations/Config.java | 3 +++ .../persistance/DatabaseBackend.java | 24 ++++++++++++++++++- .../services/XmppConnectionService.java | 14 +++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 28b090132..1ebb4d138 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -101,6 +101,9 @@ public final class Config { public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; public static final int MAM_MAX_MESSAGES = 500; + public static final long FREQUENT_RESTARTS_DETECTION_WINDOW = 10 * 60 * 60 * 1000; // 10 hours + public static final long FREQUENT_RESTARTS_THRESHOLD = 10; + public static final ChatState DEFAULT_CHATSTATE = ChatState.ACTIVE; public static final int TYPING_TIMEOUT = 8; diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 5f625ebe3..ad8dc62c0 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -54,7 +54,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 29; + private static final int DATABASE_VERSION = 30; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -139,6 +139,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { + ") ON CONFLICT IGNORE" + ");"; + private static String CREATE_START_TIMES_TABLE = "create table start_times (timestamp NUMBER);"; + private DatabaseBackend(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -194,6 +196,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); db.execSQL(CREATE_IDENTITIES_STATEMENT); db.execSQL(CREATE_PRESENCE_TEMPLATES_STATEMENT); + db.execSQL(CREATE_START_TIMES_TABLE); } @Override @@ -338,6 +341,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 29 && newVersion >= 29) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.ERROR_MESSAGE + " TEXT"); } + if (oldVersion < 30 && newVersion >= 30) { + db.execSQL(CREATE_START_TIMES_TABLE); + } } private void canonicalizeJids(SQLiteDatabase db) { @@ -1222,4 +1228,20 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteAxolotlStore.ACCOUNT + " = ?", deleteArgs); } + + public boolean startTimeCountExceedsThreshold() { + SQLiteDatabase db = this.getWritableDatabase(); + long cleanBeforeTimestamp = System.currentTimeMillis() - Config.FREQUENT_RESTARTS_DETECTION_WINDOW; + db.execSQL("delete from start_times where timestamp < "+cleanBeforeTimestamp); + ContentValues values = new ContentValues(); + values.put("timestamp",System.currentTimeMillis()); + db.insert("start_times",null,values); + String[] columns = new String[]{"count(timestamp)"}; + Cursor cursor = db.query("start_times",columns,null,null,null,null,null); + if (cursor.moveToFirst()) { + return cursor.getInt(0) >= Config.FREQUENT_RESTARTS_THRESHOLD; + } else { + return false; + } + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 12f20d036..044a518a6 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -864,6 +864,11 @@ public class XmppConnectionService extends Service { this.databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); + if (!keepForegroundService() && databaseBackend.startTimeCountExceedsThreshold()) { + getPreferences().edit().putBoolean("keep_foreground_service",true).commit(); + Log.d(Config.LOGTAG,"number of restarts exceeds threshold. enabling foreground service"); + } + restoreFromDatabase(); getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver); @@ -894,6 +899,7 @@ public class XmppConnectionService extends Service { this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE); this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "XmppConnectionService"); + toggleForegroundService(); updateUnreadCountBadge(); toggleScreenEventReceiver(); @@ -940,17 +946,21 @@ public class XmppConnectionService extends Service { } public void toggleForegroundService() { - if (getPreferences().getBoolean("keep_foreground_service", false)) { + if (keepForegroundService()) { startForeground(NotificationService.FOREGROUND_NOTIFICATION_ID, this.mNotificationService.createForegroundNotification()); } else { stopForeground(true); } } + private boolean keepForegroundService() { + return getPreferences().getBoolean("keep_foreground_service",false); + } + @Override public void onTaskRemoved(final Intent rootIntent) { super.onTaskRemoved(rootIntent); - if (!getPreferences().getBoolean("keep_foreground_service", false)) { + if (!keepForegroundService()) { this.logoutAndSave(false); } else { Log.d(Config.LOGTAG,"ignoring onTaskRemoved because foreground service is activated");