This will stop instances of the following from occuring in the logs
on SMS migration:
W/SQLiteCompiledSql: Releasing statement in a finalizer. Please ensure
that you explicitly call close() on your cursor: INSERT INTO sms
(address, person, date_sent, date, protocol, read, status, type,
reply_path_present,
net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:109)
at net.sqlcipher.database.SQLiteStatement.<init>(SQLiteStatement.java:39)
at net.sqlcipher.database.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1647)
at org.thoughtcrime.securesms.database.SmsDatabase.createInsertStatement(SmsDatabase.java:767)
at org.thoughtcrime.securesms.database.SmsMigrator.migrateConversation(SmsMigrator.java:166)
at org.thoughtcrime.securesms.database.SmsMigrator.migrateDatabase(SmsMigrator.java:210)
at org.thoughtcrime.securesms.service.ApplicationMigrationService$ImportRunnable.run(ApplicationMigrationService.java:159)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
We aren't closing Statement objects before the finalizer on those
objects runs. When the GC runs, we'll get warnings like the above
which alert us to the fact that these objects are being automatically
closed for us in the finalizer, but that this is suboptimal behavior.
If we leave too many Statement (or Cursor) objects to be closed in
their finalizers, when the GC runs, it'll take longer than 10 seconds
to close them all and Android will kill the app. This 10 second limit
is hardcoded and we can only try to avoid it. A crash will look like:
java.util.concurrent.TimeoutException: net.sqlcipher.database.SQLiteCompiledSql.finalize() timed out after 10 seconds
at java.lang.Object.wait(Native Method)
at java.lang.Thread.parkFor$(Thread.java:1220)
at sun.misc.Unsafe.park(Unsafe.java:299)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:810)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:844)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1173)
at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:196)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:257)
at net.sqlcipher.database.SQLiteDatabase.lock(SQLiteDatabase.java:553)
at net.sqlcipher.database.SQLiteCompiledSql.releaseSqlStatement(SQLiteCompiledSql.java:106)
at net.sqlcipher.database.SQLiteCompiledSql.finalize(SQLiteCompiledSql.java:152)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:202)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
at java.lang.Thread.run(Thread.java:818)
I was able to replicate the above crash consistently on a
Samsung Galaxy S7 edge when importing well over 100k SMS messages.
But as soon as I attached a debugger the crash did not persist. I
assume this is because of some VM-level interactions between the two
and did not investigate further after fixing it.
I do not have access to the stack trace for issue #7953 but this
could potentially resolve it. The crash is identical to that in #7477
but this patch is for SMS migration not restoring from a backup. I
was not able to replicate the crash on restoring a >100k message
backup.
It used to be that we let Android do the default behavior of
full-screening the EditText when in landscape, but honestly I
don't know who prefers that. So I've turned it off.
Fixes#8769
The new JobManager stuff created a table that had an
auto-incrementing ID, which was incorrectly being backed
up and restored, causing a crash. Now we skip it on both
import and export.
Some devices have a limit of 100 unique JobScheduler jobs.
Previously we allowed up to 1,000. Given that we just need
_some_ job running, I lowered the limit to 75 to give us
some head room.