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:
baldurk
2018-01-26 16:30:16 +00:00
parent 1be3e8bfac
commit 5527c57e68
9 changed files with 151 additions and 103 deletions
+1
View File
@@ -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
+14 -99
View File
@@ -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)
+1 -1
View File
@@ -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 = ".");
};
+123
View File
@@ -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;
}
};
+5
View File
@@ -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);
};
+2 -2
View File
@@ -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
+1
View File
@@ -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" />
+3
View File
@@ -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">
+1 -1
View File
@@ -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.