Configuration cache causes issues with our version generation code in the gradle build script. We compute the version name and version code based on git information, and configuration cache saves those values by default, needing a manual reload of the gradle project to refresh them.
There's currently no way to avoid caching the version name and version code in the configuration cache, so we need to turn it off altogether.
Starting from version 26+, the NDK is based on LLVM 17 and comes with Clang 17 featuring full language and library C++20 support.
This means we can get rid of the massive LLVM submodule in the repo, which will be done in a following commit.
Version code uses the number of commits until the last tag.
Version name uses the tag name if HEAD is a tag, otherwise it uses the last tag name followed by the branch name and the short commit hash.
Since the latest Android updates, which most users received in the form of August 2023 security patches, the Android runtime seems to rely on handling SIGSEGV via sigchain while performing JNI calls. We were hooking libc directly to inject our own signal handlers, so that they could run and restore the host TLS since the signal might have been generated in guest code. However, due to how we dispatched signals, the ART handlers were never called and the app crashed whenever a JNI call was made after installing our handlers.
This commit reworks signal handling to remove per-thread handlers. We now make a distinction between guest signals and host signals, and two new functions to set signal handlers have been introduced: `SetGuestSignalHandler` and `SetHostSignalHandler`. This greatly simplifies our signal handling code and allows us to get rid of some thread-local state.
Because of the above distinction, we install a "guest-safe" signal handler only when a guest signal is set. The guest-safe signal handler calls guest handlers only for guest signals, or falls back to the host handler if that's not the case.
Once a guest handler exists for a particular signal, we query libc sigaction as well as the sigchain-hooked sigaction and compare the results, and in case they differ we call sigchain's sigaction so that the host handler is correctly chained, ensuring no host handler can accidentally override the sigchain handler.
CommandScheduler and PresentationEngine both constructed the consumer threads before their CircularQueues, this resulted in a data race that would lead to a segfault if the threads were scheduled for execution quickly enough, as they would read uninitialized memory.