mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 17:40:39 +00:00
Add version checking to Android workflow
* Tag the RenderDoc layer with a version string that matches the host, including git hash. * In developer builds, check the version when scanning the application for RenderDoc support. * Pass the warning back to the UI to offer ways to fix. * Update APK patching to remove existing layer.
This commit is contained in:
committed by
Baldur Karlsson
parent
03a0a06f60
commit
82f4e82155
@@ -430,8 +430,9 @@ void CaptureDialog::CheckAndroidSetup(QString &filename)
|
||||
|
||||
const bool missingLibrary = bool(m_AndroidFlags & AndroidFlags::MissingLibrary);
|
||||
const bool missingPermissions = bool(m_AndroidFlags & AndroidFlags::MissingPermissions);
|
||||
const bool wrongLayerVersion = bool(m_AndroidFlags & AndroidFlags::WrongLayerVersion);
|
||||
|
||||
if(missingLibrary || missingPermissions)
|
||||
if(missingLibrary || missingPermissions || wrongLayerVersion)
|
||||
{
|
||||
// Check failed - set the warning visible
|
||||
GUIInvoke::call([this]() {
|
||||
@@ -463,6 +464,7 @@ void CaptureDialog::androidWarn_mouseClick()
|
||||
|
||||
bool missingPermissions = bool(m_AndroidFlags & AndroidFlags::MissingPermissions);
|
||||
bool missingLibrary = bool(m_AndroidFlags & AndroidFlags::MissingLibrary);
|
||||
bool wrongLayerVersion = bool(m_AndroidFlags & AndroidFlags::WrongLayerVersion);
|
||||
bool rootAccess = bool(m_AndroidFlags & AndroidFlags::RootAccess);
|
||||
|
||||
if(missingPermissions)
|
||||
@@ -481,6 +483,14 @@ void CaptureDialog::androidWarn_mouseClick()
|
||||
"installed application.<br><br>");
|
||||
}
|
||||
|
||||
if(wrongLayerVersion)
|
||||
{
|
||||
msg +=
|
||||
tr("<b>Wrong layer version</b><br>"
|
||||
"The RenderDoc library was found, but its version "
|
||||
"does not match that of the host.<br><br>");
|
||||
}
|
||||
|
||||
if(missingPermissions)
|
||||
{
|
||||
// Don't prompt for patching if permissions are wrong - we can't fix that
|
||||
|
||||
@@ -3508,6 +3508,10 @@ DOCUMENT(R"(A set of flags giving details of the current status of Android traca
|
||||
|
||||
The application is not debuggable.
|
||||
|
||||
.. data:: WrongLayerVersion
|
||||
|
||||
The found RenderDoc layer does not match the server's version.
|
||||
|
||||
.. data:: RootAccess
|
||||
|
||||
The device being targeted has root access.
|
||||
@@ -3522,8 +3526,9 @@ enum class AndroidFlags : uint32_t
|
||||
MissingLibrary = 0x1,
|
||||
MissingPermissions = 0x2,
|
||||
NotDebuggable = 0x4,
|
||||
RootAccess = 0x8,
|
||||
Unfixable = 0x10,
|
||||
WrongLayerVersion = 0x8,
|
||||
RootAccess = 0x10,
|
||||
Unfixable = 0x20,
|
||||
};
|
||||
|
||||
BITMASK_OPERATORS(AndroidFlags);
|
||||
|
||||
+93
-10
@@ -28,6 +28,9 @@
|
||||
#include "core/core.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
extern "C" RENDERDOC_API const char RENDERDOC_Version_Tag_String[] =
|
||||
"RenderDoc_build_version: " FULL_VERSION_STRING " from git commit " GIT_COMMIT_HASH;
|
||||
|
||||
namespace Android
|
||||
{
|
||||
enum class ToolDir
|
||||
@@ -376,12 +379,13 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SearchForAndroidLayer(const string &deviceID, const string &location, const string &layerName)
|
||||
bool SearchForAndroidLayer(const string &deviceID, const string &location, const string &layerName,
|
||||
string &foundLayer)
|
||||
{
|
||||
RDCLOG("Checking for layers in: %s", location.c_str());
|
||||
string findLayer =
|
||||
adbExecCommand(deviceID, "shell find " + location + " -name " + layerName).strStdout;
|
||||
if(!findLayer.empty())
|
||||
foundLayer =
|
||||
trim(adbExecCommand(deviceID, "shell find " + location + " -name " + layerName).strStdout);
|
||||
if(!foundLayer.empty())
|
||||
{
|
||||
RDCLOG("Found RenderDoc layer in %s", location.c_str());
|
||||
return true;
|
||||
@@ -444,6 +448,29 @@ bool AddLayerToAPK(const string &apk, const string &layerPath, const string &lay
|
||||
// Run aapt from the directory containing "lib" so the relative paths are good
|
||||
string relativeLayer("lib/" + abi + "/" + layerName);
|
||||
string workDir = removeFromEnd(layerPath, relativeLayer);
|
||||
|
||||
// If the layer was already present in the APK, we need to remove it first
|
||||
Process::ProcessResult contents = execCommand(aapt, "list \"" + apk + "\"", workDir);
|
||||
if(contents.strStdout.empty())
|
||||
{
|
||||
RDCERR("Failed to list contents of APK. STDERR: %s", contents.strStderror.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(contents.strStdout.find(relativeLayer) != std::string::npos)
|
||||
{
|
||||
RDCLOG("Removing existing layer from APK before trying to add");
|
||||
Process::ProcessResult remove =
|
||||
execCommand(aapt, "remove \"" + apk + "\" " + relativeLayer, workDir);
|
||||
|
||||
if(!remove.strStdout.empty())
|
||||
{
|
||||
RDCERR("Failed to remove existing layer from APK. STDERR: %s", remove.strStderror.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the RenderDoc layer
|
||||
Process::ProcessResult result = execCommand(aapt, "add \"" + apk + "\" " + relativeLayer, workDir);
|
||||
|
||||
if(result.strStdout.empty())
|
||||
@@ -708,6 +735,49 @@ bool PullAPK(const string &deviceID, const string &pkgPath, const string &apk)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckLayerVersion(const string &deviceID, const string &layerName, const string &remoteLayer)
|
||||
{
|
||||
RDCDEBUG("Checking layer version of: %s", layerName.c_str());
|
||||
|
||||
bool match = false;
|
||||
|
||||
// Use 'strings' command on the device to find the layer's build version
|
||||
// i.e. strings -n <tag length> <layer> | grep <tag marker>
|
||||
// Subtract 5 to provide a bit of wiggle room on version length
|
||||
Process::ProcessResult result = adbExecCommand(
|
||||
deviceID, "shell strings -n " +
|
||||
StringFormat::Fmt("%u", strlen(RENDERDOC_Version_Tag_String) - 5) + " " +
|
||||
remoteLayer + " | grep RenderDoc_build_version");
|
||||
|
||||
string line = trim(result.strStdout);
|
||||
|
||||
if(line.empty())
|
||||
{
|
||||
RDCLOG("RenderDoc layer is not versioned, so cannot be checked for compatibility.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<string> vec;
|
||||
split(line, vec, ' ');
|
||||
string version = vec[1];
|
||||
string hash = vec[5];
|
||||
|
||||
if(version == FULL_VERSION_STRING && hash == GIT_COMMIT_HASH)
|
||||
{
|
||||
RDCLOG("RenderDoc layer version (%s) and git hash (%s) match.", version.c_str(), hash.c_str());
|
||||
match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG(
|
||||
"RenderDoc layer version (%s) and git hash (%s) do NOT match the host version (%s) or git "
|
||||
"hash (%s).",
|
||||
version.c_str(), hash.c_str(), FULL_VERSION_STRING, GIT_COMMIT_HASH);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
bool CheckPermissions(const string &dump)
|
||||
{
|
||||
// TODO: remove this if we are sure that there are no permissions to check.
|
||||
@@ -1188,18 +1258,30 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CheckAndroidPackage(const c
|
||||
*flags = AndroidFlags::NoFlags;
|
||||
|
||||
bool found = false;
|
||||
string layerPath = "";
|
||||
|
||||
// First, see if the application contains the layer
|
||||
if(SearchForAndroidLayer(deviceID, pkgPath, layerName))
|
||||
// Check a debug location only usable by rooted devices, overriding app's layer
|
||||
if(SearchForAndroidLayer(deviceID, "/data/local/debug/vulkan", layerName, layerPath))
|
||||
found = true;
|
||||
|
||||
// Next, check a debug location only usable by rooted devices
|
||||
if(!found && SearchForAndroidLayer(deviceID, "/data/local/debug/vulkan", layerName))
|
||||
// See if the application contains the layer
|
||||
if(!found && SearchForAndroidLayer(deviceID, pkgPath, layerName, layerPath))
|
||||
found = true;
|
||||
|
||||
// TODO: Add any future layer locations
|
||||
|
||||
if(!found)
|
||||
if(found)
|
||||
{
|
||||
#if ENABLED(RDOC_DEVEL)
|
||||
// Check the version of the layer found
|
||||
if(!CheckLayerVersion(deviceID, layerName, layerPath))
|
||||
{
|
||||
RDCWARN("RenderDoc layer found, but version does not match");
|
||||
*flags |= AndroidFlags::WrongLayerVersion;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("No RenderDoc layer for Vulkan or GLES was found");
|
||||
*flags |= AndroidFlags::MissingLibrary;
|
||||
@@ -1255,7 +1337,8 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_PushLayerToInstalledAndroid
|
||||
result = adbExecCommand(deviceID, "push " + layerPath + " " + layerDst);
|
||||
|
||||
// Ensure the push succeeded
|
||||
return SearchForAndroidLayer(deviceID, layerDst, layerName);
|
||||
string foundLayer;
|
||||
return SearchForAndroidLayer(deviceID, layerDst, layerName, foundLayer);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(const char *host,
|
||||
|
||||
Reference in New Issue
Block a user