diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 13fa3fbd2..df9a5f584 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -1776,6 +1776,17 @@ void MainWindow::switchContext() // see if the server is up host->CheckStatus(); + if(host->IsADB() && !RENDERDOC_IsAndroidSupported(host->hostname.c_str())) + { + GUIInvoke::call(this, [this]() { + statusText->setText(tr("Device unsupported, Android 6.0 is required.")); + contextChooser->setIcon(Icons::disconnect()); + contextChooser->setText(tr("Replay Context: Local")); + contextChooser->setEnabled(true); + }); + return; + } + if(!host->serverRunning && !host->runCommand.isEmpty()) { GUIInvoke::call(this, [this]() { diff --git a/renderdoc/android/android.cpp b/renderdoc/android/android.cpp index ed68d83a3..96fb1ca72 100644 --- a/renderdoc/android/android.cpp +++ b/renderdoc/android/android.cpp @@ -587,6 +587,16 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_AndroidShutdown() Android::shutdownAdb(); } +extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_IsAndroidSupported(const char *device) +{ + int index = 0; + std::string deviceID; + + Android::ExtractDeviceIDAndIndex(device, index, deviceID); + + return Android::IsSupported(deviceID); +} + extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer(const char *device) { int index = 0; @@ -594,6 +604,9 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer(co Android::ExtractDeviceIDAndIndex(device, index, deviceID); + if(!Android::IsSupported(deviceID)) + return; + std::string packagesOutput = trim( Android::adbExecCommand(deviceID, "shell pm list packages " RENDERDOC_ANDROID_PACKAGE_BASE) .strStdout); diff --git a/renderdoc/android/android_utils.cpp b/renderdoc/android/android_utils.cpp index f0c217097..2829a7cde 100644 --- a/renderdoc/android/android_utils.cpp +++ b/renderdoc/android/android_utils.cpp @@ -131,6 +131,21 @@ std::string GetPathForPackage(const std::string &deviceID, const std::string &pa return pkgPath; } +bool IsSupported(std::string deviceID) +{ + std::string api = + trim(Android::adbExecCommand(deviceID, "shell getprop ro.build.version.sdk").strStdout); + + int apiVersion = atoi(api.c_str()); + + // SDK 23 == Android 6.0, our minimum spec. Only fail if we did parse an SDK string, in case some + // Android devices don't support the query - we assume they are new enough. + if(apiVersion >= 0 && apiVersion < 23) + return false; + + return true; +} + std::string GetFriendlyName(std::string deviceID) { auto it = friendlyNameCache.find(deviceID); @@ -153,6 +168,9 @@ std::string GetFriendlyName(std::string deviceID) else if(!manuf.empty() && !model.empty()) combined = manuf + " " + model; + if(!IsSupported(deviceID)) + combined += " - Unsupported"; + return combined; } }; \ No newline at end of file diff --git a/renderdoc/android/android_utils.h b/renderdoc/android/android_utils.h index bfba63716..26321b61c 100644 --- a/renderdoc/android/android_utils.h +++ b/renderdoc/android/android_utils.h @@ -49,6 +49,7 @@ bool toolExists(const std::string &path); std::string GetFirstMatchingLine(const std::string &haystack, const std::string &needle); +bool IsSupported(std::string deviceID); std::string GetFriendlyName(std::string deviceID); // supported ABIs diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 7bb7dcb5a..25e38786f 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -2141,6 +2141,9 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_AndroidInitialise(); DOCUMENT("Internal function for shutting down android use."); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_AndroidShutdown(); +DOCUMENT("Internal function for checking android support."); +extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_IsAndroidSupported(const char *device); + DOCUMENT("Internal function for starting an android remote server."); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer(const char *device);