mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Split out some miscellaneous utility functions
* We also wrap up and cache the fetching of friendly names by serial number to avoid some adb traffic.
This commit is contained in:
@@ -91,6 +91,7 @@ set(sources
|
||||
core/replay_proxy.h
|
||||
android/android.cpp
|
||||
android/android_tools.cpp
|
||||
android/android_utils.cpp
|
||||
android/android.h
|
||||
android/android_utils.h
|
||||
core/plugins.cpp
|
||||
|
||||
@@ -43,36 +43,6 @@ static const char keystoreName[] = "renderdoc.keystore";
|
||||
|
||||
namespace Android
|
||||
{
|
||||
bool IsHostADB(const char *hostname)
|
||||
{
|
||||
return !strncmp(hostname, "adb:", 4);
|
||||
}
|
||||
void extractDeviceIDAndIndex(const string &hostname, int &index, string &deviceID)
|
||||
{
|
||||
if(!IsHostADB(hostname.c_str()))
|
||||
return;
|
||||
|
||||
const char *c = hostname.c_str();
|
||||
c += 4;
|
||||
|
||||
index = atoi(c);
|
||||
|
||||
c = strchr(c, ':');
|
||||
|
||||
if(!c)
|
||||
{
|
||||
index = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
c++;
|
||||
|
||||
deviceID = c;
|
||||
}
|
||||
string adbGetDeviceList()
|
||||
{
|
||||
return adbExecCommand("", "devices").strStdout;
|
||||
}
|
||||
void adbForwardPorts(int index, const std::string &deviceID)
|
||||
{
|
||||
const char *forwardCommand = "forward tcp:%i localabstract:renderdoc_%i";
|
||||
@@ -87,7 +57,7 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
|
||||
{
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
string packageName = basename(string(package)); // Remove leading '/' if any
|
||||
|
||||
@@ -121,20 +91,6 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SearchForAndroidLayer(const string &deviceID, const string &location, const string &layerName,
|
||||
string &foundLayer)
|
||||
{
|
||||
RDCLOG("Checking for layers in: %s", location.c_str());
|
||||
foundLayer =
|
||||
trim(adbExecCommand(deviceID, "shell find " + location + " -name " + layerName).strStdout);
|
||||
if(!foundLayer.empty())
|
||||
{
|
||||
RDCLOG("Found RenderDoc layer in %s", location.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RemoveAPKSignature(const string &apk)
|
||||
{
|
||||
RDCLOG("Checking for existing signature");
|
||||
@@ -558,9 +514,7 @@ bool CheckDebuggable(const string &apk)
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Android
|
||||
|
||||
using namespace Android;
|
||||
bool installRenderDocServer(const string &deviceID)
|
||||
{
|
||||
string targetApk = "RenderDocCmd.apk";
|
||||
@@ -765,30 +719,6 @@ bool CheckInstalledPermissions(const string &deviceID, const string &packageName
|
||||
return CheckPermissions(dump);
|
||||
}
|
||||
|
||||
bool CheckRootAccess(const string &deviceID)
|
||||
{
|
||||
RDCLOG("Checking for root access on %s", deviceID.c_str());
|
||||
|
||||
Process::ProcessResult result = {};
|
||||
|
||||
// Try switching adb to root and check a few indicators for success
|
||||
// Nothing will fall over if we get a false positive here, it just enables
|
||||
// additional methods of getting things set up.
|
||||
|
||||
result = adbExecCommand(deviceID, "root");
|
||||
|
||||
string whoami = trim(adbExecCommand(deviceID, "shell whoami").strStdout);
|
||||
if(whoami == "root")
|
||||
return true;
|
||||
|
||||
string checksu =
|
||||
trim(adbExecCommand(deviceID, "shell test -e /system/xbin/su && echo found").strStdout);
|
||||
if(checksu == "found")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string DetermineInstalledABI(const string &deviceID, const string &packageName)
|
||||
{
|
||||
RDCLOG("Checking installed ABI for %s", packageName.c_str());
|
||||
@@ -882,11 +812,13 @@ string FindAndroidLayer(const string &abi, const string &layerName)
|
||||
|
||||
return layer;
|
||||
}
|
||||
}; // namespace Android
|
||||
using namespace Android;
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(const rdcstr &device,
|
||||
rdcstr &friendly)
|
||||
{
|
||||
if(!IsHostADB(device.c_str()))
|
||||
if(!Android::IsHostADB(device.c_str()))
|
||||
{
|
||||
RDCERR("Calling RENDERDOC_GetAndroidFriendlyName with non-android device: %s", device.c_str());
|
||||
return;
|
||||
@@ -894,7 +826,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(cons
|
||||
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(device.c_str(), index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(device.c_str(), index, deviceID);
|
||||
|
||||
if(deviceID.empty())
|
||||
{
|
||||
@@ -902,29 +834,12 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(cons
|
||||
return;
|
||||
}
|
||||
|
||||
string manuf = trim(adbExecCommand(deviceID, "shell getprop ro.product.manufacturer").strStdout);
|
||||
string model = trim(adbExecCommand(deviceID, "shell getprop ro.product.model").strStdout);
|
||||
|
||||
std::string combined;
|
||||
|
||||
if(manuf.empty() && model.empty())
|
||||
combined = "";
|
||||
else if(manuf.empty() && !model.empty())
|
||||
combined = model;
|
||||
else if(!manuf.empty() && model.empty())
|
||||
combined = manuf + " device";
|
||||
else if(!manuf.empty() && !model.empty())
|
||||
combined = manuf + " " + model;
|
||||
|
||||
if(combined.empty())
|
||||
friendly = "";
|
||||
else
|
||||
friendly = combined;
|
||||
friendly = Android::GetFriendlyName(deviceID);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr *deviceList)
|
||||
{
|
||||
string adbStdout = adbGetDeviceList();
|
||||
string adbStdout = adbExecCommand("", "devices").strStdout;
|
||||
|
||||
int idx = 0;
|
||||
|
||||
@@ -958,7 +873,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer(co
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
|
||||
Android::extractDeviceIDAndIndex(device, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(device, index, deviceID);
|
||||
|
||||
string adbPackage =
|
||||
adbExecCommand(deviceID, "shell pm list packages org.renderdoc.renderdoccmd").strStdout;
|
||||
@@ -986,7 +901,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CheckAndroidPackage(const c
|
||||
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
// Find the path to package
|
||||
string pkgPath = trim(adbExecCommand(deviceID, "shell pm path " + packageName).strStdout);
|
||||
@@ -1003,11 +918,11 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CheckAndroidPackage(const c
|
||||
string layerPath = "";
|
||||
|
||||
// Check a debug location only usable by rooted devices, overriding app's layer
|
||||
if(SearchForAndroidLayer(deviceID, "/data/local/debug/vulkan", layerName, layerPath))
|
||||
if(SearchForAndroidLibrary(deviceID, "/data/local/debug/vulkan", layerName, layerPath))
|
||||
found = true;
|
||||
|
||||
// See if the application contains the layer
|
||||
if(!found && SearchForAndroidLayer(deviceID, pkgPath, layerName, layerPath))
|
||||
if(!found && SearchForAndroidLibrary(deviceID, pkgPath, layerName, layerPath))
|
||||
found = true;
|
||||
|
||||
// TODO: Add any future layer locations
|
||||
@@ -1055,7 +970,7 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_PushLayerToInstalledAndroid
|
||||
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
// Detect which ABI was installed on the device
|
||||
string abi = DetermineInstalledABI(deviceID, packageName);
|
||||
@@ -1080,7 +995,7 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_PushLayerToInstalledAndroid
|
||||
|
||||
// Ensure the push succeeded
|
||||
string foundLayer;
|
||||
return SearchForAndroidLayer(deviceID, layerDst, layerName, foundLayer);
|
||||
return SearchForAndroidLibrary(deviceID, layerDst, layerName, foundLayer);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(
|
||||
@@ -1091,7 +1006,7 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(
|
||||
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
// make sure progress is valid so we don't have to check it everywhere
|
||||
if(!progress)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Android
|
||||
{
|
||||
bool IsHostADB(const char *hostname);
|
||||
uint32_t StartAndroidPackageForCapture(const char *host, const char *package);
|
||||
void extractDeviceIDAndIndex(const std::string &hostname, int &index, std::string &deviceID);
|
||||
void ExtractDeviceIDAndIndex(const std::string &hostname, int &index, std::string &deviceID);
|
||||
Process::ProcessResult adbExecCommand(const std::string &deviceID, const std::string &args,
|
||||
const string &workDir = ".");
|
||||
};
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "android_utils.h"
|
||||
#include "core/core.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
static std::map<std::string, std::string> friendlyNameCache;
|
||||
|
||||
namespace Android
|
||||
{
|
||||
bool IsHostADB(const char *hostname)
|
||||
{
|
||||
return !strncmp(hostname, "adb:", 4);
|
||||
}
|
||||
|
||||
void ExtractDeviceIDAndIndex(const std::string &hostname, int &index, std::string &deviceID)
|
||||
{
|
||||
if(!IsHostADB(hostname.c_str()))
|
||||
return;
|
||||
|
||||
const char *c = hostname.c_str();
|
||||
c += 4;
|
||||
|
||||
index = atoi(c);
|
||||
|
||||
c = strchr(c, ':');
|
||||
|
||||
if(!c)
|
||||
{
|
||||
index = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
c++;
|
||||
|
||||
deviceID = c;
|
||||
}
|
||||
|
||||
bool CheckRootAccess(const std::string &deviceID)
|
||||
{
|
||||
RDCLOG("Checking for root access on %s", deviceID.c_str());
|
||||
|
||||
Process::ProcessResult result = {};
|
||||
|
||||
// Try switching adb to root and check a few indicators for success
|
||||
// Nothing will fall over if we get a false positive here, it just enables
|
||||
// additional methods of getting things set up.
|
||||
|
||||
result = adbExecCommand(deviceID, "root");
|
||||
|
||||
std::string whoami = trim(adbExecCommand(deviceID, "shell whoami").strStdout);
|
||||
if(whoami == "root")
|
||||
return true;
|
||||
|
||||
std::string checksu =
|
||||
trim(adbExecCommand(deviceID, "shell test -e /system/xbin/su && echo found").strStdout);
|
||||
if(checksu == "found")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SearchForAndroidLibrary(const std::string &deviceID, const std::string &location,
|
||||
const std::string &layerName, std::string &foundLayer)
|
||||
{
|
||||
RDCLOG("Checking for layers in: %s", location.c_str());
|
||||
foundLayer =
|
||||
trim(adbExecCommand(deviceID, "shell find " + location + " -name " + layerName).strStdout);
|
||||
if(!foundLayer.empty())
|
||||
{
|
||||
RDCLOG("Found RenderDoc layer in %s", location.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetFriendlyName(std::string deviceID)
|
||||
{
|
||||
auto it = friendlyNameCache.find(deviceID);
|
||||
if(it != friendlyNameCache.end())
|
||||
return it->second;
|
||||
|
||||
std::string manuf =
|
||||
trim(Android::adbExecCommand(deviceID, "shell getprop ro.product.manufacturer").strStdout);
|
||||
std::string model =
|
||||
trim(Android::adbExecCommand(deviceID, "shell getprop ro.product.model").strStdout);
|
||||
|
||||
std::string &combined = friendlyNameCache[deviceID];
|
||||
|
||||
if(manuf.empty() && model.empty())
|
||||
combined = "";
|
||||
else if(manuf.empty() && !model.empty())
|
||||
combined = model;
|
||||
else if(!manuf.empty() && model.empty())
|
||||
combined = manuf + " device";
|
||||
else if(!manuf.empty() && !model.empty())
|
||||
combined = manuf + " " + model;
|
||||
|
||||
return combined;
|
||||
}
|
||||
};
|
||||
@@ -46,4 +46,9 @@ enum class ToolDir
|
||||
};
|
||||
std::string getToolPath(ToolDir subdir, const std::string &toolname, bool checkExist);
|
||||
bool toolExists(const std::string &path);
|
||||
|
||||
std::string GetFriendlyName(std::string deviceID);
|
||||
bool CheckRootAccess(const std::string &deviceID);
|
||||
bool SearchForAndroidLibrary(const std::string &deviceID, const std::string &location,
|
||||
const std::string &layerName, std::string &foundLayer);
|
||||
};
|
||||
|
||||
@@ -1152,7 +1152,7 @@ public:
|
||||
{
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(m_hostname, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(m_hostname, index, deviceID);
|
||||
|
||||
string adbStdout = Android::adbExecCommand(deviceID, "shell pm list packages -3").strStdout;
|
||||
using namespace std;
|
||||
@@ -1770,7 +1770,7 @@ RENDERDOC_CreateRemoteServerConnection(const char *host, uint32_t port, IRemoteS
|
||||
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
// each subsequent device gets a new range of ports. The deviceID isn't needed since we
|
||||
// already
|
||||
|
||||
@@ -308,6 +308,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="android\android.cpp" />
|
||||
<ClCompile Include="android\android_tools.cpp" />
|
||||
<ClCompile Include="android\android_utils.cpp" />
|
||||
<ClCompile Include="common\common.cpp" />
|
||||
<ClCompile Include="common\dds_readwrite.cpp" />
|
||||
<ClCompile Include="core\core.cpp" />
|
||||
|
||||
@@ -659,6 +659,9 @@
|
||||
<ClCompile Include="android\android_tools.cpp">
|
||||
<Filter>Android</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="android\android_utils.cpp">
|
||||
<Filter>Android</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="os\win32\comexport.def">
|
||||
|
||||
@@ -369,7 +369,7 @@ extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteTargets(
|
||||
{
|
||||
int index = 0;
|
||||
std::string deviceID;
|
||||
Android::extractDeviceIDAndIndex(host, index, deviceID);
|
||||
Android::ExtractDeviceIDAndIndex(host, index, deviceID);
|
||||
|
||||
// each subsequent device gets a new range of ports. The deviceID isn't needed since we already
|
||||
// forwarded the ports to the right devices.
|
||||
|
||||
Reference in New Issue
Block a user