1. The things we're really trying to protect - contact identities,
message contents, etc - can't be erased from memory because they're
encapsulated inside objects we don't control.
2. Long-term secrets can't be protected by erasing them from memory
because they're stored in the database and the database key has to be
held in memory whenever the app's running.
3. If the runtime uses a compacting garbage collector then we have no
way to ensure an object is erased from memory.
4. Trying to erase secrets from memory makes the code more complex.
Conclusion: Let's not try to protect secrets from an attacker who can
read arbitrary memory locations.
This ensures that if two DatabaseExecutor tasks update the database and
broadcast events, the events are broadcast in the same order as the
updates occurred.
We check for compatibility by specifying a schema version and minimum
schema version in the code, storing them in the DB, and checking whether
the DB is too old for the code or vice versa.
Dev task #52. Known but unverified identities are also supported, but
currently unused. These will be used in future for contacts who've been
introduced but not verified face to face.
If the schema of the database is incompatible with the schema expected
by the code, the database throws a DbSchemaException. LifecycleManager
indicates the error to BriarService, which uses HomeScreenActivity to
show a notification and quit the app.