* We also don't copy out of the android SDK anymore as that has a
licensing impact. Instead we ship our own builds from a local AOSP
checkout, the same way as other plugins.
The "files" system expects other files to be #included, which won't make
sense for GLSL sources, which are expected to be concatenated. Use the
concatenated string as a single "main.glsl" file.
* CMake can find the local LLVM even without specifying LLVM_DIR, but
we don't want to build it for interceptor-lib unless it's exactly the
one we want, so we ask for explicit opt-in.
* On EGL we want to populate our hooks immediately so we have them ready
before anything is used, and it's valid because eglGetProcAddress is
spec'd to return function pointers that can be used with any context.
* Then later when we have a context we can check extensions and emulate.
* If we destroy them at the end of android_main we might destroy them
while the thread is running and cause incorrect code flows where we
try to join and restart the thread while it's blocking.
* Don't get me started on why android_main exits when you get alt-tabbed
away from...
* Note we still have to use PLT hooking for android_dlopen_ext that
libvulkan uses to load layers, since interceptor-lib can't hook that,
and otherwise libvulkan will load our library multiple times into the
process instead of re-using the existing injected library.
* If we want our global constructor to run after even static linked
libaries (which we will soon for LLVM) then we must make it a static
library as well. We do some tricks to ensure the symbols are still
pulled in even though it's otherwise "unused".
* This library will be used to replace the PLT hooking for most core
functions, and is generally more reliable. It still fails in some
cases though when the target function is not patchable.
* To build, it requires LLVM. See README.md for instructions on building
a compatible LLVM for use.
* This closely resembles the behaviour before, when at least for vulkan
the library wouldn't be loaded and open the connection until the
instance is created and the layer is loaded.
* When injecting our libraries, the connection is made very early but it
may be some time before the program initialises vulkan - we can't
setprop debug.vulkan.layers back to empty until it has, so instead we
wait for the API to be presenting.
* We assume that if the user injected libVkLayer_GLES_RenderDoc.so then
it's either a vulkan app and that's sufficient, or they linked
against it.
* Injecting our libraries over the top of that could cause problems -
at worst crashes, or at best we could end up with nested hooking with
double overhead, or the loaded renderdoc library won't be the one that
hooks and the workflow will break.
* This lets us add the debuggable flag we need, at the cost of needing
to re-sign the APK. It works in many cases although sometimes it does
fail - but this is provided just as a 'best effort' and not as a
recommended workflow.
* We don't consider anything else, this includes permissions or the
library being present. Since we no longer expect to patch in the
library we also don't check its version (however we leave the tag in
case it is useful in the future).
* If the user has root access we will never warn, assuming the injection
will work fine even without the debuggable flag.
* This is based on the GAPID method of injection, using the same steps
to connect with JDWP and debug the application, breakpointing on key
init-time steps to patch vulkan layer search paths and load libraries
from our installed apk.
* We diverge by then using PLT hooks instead of trampolines to hook the
EGL/GL calls - and so we also hook dlopen.
* This should work on any debuggable application - not currently checked
but does not replace/break any of the previous injection, which can
still work.
* Android::StartAndroidPackageForCapture can take a long time, and we
want to preserve the connection, so we spin up a temporary thread to
continually Ping().