If "adb install" command is used with "-g" flag, we may get java.lang.SecurityException on some devices because granting runtime permissions at installation time is only allowed for system apps (however we can enable it in the device's Developer options menu).
Also, pulling APK from /data/app/ may be restricted. We can workaround by copying the APK to a directory which we can access then try to pull the APK from there.
* This means that things will work successfully even if the 'executable' is
actually e.g. python3 in a system directory and nowhere related to where the
renderdoc library is.
* This has some possible problems - e.g. if one copy of qrenderdoc is closed and
kills the server used by another copy. However it seems impossible to reliably
manage adb and we need to ensure we don't leave the process lingering around.
* At the moment 95% of users don't use android, so it's most important that they
have a smooth experience.
* This was the cause of problems around updating versions because adb.exe would
hang around and then be 'in use' and not able to be overwritten.
"cmd package resolve-activity" is only available from Android 7.0. Pre Android 7.0 we can use "pm dump <packagename>" to get the default Activity name.
* If android studio or other android tools are open when a package is
launched for debugging, they greedily jump on it and connect which
prevents us from connecting.
* We can't reliably know when we can safely remove the layer property
at capture time because it's impossible to know if an android app will
use vulkan or not. So instead we fall back to unsetting it whenever we
need to - before opening a capture or when shutting down the remote
server (in case after capturing, no frame capture was actually opened)
* This means that if the UI crashes without unsetting it, we will poison
the state, but this seems unavoidable.
* 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.
* 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.