summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author “riyaghai” <riyaghai@google.com> 2024-12-02 08:43:09 +0000
committer Riya Ghai <riyaghai@google.com> 2024-12-03 17:00:19 +0000
commitc5b74085376aae52052c27c9518eb47d37cf0b73 (patch)
treec908b922a2c1e4fc97cbcd730c32b4c96686aabc
parent3177b994cc9e8ef626c337eab5b51961b6de9b3b (diff)
Modify FuseDaemon#DeriveVolumeName to better handle invalid paths.
Test: atest FuseUtilsTest.cpp Bug: 378021978 Flag: EXEMPT, bug fix Change-Id: I66c05397a1350c3fd1af52218f803e1202ed9b3d
-rw-r--r--jni/FuseDaemon.cpp24
-rw-r--r--jni/FuseUtils.cpp20
-rw-r--r--jni/FuseUtilsTest.cpp14
-rw-r--r--jni/include/libfuse_jni/FuseUtils.h9
4 files changed, 50 insertions, 17 deletions
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index e77fe5705..2a2e6310f 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -124,11 +124,6 @@ const std::regex PATTERN_BPF_BACKING_PATH("^/storage/[^/]+/[0-9]+/Android/(data|
static constexpr char TRANSFORM_SYNTHETIC_DIR[] = "synthetic";
static constexpr char TRANSFORM_TRANSCODE_DIR[] = "transcode";
-static constexpr char PRIMARY_VOLUME_PREFIX[] = "/storage/emulated";
-static constexpr char STORAGE_PREFIX[] = "/storage";
-
-static constexpr char VOLUME_INTERNAL[] = "internal";
-static constexpr char VOLUME_EXTERNAL_PRIMARY[] = "external_primary";
static constexpr char OWNERSHIP_RELATION[] = "ownership";
@@ -282,7 +277,7 @@ struct fuse {
inline bool IsRoot(const node* node) const { return node == root; }
inline string GetEffectiveRootPath() {
- if (android::base::StartsWith(path, PRIMARY_VOLUME_PREFIX)) {
+ if (android::base::StartsWith(path, mediaprovider::fuse::PRIMARY_VOLUME_PREFIX)) {
return path + "/" + MY_USER_ID_STRING;
}
return path;
@@ -356,7 +351,7 @@ struct fuse {
return false;
}
- if (!android::base::StartsWithIgnoreCase(path, PRIMARY_VOLUME_PREFIX)) {
+ if (!android::base::StartsWithIgnoreCase(path, mediaprovider::fuse::PRIMARY_VOLUME_PREFIX)) {
// Uncached path config applies only to primary volumes.
return false;
}
@@ -2639,7 +2634,7 @@ void FuseDaemon::SetupLevelDbInstances() {
// Setup leveldb instance for both external primary and internal volume.
fuse->level_db_mutex.lock();
// Create level db instance for internal volume
- SetupLevelDbConnection(VOLUME_INTERNAL);
+ SetupLevelDbConnection(mediaprovider::fuse::VOLUME_INTERNAL);
// Create level db instance for external primary volume
SetupLevelDbConnection(VOLUME_EXTERNAL_PRIMARY);
// Create level db instance to store owner id to owner package name and vice versa relation
@@ -2657,16 +2652,11 @@ void FuseDaemon::SetupPublicVolumeLevelDbInstance(const std::string& volume_name
}
std::string deriveVolumeName(const std::string& path) {
- std::string volume_name;
- if (!android::base::StartsWith(path, STORAGE_PREFIX)) {
- volume_name = VOLUME_INTERNAL;
- } else if (android::base::StartsWith(path, PRIMARY_VOLUME_PREFIX)) {
- volume_name = VOLUME_EXTERNAL_PRIMARY;
+ std::string volume_name = mediaprovider::fuse::getVolumeNameFromPath(path);
+ if (volume_name.empty()) {
+ LOG(ERROR) << "Invalid input URI for extracting volume name." << path;
} else {
- // Return "C58E-1702" from the path like "/storage/C58E-1702/Download/1935694997673.png"
- volume_name = path.substr(9, 9);
- // Convert to lowercase
- std::transform(volume_name.begin(), volume_name.end(), volume_name.begin(), ::tolower);
+ LOG(DEBUG) << "Volume name from input path: " << path << " , volName: " + volume_name;
}
return volume_name;
}
diff --git a/jni/FuseUtils.cpp b/jni/FuseUtils.cpp
index 7b0816488..a74b56033 100644
--- a/jni/FuseUtils.cpp
+++ b/jni/FuseUtils.cpp
@@ -16,6 +16,7 @@
#include "include/libfuse_jni/FuseUtils.h"
+#include <regex>
#include <string>
#include <vector>
@@ -51,5 +52,24 @@ bool containsMount(const string& path) {
android::base::EqualsIgnoreCase(path_suffix, obb_suffix);
}
+string getVolumeNameFromPath(const std::string& path) {
+ std::string volume_name = "";
+ if (!android::base::StartsWith(path, STORAGE_PREFIX)) {
+ volume_name = VOLUME_INTERNAL;
+ } else if (android::base::StartsWith(path, PRIMARY_VOLUME_PREFIX) || path == STORAGE_PREFIX) {
+ volume_name = VOLUME_EXTERNAL_PRIMARY;
+ } else {
+ // Use regex to extract volume name
+ std::regex volumeRegex(R"(/storage/([a-zA-Z0-9-]+)/)");
+ std::smatch match;
+ if (std::regex_search(path, match, volumeRegex)) {
+ volume_name = match[1].str();
+ // Convert to lowercase
+ std::transform(volume_name.begin(), volume_name.end(), volume_name.begin(), ::tolower);
+ }
+ }
+ return volume_name;
+}
+
} // namespace fuse
} // namespace mediaprovider
diff --git a/jni/FuseUtilsTest.cpp b/jni/FuseUtilsTest.cpp
index d76a89c6f..a1b03e0c2 100644
--- a/jni/FuseUtilsTest.cpp
+++ b/jni/FuseUtilsTest.cpp
@@ -59,4 +59,18 @@ TEST(FuseUtilsTest, testContainsMount_isFalseForPathWithAdditionalSlash) {
EXPECT_FALSE(containsMount("/storage/emulated/1234//Android/data"));
}
+TEST(FuseUtilsTest, getVolumeNameFromPath) {
+ EXPECT_EQ(getVolumeNameFromPath("/storage/emulated/0/Pictures"), VOLUME_EXTERNAL_PRIMARY);
+ EXPECT_EQ(getVolumeNameFromPath("/storage/emulated/0/DCIM"), VOLUME_EXTERNAL_PRIMARY);
+ EXPECT_EQ(getVolumeNameFromPath("/storage/emulated/0/"), VOLUME_EXTERNAL_PRIMARY);
+ EXPECT_EQ(getVolumeNameFromPath("/storage/emulated/0"), VOLUME_EXTERNAL_PRIMARY);
+ EXPECT_EQ(getVolumeNameFromPath("/storage/1234-5678/Music"), "1234-5678");
+ EXPECT_EQ(getVolumeNameFromPath("/storage/ABCD-EFGH/Movies"), "abcd-efgh");
+ EXPECT_EQ(getVolumeNameFromPath("/storage/AB12-E34g/Movies"), "ab12-e34g");
+ EXPECT_EQ(getVolumeNameFromPath("/storage/"), "");
+ EXPECT_EQ(getVolumeNameFromPath("/storage"), VOLUME_EXTERNAL_PRIMARY);
+ EXPECT_EQ(getVolumeNameFromPath("/data/media/0/"), VOLUME_INTERNAL);
+ EXPECT_EQ(getVolumeNameFromPath("/data/user_de/0/com.example.app/"), VOLUME_INTERNAL);
+}
+
} // namespace mediaprovider::fuse
diff --git a/jni/include/libfuse_jni/FuseUtils.h b/jni/include/libfuse_jni/FuseUtils.h
index 0e350995e..11f880f7a 100644
--- a/jni/include/libfuse_jni/FuseUtils.h
+++ b/jni/include/libfuse_jni/FuseUtils.h
@@ -21,6 +21,10 @@
namespace mediaprovider {
namespace fuse {
+static constexpr char STORAGE_PREFIX[] = "/storage";
+static constexpr char VOLUME_INTERNAL[] = "internal";
+static constexpr char VOLUME_EXTERNAL_PRIMARY[] = "external_primary";
+static constexpr char PRIMARY_VOLUME_PREFIX[] = "/storage/emulated";
/**
* Returns true if the given path (ignoring case) is mounted for any
@@ -31,6 +35,11 @@ namespace fuse {
*/
bool containsMount(const std::string& path);
+/**
+ * Returns the volume name extracted from a given path.
+ */
+std::string getVolumeNameFromPath(const std::string& path);
+
} // namespace fuse
} // namespace mediaprovider