From bcb99146654b79476f804c4dc312f4cdf9b6a733 Mon Sep 17 00:00:00 2001 From: Michael Rennie Date: Wed, 2 Nov 2016 14:19:05 +0000 Subject: [PATCH] Start remoteserver and captured packages by adb commands in native code. Use adb to enumerate installed 3rd party packages in capture dialog. Cleaned up all the "adb:" strcmp's. --- renderdoc/core/remote_server.cpp | 42 ++++++++++++++++++++++++++-- renderdoc/core/target_control.cpp | 2 +- renderdoc/os/os_specific.h | 7 +++++ renderdoc/replay/entry_points.cpp | 35 ++++++++++++++++++++++- renderdocui/Interop/StaticExports.cs | 8 ++++++ renderdocui/Windows/MainWindow.cs | 7 +---- renderdocui/renderdocui.csproj | 4 +-- scripts/android_capture.bat | 6 ---- scripts/android_remoteserver.bat | 6 ---- 9 files changed, 92 insertions(+), 25 deletions(-) delete mode 100644 scripts/android_capture.bat delete mode 100644 scripts/android_remoteserver.bat diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index 5268cf71c..757e95435 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -23,6 +23,7 @@ * THE SOFTWARE. ******************************************************************************/ +#include #include #include "api/replay/renderdoc_replay.h" #include "core/core.h" @@ -705,7 +706,7 @@ void RenderDoc::BecomeRemoteServer(const char *listenhost, uint16_t port, volati struct RemoteServer : public IRemoteServer { public: - RemoteServer(Network::Socket *sock) : m_Socket(sock) + RemoteServer(Network::Socket *sock, const char *hostname) : m_Socket(sock), m_hostname(hostname) { map m = RenderDoc::Inst().GetReplayDrivers(); @@ -713,6 +714,7 @@ public: for(auto it = m.begin(); it != m.end(); ++it) m_Proxies.push_back(*it); } + const string &hostname() const { return m_hostname; } virtual ~RemoteServer() { SAFE_DELETE(m_Socket); } void ShutdownConnection() { delete this; } void ShutdownServerAndConnection() @@ -797,6 +799,9 @@ public: rdctype::str GetHomeFolder() { + if(Android::IsHostADB(m_hostname.c_str())) + return "/"; + rdctype::str ret; Serialiser sendData("", Serialiser::WRITING, false); @@ -824,6 +829,33 @@ public: { rdctype::array ret; + if(Android::IsHostADB(m_hostname.c_str())) + { + string adbStdout = Android::adbExecCommand("shell pm list packages -3"); + using namespace std; + istringstream stdoutStream(adbStdout); + string line; + vector packages; + while(getline(stdoutStream, line)) + { + vector tokens; + split(line, tokens, ':'); + if(tokens.size() == 2 && tokens[0] == "package") + { + DirectoryFile package; + package.filename = trim(tokens[1]); + package.flags = eFileProp_Executable; + packages.push_back(package); + } + } + + create_array_uninit(ret, packages.size()); + for(size_t i = 0; i < packages.size(); i++) + ret[i] = packages[i]; + + return ret; + } + string folderPath = path; Serialiser sendData("", Serialiser::WRITING, false); @@ -1069,6 +1101,7 @@ public: private: Network::Socket *m_Socket; + string m_hostname; void Send(RemoteServerPacket type, const Serialiser &ser) { SendPacket(m_Socket, type, ser); } void Get(RemoteServerPacket &type, Serialiser **ser) @@ -1137,6 +1170,9 @@ extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RemoteServer_ExecuteAndInject(RemoteServer *remote, const char *app, const char *workingDir, const char *cmdLine, void *env, const CaptureOptions *opts) { + if(Android::IsHostADB(remote->hostname().c_str())) + return Android::StartAndroidPackageForCapture(app); + return remote->ExecuteAndInject(app, workingDir, cmdLine, env, opts); } @@ -1190,7 +1226,7 @@ RENDERDOC_CreateRemoteServerConnection(const char *host, uint32_t port, RemoteSe if(port == 0) port = RENDERDOC_GetDefaultRemoteServerPort(); - if(host != NULL && !strncmp(host, "adb:", 4)) + if(host != NULL && Android::IsHostADB(host)) { s = "127.0.0.1"; @@ -1236,7 +1272,7 @@ RENDERDOC_CreateRemoteServerConnection(const char *host, uint32_t port, RemoteSe return eReplayCreate_NetworkIOFailed; } - *rend = new RemoteServer(sock); + *rend = new RemoteServer(sock, host); return eReplayCreate_Success; } diff --git a/renderdoc/core/target_control.cpp b/renderdoc/core/target_control.cpp index cee4366c8..7cd5947c1 100644 --- a/renderdoc/core/target_control.cpp +++ b/renderdoc/core/target_control.cpp @@ -707,7 +707,7 @@ extern "C" RENDERDOC_API TargetControl *RENDERDOC_CC RENDERDOC_CreateTargetContr bool android = false; - if(host != NULL && !strncmp(host, "adb:", 4)) + if(host != NULL && Android::IsHostADB(host)) { android = true; s = "127.0.0.1"; diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 1f74e9a81..ef8652399 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -443,3 +443,10 @@ inline uint64_t CountLeadingZeroes(uint64_t value); #else #error Undefined Platform! #endif + +namespace Android +{ +bool IsHostADB(const char *hostname); +uint32_t StartAndroidPackageForCapture(const char *package); +string adbExecCommand(const string &args); +} diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index d42ac708a..c9dfc3e4e 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -499,7 +499,7 @@ extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteTargets( nextIdent++; uint32_t lastIdent = RenderDoc_LastTargetControlPort; - if(host != NULL && !strncmp(host, "adb:", 4)) + if(host != NULL && Android::IsHostADB(host)) { if(nextIdent == RenderDoc_FirstTargetControlPort) nextIdent += RenderDoc_AndroidPortOffset; @@ -594,6 +594,12 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EndSelfHostCapture(const ch rdoc->EndFrameCapture(NULL, NULL); } +namespace Android +{ +bool IsHostADB(const char *hostname) +{ + return !strncmp(hostname, "adb:", 4); +} string adbExecCommand(const string &args) { string adbExePath = RenderDoc::Inst().GetConfigSetting("adbExePath"); @@ -614,7 +620,23 @@ void adbForwardPorts() RenderDoc_FirstTargetControlPort + RenderDoc_AndroidPortOffset, RenderDoc_FirstTargetControlPort)); } +uint32_t StartAndroidPackageForCapture(const char *package) +{ + string packageName = basename(string(package)); // Remove leading '/' if any + adbExecCommand("shell am force-stop " + packageName); + adbForwardPorts(); + adbExecCommand("shell setprop debug.vulkan.layers VK_LAYER_RENDERDOC_Capture"); + adbExecCommand("shell monkey -p " + packageName + " -c android.intent.category.LAUNCHER 1"); + Threading::Sleep( + 5000); // Let the app pickup the setprop before we turn it back off for replaying. + adbExecCommand("shell setprop debug.vulkan.layers \\\"\\\""); + + return RenderDoc_FirstTargetControlPort + RenderDoc_AndroidPortOffset; +} +} + +using namespace Android; extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdctype::str *deviceList) { string adbStdout = adbExecCommand("devices"); @@ -641,3 +663,14 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdc *deviceList = ret; } + +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer() +{ + adbExecCommand("shell am force-stop org.renderdoc.renderdoccmd"); + adbForwardPorts(); + adbExecCommand("shell setprop debug.vulkan.layers \\\"\\\""); + adbExecCommand( + "shell pm grant org.renderdoc.renderdoccmd android.permission.READ_EXTERNAL_STORAGE"); + adbExecCommand( + "shell am start -n org.renderdoc.renderdoccmd/.Loader -e renderdoccmd remoteserver"); +} diff --git a/renderdocui/Interop/StaticExports.cs b/renderdocui/Interop/StaticExports.cs index 8cad3400c..9c3d36f84 100644 --- a/renderdocui/Interop/StaticExports.cs +++ b/renderdocui/Interop/StaticExports.cs @@ -113,6 +113,9 @@ namespace renderdoc [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern ReplaySupport RENDERDOC_EnumerateAndroidDevices(IntPtr driverName); + [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern ReplaySupport RENDERDOC_StartAndroidRemoteServer(); + [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern void RENDERDOC_StartSelfHostCapture(IntPtr dllname); @@ -409,5 +412,10 @@ namespace renderdoc return driverList.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries); } + + public static void StartAndroidRemoteServer() + { + RENDERDOC_StartAndroidRemoteServer(); + } } } diff --git a/renderdocui/Windows/MainWindow.cs b/renderdocui/Windows/MainWindow.cs index 5cce9483b..38e4cc66a 100644 --- a/renderdocui/Windows/MainWindow.cs +++ b/renderdocui/Windows/MainWindow.cs @@ -1967,12 +1967,7 @@ namespace renderdocui.Windows private void startAndroidRemoteServerToolStripMenuItem_Click(object sender, EventArgs e) { - // /K to keep the window open after finishing. - // We want to see the output, e.g. to see if adb is on the path. - ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", "/K android_remoteserver.bat"); - - Process process = Process.Start(processInfo); - process.Close(); + StaticExports.StartAndroidRemoteServer(); } } } diff --git a/renderdocui/renderdocui.csproj b/renderdocui/renderdocui.csproj index f42315876..c21dd55c4 100644 --- a/renderdocui/renderdocui.csproj +++ b/renderdocui/renderdocui.csproj @@ -628,8 +628,8 @@ - copy $(SolutionDir)scripts\android_remoteserver.bat $(TargetDir) -copy $(SolutionDir)scripts\android_capture.bat $(TargetDir) + +