This change should have no impact on behavior.
SQLite supports [several different checkpoint modes][0]. We always use
the "TRUNCATE" mode, so we can remove the code that handles different
ones.
We can also stop logging checkpoint results that are [always 0 in
"TRUNCATE" mode][1].
We can also use GRDB's WAL checkpoint method instead of calling SQLite's
API directly.
[0]: https://www.sqlite.org/c3ref/c_checkpoint_full.html
[1]: https://sqlite.org/c3ref/wal_checkpoint_v2.html
*I recommend reviewing this with whitespace changes disabled.*
`GRDBDatabaseStorageAdapter.logIntegrityChecks()` needn't return a
promise. It only does that so it can run on a specific dispatch queue.
Instead, the dispatch queue should be the responsibility of the caller.
This change should have no user impact and makes a future improvement
easier.
* Factor out RegistrationCoordinatorLoader
* Add PNI change number state to regcoordinatorloader
* Don't exit change number flow once we start a pni operation
* Add ChangePhoneNumberPniManager to reg coordinator dependencies
* add params required for pni to change number registration mode
* change number from regcoordinator
* rename ChangePhoneNumber -> LegacyChangePhoneNumber
* remove pni change number support from LegacyChangePhoneNumber
* remove codable conformance from pni change number manager's pending state
* Update ts account manager state when finalizing change number
* Add message processor deps to reg coordinator
* addAsyncCompletion on dbv2 write transactions
* Suspend message processing while doing a reg coordinator change number
* hook up change number
* Add handler-free message processing suspension method
* odds and ends
* minor cleanup
* slight refactor to finalize change phone number in the export function
* Put wait for message processing + suspend onto messageProcessor
* kick of prekey refresh after pni change number finalize transaction ends
* nit
From [the SQLite docs][0]:
> Query or change the fullfsync flag for checkpoint operations. If this
> flag is set, then the F_FULLFSYNC syncing method is used during
> checkpoint operations on systems that support F_FULLFSYNC. The default
> value of the checkpoint_fullfsync flag is off.
In other words, checkpoints should be more reliable (but possibly
slower).
[0]: https://www.sqlite.org/pragma.html#pragma_checkpoint_fullfsync
* Add CallEvent sync message proto
* Add CallRecord class and db table
* Renames and comments for clarity
* create and update CallRecord from local device call events
* Handle incoming call event sync messages
* Add outgoing call sync event piping
* Send call event sync messages
* Handle call record sync messages before the app is launched
* Mark TSCall interactions as read and update their status when getting call event sync messages
* Prevent CallKit race conditions by checking state before creating TSCall interactions
* Update chat call event text for unanswered and declined calls
* Remove incorrect debug assert which fires every time a call is missed in the background
* PR comments, mostly nits
* convert old debug assert into a log + task comment
* nit
* Update copy for in chat call logs
* Smaller PR comments
* Add foreign key to CallRecord's interactionUniqueId
* Update write transaction ordering comment
* run genstrings
* fix strings
The `#if` blocks seem to be confusing swiftlint. Since this is
debug-only code, just disable those warnings.
(GRDB itself will catch *some* re-entrant queries but not all of them,
so we might want to keep this logic around even though it’s disabled. It
detects read/read and write/write, but it doesn’t detect read/write or
write/read.)
This adds a table of "cancelled group rings", to handle out-of-order
delivery between a cancellation and a ring. (This can happen when the
cancellation comes from a linked device rather than the original
ringer, though it's very unlikely.) Thirty-minute-old cancellations
are cleared lazily.
This also adds a new IncomingCallControls to replace the usual
CallControls in a GroupCallViewController.
And finally, there's a lot of code that was 1:1-call-specific that now
handles group calls as well, either by being more general or by
checking which kind of call we have.
This change may improve performance slightly but should have no other
user impact.
`myString.isEmpty` is faster than `myString.count == 0` or equivalent,
because computing `count` may require iterating over the string.
I tried to fix all occurrences of this.
Tested this by sending a message in a group and doing a full
re-registration, just in case I broke something there.
Change license to AGPL
This commit:
- Updates the `LICENSE` file
- Start every file with something like:
// Copyright YEAR_FIRST_PUBLISHED Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
---
First, I removed existing license headers with this Ruby 3.1.2 script:
require 'set'
EXTENSIONS_TO_CHECK = Set['.h', '.hpp', '.cpp', '.m', '.mm', '.pch', '.swift']
same = 0
different = 0
all_files = `git ls-files`.lines.map { |line| line.strip }
all_files.each do |relative_path|
if relative_path == 'Pods'
next
end
unless EXTENSIONS_TO_CHECK.include? File.extname(relative_path)
next
end
path = File.expand_path(relative_path)
contents = File.read(path)
new_contents = contents.sub(/\/\/\n\/\/ Copyright .*\n\/\/\n\n/, '')
if contents == new_contents
same += 1
else
different += 1
end
File.write(path, new_contents)
end
puts "updated #{different} file(s), left #{same} untouched"
I'm sure this script could be improved, but it worked well enough.
Then, I created `Scripts/lint/lint-license-headers` and ran it to auto-
fix a lot of files. This changed the mode of some files, but I think
that's actually desirable. For example,
`SignalServiceKit/src/Util/AppContext.m` previously had a mode of
`0755/-rwxr-xr-x`, and it's now `0644/-rw-r--r--`.
Then I fixed some stragglers and updated the precommit script.
See [a similar change in the Desktop app][0].
[0]: 8bfaf598af
If a user's database is corrupted, we now try to fix it. I recommend
reviewing `DatabaseRecovery` to see how this works, and
`DatabaseRecoveryViewController` for the bulk of the UI.
* Add StoryContextAssociatedData and db migrations
* Remove hideStory from ThreadAssociatedData
* Remove lastViewedStoryTimestamp and lastReceivedStoryTimestamp from TSThread
* drop deprecated columns in db migration
* add indexes
* dump schema.sql
* Update unviewed stories SQL query
* fix thread fetching for incoming story messages
* reload story tab badge when StoryContextAssociatedData changes
* Add test for TSGroupModel backwards-compatible deserialization
* move db migration
* Only use StoryContextAssociatedData for story badge count
* update StoryContextAssociatedData lastReceivedTime when a story message is deleted
* catch group threads for outgoing story messages too
* clean up sql query
* Only update lastReceievedStoryTimestamp for remote deletions
* add latestUnexpiredTimestamp to StoryContextAssociatedData
Previously, users who experienced database corruption would be asked to
submit debug logs. (Special builds had additional options which were not
generally available, so some of this code was already written.)
Now, if they choose to submit debug logs, they will also be asked to
submit a "database diagnostic" before the logs are submitted. This runs
and logs the results of `PRAGMA cipher_provider`, `PRAGMA
cipher_integrity_check`, and whether `PRAGMA quick_check` succeeds. If
they choose to skip the diagnostic, we still submit debug logs.
Other launch failures, such as "out of disk space", do not run these
diagnostics, as they're irrelevant.
This disgusting hack removes GRDB's notification
center observers, which prevents it from calling
`DatabasePool.releaseMemory()`.
`releaseMemory` is harmful because it places all
future reads behind a dispatch barrier. The effect
is that even very short reads block on any db
reads that precede the barrier. Some of those can
be very slow, such as orphan message handling.
The practical effect of this barrier is that the
main thread gets stuck on what should be a very
quick operation, such as loading your own avatar
data. iOS can kill the app with 8badf00d.
This change is a temporary workaround. A proper
solution has been added to a PR that I sent to
GRDB, which you can see here:
https://github.com/groue/GRDB.swift/pull/1253
Once that is accepted upstream we should update
GRDB and revert this commit.
This change should fix IOS-2474 and doubtless many
other issues.
This upgrades [GRDB][0] from v4.3.0 to v5.23.0, the latest version.
I closely followed the [migration guide][1] and stole from a prior
attempt at this upgrade. I also made sure to test the media gallery,
because that allegedly had problems before.
[0]: https://github.com/groue/GRDB.swift
[1]: 6d3f309cad/Documentation/GRDB5MigrationGuide.md
The default cache size for a SQLite connection is 2000KiB, but our
database pool has several reader connections plus a writer connection.
They can't share a cache because that changes SQLite's locking model,
so the next best thing is to limit their caches individually when
we're in a memory-constrained environment. To avoid the caches getting
*too* small, this also removes one of the available readers outside
the main app.