Fix some mis-handling of single file URI. Fixes the Load... button.

This commit is contained in:
Henrik Rydgård 2021-08-07 12:17:31 +02:00
parent 43ba908225
commit ed7053329a
2 changed files with 47 additions and 24 deletions

View File

@ -4,6 +4,7 @@
#include "Common/StringUtils.h"
#include "Common/Net/URL.h"
#include "Common/Log.h"
// Utility to deal with Android storage URIs of the forms:
// content://com.android.externalstorage.documents/tree/primary%3APSP%20ISO
@ -39,12 +40,20 @@ public:
if (parts.size() == 3) {
// Single file URI.
provider = parts[0];
if (parts[1] != "tree") {
if (parts[1] == "tree") {
// Single directory URI.
// Not sure when we encounter these?
// file empty signals this type.
root = UriDecode(parts[2]);
return true;
} else if (parts[1] == "document") {
// root empty signals this type.
file = UriDecode(parts[2]);
return true;
} else {
// What's this?
return false;
}
root = UriDecode(parts[2]);
// file empty signals this type.
return true;
} else if (parts.size() == 5) {
// Tree URI
provider = parts[0];
@ -65,6 +74,11 @@ public:
}
AndroidContentURI WithRootFilePath(const std::string &filePath) {
if (root.empty()) {
ERROR_LOG(SYSTEM, "WithRootFilePath cannot be used with single file URIs.");
return *this;
}
AndroidContentURI uri = *this;
uri.file = uri.root;
if (!filePath.empty()) {
@ -106,11 +120,10 @@ public:
return uri;
}
bool IsTreeURI() const {
return file.empty();
}
bool CanNavigateUp() const {
if (root.empty()) {
return false;
}
return file.size() > root.size();
}
@ -145,7 +158,7 @@ public:
}
std::string GetLastPart() const {
if (IsTreeURI()) {
if (file.empty()) {
// Can't do anything anyway.
return std::string();
}
@ -182,7 +195,7 @@ public:
}
bool TreeContains(const AndroidContentURI &fileURI) {
if (!IsTreeURI()) {
if (root.empty()) {
return false;
}
return startsWith(fileURI.file, root);
@ -192,8 +205,11 @@ public:
if (file.empty()) {
// Tree URI
return StringFromFormat("content://%s/tree/%s", provider.c_str(), UriEncode(root).c_str());
} else if (root.empty()) {
// Single file URI
return StringFromFormat("content://%s/document/%s", provider.c_str(), UriEncode(file).c_str());
} else {
// File URI
// File URI from Tree
return StringFromFormat("content://%s/tree/%s/document/%s", provider.c_str(), UriEncode(root).c_str(), UriEncode(file).c_str());
}
}
@ -208,6 +224,6 @@ public:
}
const std::string &RootPath() const {
return root;
return root.empty() ? file : root;
}
};

View File

@ -622,33 +622,40 @@ static bool TestPath() {
static bool TestAndroidContentURI() {
static const char *treeURIString = "content://com.android.externalstorage.documents/tree/primary%3APSP%20ISO";
static const char *directoryURIString = "content://com.android.externalstorage.documents/tree/primary%3APSP%20ISO/document/primary%3APSP%20ISO";
static const char *fileURIString = "content://com.android.externalstorage.documents/tree/primary%3APSP%20ISO/document/primary%3APSP%20ISO%2FTekken%206.iso";
static const char *fileTreeURIString = "content://com.android.externalstorage.documents/tree/primary%3APSP%20ISO/document/primary%3APSP%20ISO%2FTekken%206.iso";
static const char *fileNonTreeString = "content://com.android.externalstorage.documents/document/primary%3APSP%2Fcrash_bad_execaddr.prx";
AndroidContentURI treeURI;
EXPECT_TRUE(treeURI.Parse(std::string(treeURIString)));
AndroidContentURI dirURI;
EXPECT_TRUE(dirURI.Parse(std::string(directoryURIString)));
AndroidContentURI fileTreeURI;
EXPECT_TRUE(fileTreeURI.Parse(std::string(fileTreeURIString)));
AndroidContentURI fileTreeURICopy;
EXPECT_TRUE(fileTreeURICopy.Parse(std::string(fileTreeURIString)));
AndroidContentURI fileURI;
EXPECT_TRUE(fileURI.Parse(std::string(fileURIString)));
EXPECT_TRUE(fileURI.Parse(std::string(fileNonTreeString)));
std::string lastPart = dirURI.GetLastPart();
EXPECT_EQ_STR(fileTreeURI.GetLastPart(), std::string("Tekken 6.iso"));
EXPECT_EQ_STR(fileURI.GetLastPart(), std::string("Tekken 6.iso"));
EXPECT_TRUE(treeURI.TreeContains(fileTreeURI));
EXPECT_TRUE(treeURI.TreeContains(fileURI));
EXPECT_TRUE(fileURI.CanNavigateUp());
fileURI.NavigateUp();
EXPECT_FALSE(fileURI.CanNavigateUp());
EXPECT_TRUE(fileTreeURI.CanNavigateUp());
fileTreeURI.NavigateUp();
EXPECT_FALSE(fileTreeURI.CanNavigateUp());
EXPECT_EQ_STR(fileURI.FilePath(), fileURI.RootPath());
EXPECT_EQ_STR(fileTreeURI.FilePath(), fileTreeURI.RootPath());
EXPECT_EQ_STR(fileURI.ToString(), std::string(directoryURIString));
EXPECT_EQ_STR(fileTreeURI.ToString(), std::string(directoryURIString));
std::string diff;
EXPECT_TRUE(dirURI.ComputePathTo(fileURI, diff));
EXPECT_TRUE(dirURI.ComputePathTo(fileTreeURICopy, diff));
EXPECT_EQ_STR(diff, std::string("Tekken 6.iso"));
EXPECT_EQ_STR(fileURI.GetFileExtension(), std::string(".prx"));
EXPECT_FALSE(fileURI.CanNavigateUp());
return true;
}