From 1778e4028d4ff85a6e06bbab7f45f41b58baadba Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 31 Jan 2018 14:36:56 +0000 Subject: [PATCH] Don't do any injection if the library is already present * 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. --- renderdoc/android/android.cpp | 61 +++++++++++++++++++++++++++---- renderdoc/core/target_control.cpp | 3 ++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/renderdoc/android/android.cpp b/renderdoc/android/android.cpp index ff90081bf..cfbb9144f 100644 --- a/renderdoc/android/android.cpp +++ b/renderdoc/android/android.cpp @@ -141,20 +141,67 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package) adbExecCommand(deviceID, "shell am force-stop " + packageName); // enable the vulkan layer (will only be used by vulkan programs) adbExecCommand(deviceID, "shell setprop debug.vulkan.layers " RENDERDOC_VULKAN_LAYER_NAME); - // start the activity in this package with debugging enabled and force-stop after starting - adbExecCommand(deviceID, StringFormat::Fmt("shell am start -S -D %s/%s", packageName.c_str(), - activityName.c_str())); - // adb shell ps | grep $PACKAGE | awk '{print $2}') - int pid = GetCurrentPID(deviceID, packageName); + std::string installedPath = GetPathForPackage(deviceID, packageName); + + std::string RDCLib = trim( + adbExecCommand(deviceID, "shell ls " + installedPath + "/lib/*/" RENDERDOC_ANDROID_LIBRARY) + .strStdout); + + bool injectLibraries = true; + + if(RDCLib.empty()) + { + RDCLOG("No library found in %s/lib/*/" RENDERDOC_ANDROID_LIBRARY + " for %s - assuming injection is required.", + installedPath.c_str(), packageName.c_str()); + } + else + { + injectLibraries = false; + RDCLOG("Library found, no injection required: %s", RDCLib.c_str()); + } + + int pid = 0; + + if(injectLibraries) + { + RDCLOG("Setting up to launch the application as a debugger to inject."); + + // start the activity in this package with debugging enabled and force-stop after starting + adbExecCommand(deviceID, StringFormat::Fmt("shell am start -S -D %s/%s", packageName.c_str(), + activityName.c_str())); + + // adb shell ps | grep $PACKAGE | awk '{print $2}') + pid = GetCurrentPID(deviceID, packageName); + } + else + { + RDCLOG("Not doing any injection - assuming APK is pre-loaded with RenderDoc capture library."); + + // start the activity in this package with debugging enabled and force-stop after starting + adbExecCommand(deviceID, StringFormat::Fmt("shell am start %s/%s", packageName.c_str(), + activityName.c_str())); + + // don't connect JDWP + jdwpPort = 0; + } adbForwardPorts(index, deviceID, jdwpPort, pid); // sleep a little to let the ports initialise Threading::Sleep(500); - // use a JDWP connection to inject our libraries - InjectWithJDWP(deviceID, jdwpPort); + if(jdwpPort) + { + // use a JDWP connection to inject our libraries + bool injected = InjectWithJDWP(deviceID, jdwpPort); + if(!injected) + { + RDCERR("Failed to inject using JDWP"); + return 0; + } + } uint32_t ret = RenderDoc_FirstTargetControlPort + RenderDoc_AndroidPortOffset * (index + 1); uint32_t elapsed = 0, diff --git a/renderdoc/core/target_control.cpp b/renderdoc/core/target_control.cpp index 230ba3428..56268bd77 100644 --- a/renderdoc/core/target_control.cpp +++ b/renderdoc/core/target_control.cpp @@ -712,6 +712,9 @@ public: msg.apiUse.presenting = presenting; msg.apiUse.supported = supported; + if(presenting) + m_API = ToStr(driver); + RDCLOG("Used API: %s (%s & %s)", msg.apiUse.name.c_str(), presenting ? "Presenting" : "Not presenting", supported ? "supported" : "not supported");