Commit 92e5f97f authored by Naoki Fukino's avatar Naoki Fukino Committed by Commit Bot

Fix Android path to request media scan for removable media.

In Android, a removable media labelled as "UNTITLED" is mounted
at /storage/removable_UNTITLED instead of /storage/UNTITLED.
This behavior change was made by ag/6513597, but Chrome side
didn't follow the changed paths.

*Example*
CrOS path: /removable/media/UNTITLED/foo.jpg
Wrong path to request media scan (today's behavior): /storage/UNTITLED/foo.jpg
Correct path to request media scan: /storage/removable_UNTITLED/foo.jpg

This CL alters the path in Chrome side, since Android side
can't tell if the requested path is on a removable device or not.

Bug: 1000163
Test: Manually tested on Kevin.
Change-Id: I318735135900ed47f144bff13a51965b0bcb0ee0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1787620
Commit-Queue: Naoki Fukino <fukino@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#694192}
parent bcc95498
......@@ -66,6 +66,11 @@ constexpr base::FilePath::CharType kCrosRemovableMediaDir[] =
constexpr base::FilePath::CharType kAndroidRemovableMediaDir[] =
FILE_PATH_LITERAL("/storage");
// The prefix for device label used in Android paths for removable media.
// A removable device mounted at /media/removable/UNTITLED is mounted at
// /storage/removable_UNTITLED in Android.
constexpr char kRemovableMediaLabelPrefix[] = "removable_";
// How long to wait for new inotify events before building the updated timestamp
// map.
const base::TimeDelta kBuildTimestampMapDelay =
......@@ -126,7 +131,11 @@ TimestampMap BuildTimestampMap(base::FilePath cros_dir,
// Android file path can be obtained by replacing |cros_dir|
// prefix with |android_dir|.
base::FilePath android_path(android_dir);
cros_dir.AppendRelativePath(cros_path, &android_path);
if (cros_dir.value() == kCrosRemovableMediaDir) {
AppendRelativePathForRemovableMedia(cros_path, &android_path);
} else {
cros_dir.AppendRelativePath(cros_path, &android_path);
}
const base::FileEnumerator::FileInfo& info = enumerator.GetInfo();
timestamp_map[android_path] = info.GetLastModifiedTime();
}
......@@ -251,6 +260,35 @@ bool HasAndroidSupportedMediaExtension(const base::FilePath& path) {
extension.c_str(), less_comparator);
}
bool AppendRelativePathForRemovableMedia(const base::FilePath& cros_path,
base::FilePath* android_path) {
std::vector<base::FilePath::StringType> parent_components;
base::FilePath(kCrosRemovableMediaDir).GetComponents(&parent_components);
std::vector<base::FilePath::StringType> child_components;
cros_path.GetComponents(&child_components);
auto child_itr = child_components.begin();
for (const auto& parent_component : parent_components) {
if (child_itr == child_components.end() || parent_component != *child_itr) {
LOG(WARNING) << "|cros_path| is not under kCrosRemovableMediaDir.";
return false;
}
++child_itr;
}
if (child_itr == child_components.end()) {
LOG(WARNING) << "The CrOS path doesn't have a component for device label.";
return false;
}
// The device label (e.g. "UNTITLED" for /media/removable/UNTITLED/foo.jpg)
// should be converted to removable_UNTITLED, since the prefix "removable_"
// is appended to paths for removable media in Android.
*android_path = android_path->Append(kRemovableMediaLabelPrefix + *child_itr);
++child_itr;
for (; child_itr != child_components.end(); ++child_itr) {
*android_path = android_path->Append(*child_itr);
}
return true;
}
// The core part of ArcFileSystemWatcherService to watch for file changes in
// directory.
class ArcFileSystemWatcherService::FileSystemWatcher {
......
......@@ -32,6 +32,12 @@ class ArcBridgeService;
// Returns true if the file path has a media extension supported by Android.
bool HasAndroidSupportedMediaExtension(const base::FilePath& path);
// Appends |cros_path|'s relative path from "/media/removable" to |android_path|
// with the altered device label which is used in Android removable media paths.
// Exposed only for testing.
bool AppendRelativePathForRemovableMedia(const base::FilePath& cros_path,
base::FilePath* android_path);
// Exposed only for testing.
extern const char* kAndroidSupportedMediaExtensions[];
extern const int kAndroidSupportedMediaExtensionsSize;
......
......@@ -50,4 +50,39 @@ TEST(ArcFileSystemWatcherServiceTest, HasAndroidSupportedMediaExtension) {
base::FilePath(FILE_PATH_LITERAL("/tmp/kitten"))));
}
TEST(ArcFileSystemWatcherServiceTest, AppendRelativePathForRemovableMedia) {
base::FilePath android_path(FILE_PATH_LITERAL("/storage"));
EXPECT_TRUE(AppendRelativePathForRemovableMedia(
base::FilePath(FILE_PATH_LITERAL("/media/removable/UNTITLED/foo.jpg")),
&android_path));
EXPECT_EQ("/storage/removable_UNTITLED/foo.jpg", android_path.value());
android_path = base::FilePath(FILE_PATH_LITERAL("/storage"));
EXPECT_TRUE(AppendRelativePathForRemovableMedia(
base::FilePath(
FILE_PATH_LITERAL("/media/removable/UNTITLED/foo/bar/baz.mp4")),
&android_path));
EXPECT_EQ("/storage/removable_UNTITLED/foo/bar/baz.mp4",
android_path.value());
android_path = base::FilePath(FILE_PATH_LITERAL("/"));
EXPECT_TRUE(AppendRelativePathForRemovableMedia(
base::FilePath(FILE_PATH_LITERAL("/media/removable/UNTITLED/foo.jpg")),
&android_path));
EXPECT_EQ("/removable_UNTITLED/foo.jpg", android_path.value());
// Error: |cros_path| is not under /media/removable.
android_path = base::FilePath(FILE_PATH_LITERAL("/storage"));
EXPECT_FALSE(AppendRelativePathForRemovableMedia(
base::FilePath(FILE_PATH_LITERAL("/foo/bar/UNTITLED/foo.jpg")),
&android_path));
EXPECT_EQ("/storage", android_path.value());
// Error: |cros_path| does not contain a component for device label.
android_path = base::FilePath(FILE_PATH_LITERAL("/storage"));
EXPECT_FALSE(AppendRelativePathForRemovableMedia(
base::FilePath(FILE_PATH_LITERAL("/media/removable")), &android_path));
EXPECT_EQ("/storage", android_path.value());
}
} // namespace arc
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment