Skip to content

Commit

Permalink
Merge pull request #17466 from hrydgard/android-fix-load-from-downloads
Browse files Browse the repository at this point in the history
Fix running some file formats from the Downloads folder
  • Loading branch information
hrydgard committed May 16, 2023
2 parents 6deddbb + 444897a commit 6bdb721
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
36 changes: 30 additions & 6 deletions Common/File/AndroidContentURI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ AndroidContentURI AndroidContentURI::WithRootFilePath(const std::string &filePat

AndroidContentURI AndroidContentURI::WithComponent(const std::string &filePath) {
AndroidContentURI uri = *this;
uri.file = uri.file + "/" + filePath;
if (uri.file.empty()) {
// Not sure what to do.
return uri;
}
if (uri.file.back() == ':') {
// Special case handling for Document URIs: Treat the ':' as a directory separator too (but preserved in the filename).
uri.file = uri.file + filePath;
} else {
uri.file = uri.file + "/" + filePath;
}
return uri;
}

Expand Down Expand Up @@ -94,10 +103,11 @@ AndroidContentURI AndroidContentURI::WithReplacedExtension(const std::string &ne
}

bool AndroidContentURI::CanNavigateUp() const {
if (root.empty()) {
return false;
if (IsTreeURI()) {
return file.size() > root.size();
} else {
return file.find(':') != std::string::npos && file.back() != ':';
}
return file.size() > root.size();
}

// Only goes downwards in hierarchies. No ".." will ever be generated.
Expand Down Expand Up @@ -141,12 +151,20 @@ std::string AndroidContentURI::GetLastPart() const {
if (colon == std::string::npos) {
return std::string();
}
if (file.back() == ':') {
return file;
}
return file.substr(colon + 1);
}

size_t slash = file.rfind('/');
if (slash == std::string::npos) {
return std::string();
// ok, look for the final colon. If it's the last char, we would have been caught above in !CanNavigateUp.
size_t colon = file.rfind(':');
if (colon == std::string::npos) {
return std::string();
}
return file.substr(colon + 1);
}

std::string part = file.substr(slash + 1);
Expand All @@ -160,7 +178,13 @@ bool AndroidContentURI::NavigateUp() {

size_t slash = file.rfind('/');
if (slash == std::string::npos) {
return false;
// ok, look for the final colon.
size_t colon = file.rfind(':');
if (colon == std::string::npos) {
return false;
}
file = file.substr(0, colon + 1); // Note: we include the colon in these paths.
return true;
}

file = file.substr(0, slash);
Expand Down
4 changes: 4 additions & 0 deletions Common/File/AndroidContentURI.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ class AndroidContentURI {
const std::string &RootPath() const {
return root.empty() ? file : root;
}

bool IsTreeURI() const {
return !root.empty();
}
};
14 changes: 10 additions & 4 deletions unittest/UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,14 +722,20 @@ static bool TestAndroidContentURI() {
EXPECT_EQ_STR(diff, std::string("Tekken 6.iso"));

EXPECT_EQ_STR(fileURI.GetFileExtension(), std::string(".prx"));
EXPECT_FALSE(fileURI.CanNavigateUp());
EXPECT_TRUE(fileURI.CanNavigateUp()); // Can now virtually navigate up one step from these.

// These are annoying because they hide the actual filename, and we can't get at a parent folder,
// which confuses our elf loading.
// These are annoying because they hide the actual filename, and we can't get at a parent folder.
// Decided to handle the ':' as a directory separator for navigation purposes, which fixes the problem (though not the extension thing).
AndroidContentURI downloadURI;
EXPECT_TRUE(downloadURI.Parse(std::string(downloadURIString)));
EXPECT_EQ_STR(downloadURI.GetLastPart(), std::string("10000000006"));
EXPECT_FALSE(downloadURI.CanNavigateUp());
EXPECT_TRUE(downloadURI.CanNavigateUp());
EXPECT_TRUE(downloadURI.NavigateUp());
// While this is not an openable valid content URI, we can still get something that we can concatenate a filename on top of.
EXPECT_EQ_STR(downloadURI.ToString(), std::string("content://com.android.providers.downloads.documents/document/msf%3A"));
EXPECT_EQ_STR(downloadURI.GetLastPart(), std::string("msf:"));
downloadURI = downloadURI.WithComponent("myfile");
EXPECT_EQ_STR(downloadURI.ToString(), std::string("content://com.android.providers.downloads.documents/document/msf%3Amyfile"));
return true;
}

Expand Down

0 comments on commit 6bdb721

Please sign in to comment.