diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp
index ac990400c..0671d2d79 100644
--- a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp
+++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp
@@ -467,7 +467,6 @@ void CaptureDialog::androidWarn_mouseClick()
msg +=
tr("Missing permissions
"
"The target APK must have the following permissions:
"
- "android.permission.WRITE_EXTERNAL_STORAGE
"
"android.permission.INTERNET
");
}
diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h
index 93de7fd83..36d3bf26e 100644
--- a/renderdoc/api/replay/replay_enums.h
+++ b/renderdoc/api/replay/replay_enums.h
@@ -3319,7 +3319,6 @@ DOCUMENT(R"(A set of flags giving details of the current status of Android traca
The application being checked does not have the requesite permission:
- android.permission.WRITE_EXTERNAL_STORAGE
android.permission.INTERNET
.. data:: NotDebuggable
diff --git a/renderdoc/core/android.cpp b/renderdoc/core/android.cpp
index 648f01bb1..260c940e4 100644
--- a/renderdoc/core/android.cpp
+++ b/renderdoc/core/android.cpp
@@ -133,12 +133,6 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
adbExecCommand(deviceID, "shell am force-stop " + packageName);
adbForwardPorts(index, deviceID);
adbExecCommand(deviceID, "shell setprop debug.vulkan.layers VK_LAYER_RENDERDOC_Capture");
- // Creating the capture file
- adbExecCommand(deviceID,
- "shell pm grant " + packageName + " android.permission.WRITE_EXTERNAL_STORAGE");
- // Reading the capture thumbnail
- adbExecCommand(deviceID,
- "shell pm grant " + packageName + " android.permission.READ_EXTERNAL_STORAGE");
adbExecCommand(deviceID,
"shell monkey -p " + packageName + " -c android.intent.category.LAUNCHER 1");
@@ -438,12 +432,6 @@ bool PullAPK(const string &deviceID, const string &pkgPath, const string &apk)
bool CheckPermissions(const string &dump)
{
- if(dump.find("android.permission.WRITE_EXTERNAL_STORAGE") == string::npos)
- {
- RDCWARN("APK missing WRITE_EXTERNAL_STORAGE permission");
- return false;
- }
-
if(dump.find("android.permission.INTERNET") == string::npos)
{
RDCWARN("APK missing INTERNET permission");
diff --git a/renderdoc/os/posix/android/android_stringio.cpp b/renderdoc/os/posix/android/android_stringio.cpp
index 4d28c7efa..471dc4a25 100644
--- a/renderdoc/os/posix/android/android_stringio.cpp
+++ b/renderdoc/os/posix/android/android_stringio.cpp
@@ -56,9 +56,15 @@ bool GetKeyState(int key)
namespace FileIO
{
-const char *GetTempRootPath()
+string GetTempRootPath()
{
- return "/sdcard";
+ // Save captures in the app's private /sdcard directory, which doesnt require
+ // WRITE_EXTERNAL_STORAGE permissions. There is no security enforced here,
+ // so the replay server can load it as it has READ_EXTERNAL_STORAGE.
+ // This is the same as returned by getExternalFilesDir(). It might possibly change in the future.
+ string package;
+ GetExecutableFilename(package);
+ return "/sdcard/Android/data/" + package + "/files";
}
string GetAppFolderFilename(const string &filename)
diff --git a/renderdoc/os/posix/apple/apple_stringio.cpp b/renderdoc/os/posix/apple/apple_stringio.cpp
index 4b00186e9..6ab51eaa3 100644
--- a/renderdoc/os/posix/apple/apple_stringio.cpp
+++ b/renderdoc/os/posix/apple/apple_stringio.cpp
@@ -57,7 +57,7 @@ bool GetKeyState(int key)
namespace FileIO
{
-const char *GetTempRootPath()
+string GetTempRootPath()
{
return "/tmp";
}
diff --git a/renderdoc/os/posix/linux/linux_stringio.cpp b/renderdoc/os/posix/linux/linux_stringio.cpp
index 0948bcbe2..f865f0ddb 100644
--- a/renderdoc/os/posix/linux/linux_stringio.cpp
+++ b/renderdoc/os/posix/linux/linux_stringio.cpp
@@ -253,7 +253,7 @@ bool GetKeyState(int key)
namespace FileIO
{
-const char *GetTempRootPath()
+string GetTempRootPath()
{
return "/tmp";
}
diff --git a/renderdoc/os/posix/posix_stringio.cpp b/renderdoc/os/posix/posix_stringio.cpp
index eceea0253..ae508ac8c 100644
--- a/renderdoc/os/posix/posix_stringio.cpp
+++ b/renderdoc/os/posix/posix_stringio.cpp
@@ -49,7 +49,7 @@ static int soLocator = 0;
namespace FileIO
{
// in posix/.../..._stringio.cpp
-const char *GetTempRootPath();
+string GetTempRootPath();
string GetHomeFolderFilename()
{
@@ -61,7 +61,7 @@ string GetHomeFolderFilename()
string GetTempFolderFilename()
{
- return string(GetTempRootPath()) + "/";
+ return GetTempRootPath() + "/";
}
void CreateParentDirectory(const string &filename)
@@ -202,7 +202,7 @@ void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &
char temp_folder[2048] = {0};
- strcpy(temp_folder, GetTempRootPath());
+ strcpy(temp_folder, GetTempRootPath().c_str());
char *temp_override = getenv("RENDERDOC_TEMP");
if(temp_override && temp_override[0] == '/')