Skip to content

Commit dc77226

Browse files
Address a FTS table configuration crash.
1 parent 0a346ed commit dc77226

3 files changed

Lines changed: 35 additions & 3 deletions

File tree

app/src/main/java/org/thoughtcrime/securesms/database/SearchTable.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.thoughtcrime.securesms.database
22

33
import android.annotation.SuppressLint
4+
import android.app.Application
45
import android.content.Context
56
import android.database.Cursor
67
import android.database.sqlite.SQLiteException
@@ -11,6 +12,8 @@ import org.signal.core.util.SqlUtil
1112
import org.signal.core.util.ThreadUtil
1213
import org.signal.core.util.logging.Log
1314
import org.signal.core.util.withinTransaction
15+
import org.thoughtcrime.securesms.dependencies.AppDependencies
16+
import org.thoughtcrime.securesms.dependencies.ApplicationDependencyProvider
1417
import org.thoughtcrime.securesms.jobs.RebuildMessageSearchIndexJob
1518

1619
/**
@@ -288,6 +291,11 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
288291
Log.w(TAG, "[fullyResetTables] Recreating triggers...")
289292
CREATE_TRIGGERS.forEach { db.execSQL(it) }
290293

294+
// There are specific error recovery paths where this is run inside of database initialization, before the job manager is initialized
295+
if (!AppDependencies.isInitialized) {
296+
AppDependencies.init(context as Application, ApplicationDependencyProvider(context))
297+
}
298+
291299
RebuildMessageSearchIndexJob.enqueue()
292300

293301
Log.w(TAG, "[fullyResetTables] Done. Index will be rebuilt asynchronously)")

app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package org.thoughtcrime.securesms.database.helpers
22

33
import android.app.Application
44
import android.content.Context
5+
import android.database.sqlite.SQLiteException
56
import net.zetetic.database.sqlcipher.SQLiteDatabase
67
import org.signal.core.util.areForeignKeyConstraintsEnabled
78
import org.signal.core.util.logging.Log
8-
import org.signal.core.util.withinTransaction
9+
import org.thoughtcrime.securesms.database.SignalDatabase
910
import org.thoughtcrime.securesms.database.helpers.migration.SignalDatabaseMigration
1011
import org.thoughtcrime.securesms.database.helpers.migration.V149_LegacyMigrations
1112
import org.thoughtcrime.securesms.database.helpers.migration.V150_UrgentMslFlagMigration
@@ -226,10 +227,28 @@ object SignalDatabaseMigrations {
226227
Log.i(TAG, "Running migration for version $version: ${migration.javaClass.simpleName}. Foreign keys: ${migration.enableForeignKeys}")
227228
val startTime = System.currentTimeMillis()
228229

230+
var ftsException: SQLiteException? = null
231+
229232
db.setForeignKeyConstraintsEnabled(migration.enableForeignKeys)
230-
db.withinTransaction {
233+
db.beginTransaction()
234+
try {
231235
migration.migrate(context, db, oldVersion, newVersion)
232236
db.version = version
237+
db.setTransactionSuccessful()
238+
} catch (e: SQLiteException) {
239+
if (e.message?.contains("invalid fts5 file format") == true || e.message?.contains("vtable constructor failed") == true) {
240+
ftsException = e
241+
} else {
242+
throw e
243+
}
244+
} finally {
245+
db.endTransaction()
246+
}
247+
248+
if (ftsException != null) {
249+
Log.w(TAG, "Encountered FTS format issue! Attempting to repair.", ftsException)
250+
SignalDatabase.messageSearch.fullyResetTables(db)
251+
throw ftsException
233252
}
234253

235254
Log.i(TAG, "Successfully completed migration for version $version in ${System.currentTimeMillis() - startTime} ms")

app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraintObserver.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import android.app.Application;
44
import android.os.Build;
5+
import android.os.Handler;
6+
import android.os.HandlerThread;
57
import android.telephony.PhoneStateListener;
68
import android.telephony.ServiceState;
79
import android.telephony.TelephonyCallback;
@@ -44,7 +46,10 @@ private CellServiceConstraintObserver(@NonNull Application application) {
4446
if (Build.VERSION.SDK_INT >= 31) {
4547
telephonyManager.registerTelephonyCallback(SignalExecutors.BOUNDED, new ServiceStateListenerApi31());
4648
} else {
47-
SignalExecutors.BOUNDED.execute(() -> {
49+
HandlerThread handlerThread = SignalExecutors.getAndStartHandlerThread("CellServiceConstraintObserver", Thread.NORM_PRIORITY);
50+
Handler handler = new Handler(handlerThread.getLooper());
51+
52+
handler.post(() -> {
4853
telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
4954
});
5055
}

0 commit comments

Comments
 (0)