OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string.h> | 5 #include <string.h> |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
14 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" | 14 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" |
15 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" | 15 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" |
| 16 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h
" |
16 #include "components/arc/arc_bridge_service.h" | 17 #include "components/arc/arc_bridge_service.h" |
17 #include "components/arc/arc_service_manager.h" | 18 #include "components/arc/arc_service_manager.h" |
18 #include "components/arc/file_system/test/fake_arc_file_system_operation_runner.
h" | 19 #include "components/arc/test/fake_file_system_instance.h" |
19 #include "content/public/test/test_browser_thread_bundle.h" | 20 #include "content/public/test/test_browser_thread_bundle.h" |
20 #include "storage/common/fileapi/directory_entry.h" | 21 #include "storage/common/fileapi/directory_entry.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "url/gurl.h" | 23 #include "url/gurl.h" |
23 | 24 |
24 using storage::DirectoryEntry; | 25 using storage::DirectoryEntry; |
| 26 using Document = arc::FakeFileSystemInstance::Document; |
25 using EntryList = storage::AsyncFileUtil::EntryList; | 27 using EntryList = storage::AsyncFileUtil::EntryList; |
26 | 28 |
27 namespace arc { | 29 namespace arc { |
28 | 30 |
29 namespace { | 31 namespace { |
30 | 32 |
| 33 // Simliar as FakeFileSystemInstance::Document, but all fields are primitives |
| 34 // so that values can be constexpr. |
31 struct DocumentSpec { | 35 struct DocumentSpec { |
32 const char* document_id; | 36 const char* document_id; |
| 37 const char* parent_document_id; |
33 const char* display_name; | 38 const char* display_name; |
34 const char* mime_type; | 39 const char* mime_type; |
35 int64_t size; | 40 int64_t size; |
36 uint64_t last_modified; | 41 uint64_t last_modified; |
37 }; | 42 }; |
38 | 43 |
39 // Fake file system hierarchy: | 44 // Fake file system hierarchy: |
40 // | 45 // |
41 // <path> <type> <ID> | 46 // <path> <type> <ID> |
42 // (root)/ dir root-id | 47 // (root)/ dir root-id |
43 // dir/ dir dir-id | 48 // dir/ dir dir-id |
44 // photo.jpg image/jpeg photo-id | 49 // photo.jpg image/jpeg photo-id |
45 // music.bin audio/mp3 music-id | 50 // music.bin audio/mp3 music-id |
46 // dups/ dir dups-id | 51 // dups/ dir dups-id |
47 // dup.mp4 video/mp4 dup1-id | 52 // dup.mp4 video/mp4 dup1-id |
48 // dup.mp4 video/mp4 dup2-id | 53 // dup.mp4 video/mp4 dup2-id |
49 // dup.mp4 video/mp4 dup3-id | 54 // dup.mp4 video/mp4 dup3-id |
50 // dup.mp4 video/mp4 dup4-id | 55 // dup.mp4 video/mp4 dup4-id |
51 constexpr char kAuthority[] = "org.chromium.test"; | 56 constexpr char kAuthority[] = "org.chromium.test"; |
52 // NOTE: ArcDocumentsProviderRoot::GetFileInfo() returns hard-coded info | 57 constexpr DocumentSpec kRootSpec{"root-id", "", "", kAndroidDirectoryMimeType, |
53 // for root documents. | 58 -1, 0}; |
54 constexpr DocumentSpec kRootSpec = {"root-id", nullptr /* not used */, | 59 constexpr DocumentSpec kDirSpec{ |
55 kAndroidDirectoryMimeType, -1, 0}; | 60 "dir-id", kRootSpec.document_id, "dir", kAndroidDirectoryMimeType, -1, 22}; |
56 constexpr DocumentSpec kDirSpec = {"dir-id", "dir", kAndroidDirectoryMimeType, | 61 constexpr DocumentSpec kPhotoSpec{ |
57 -1, 22}; | 62 "photo-id", kDirSpec.document_id, "photo.jpg", "image/jpeg", 3, 33}; |
58 constexpr DocumentSpec kPhotoSpec = {"photo-id", "photo.jpg", "image/jpeg", 3, | 63 constexpr DocumentSpec kMusicSpec{ |
59 33}; | 64 "music-id", kDirSpec.document_id, "music.bin", "audio/mp3", 4, 44}; |
60 constexpr DocumentSpec kMusicSpec = {"music-id", "music.bin", "audio/mp3", 4, | 65 constexpr DocumentSpec kDupsSpec{"dups-id", kRootSpec.document_id, |
61 44}; | 66 "dups", kAndroidDirectoryMimeType, |
62 constexpr DocumentSpec kDupsSpec = {"dups-id", "dups", | 67 -1, 55}; |
63 kAndroidDirectoryMimeType, -1, 55}; | 68 constexpr DocumentSpec kDup1Spec{ |
64 constexpr DocumentSpec kDup1Spec = {"dup1-id", "dup.mp4", "video/mp4", 6, 66}; | 69 "dup1-id", kDupsSpec.document_id, "dup.mp4", "video/mp4", 6, 66}; |
65 constexpr DocumentSpec kDup2Spec = {"dup2-id", "dup.mp4", "video/mp4", 7, 77}; | 70 constexpr DocumentSpec kDup2Spec{ |
66 constexpr DocumentSpec kDup3Spec = {"dup3-id", "dup.mp4", "video/mp4", 8, 88}; | 71 "dup2-id", kDupsSpec.document_id, "dup.mp4", "video/mp4", 7, 77}; |
67 constexpr DocumentSpec kDup4Spec = {"dup4-id", "dup.mp4", "video/mp4", 9, 99}; | 72 constexpr DocumentSpec kDup3Spec{ |
| 73 "dup3-id", kDupsSpec.document_id, "dup.mp4", "video/mp4", 8, 88}; |
| 74 constexpr DocumentSpec kDup4Spec{ |
| 75 "dup4-id", kDupsSpec.document_id, "dup.mp4", "video/mp4", 9, 99}; |
| 76 |
| 77 // The order is intentionally shuffled here so that |
| 78 // FileSystemInstance::GetChildDocuments() returns documents in shuffled order. |
| 79 // See ResolveToContentUrlDups test below. |
68 constexpr DocumentSpec kAllSpecs[] = {kRootSpec, kDirSpec, kPhotoSpec, | 80 constexpr DocumentSpec kAllSpecs[] = {kRootSpec, kDirSpec, kPhotoSpec, |
69 kMusicSpec, kDupsSpec, kDup1Spec, | 81 kMusicSpec, kDupsSpec, kDup2Spec, |
70 kDup2Spec, kDup3Spec, kDup4Spec}; | 82 kDup1Spec, kDup4Spec, kDup3Spec}; |
71 | 83 |
72 mojom::DocumentPtr MakeDocument(const DocumentSpec& spec) { | 84 Document ToDocument(const DocumentSpec& spec) { |
73 mojom::DocumentPtr document = mojom::Document::New(); | 85 return Document(kAuthority, spec.document_id, spec.parent_document_id, |
74 document->document_id = spec.document_id; | 86 spec.display_name, spec.mime_type, spec.size, |
75 document->display_name = spec.display_name; | 87 spec.last_modified); |
76 document->mime_type = spec.mime_type; | |
77 document->size = spec.size; | |
78 document->last_modified = spec.last_modified; | |
79 return document; | |
80 } | 88 } |
81 | 89 |
82 // TODO(crbug.com/683049): Use a generic FakeArcFileSystemOperationRunner. | |
83 class ArcFileSystemOperationRunnerForTest | |
84 : public FakeArcFileSystemOperationRunner { | |
85 public: | |
86 explicit ArcFileSystemOperationRunnerForTest(ArcBridgeService* bridge_service) | |
87 : FakeArcFileSystemOperationRunner(bridge_service) {} | |
88 ~ArcFileSystemOperationRunnerForTest() override = default; | |
89 | |
90 void GetChildDocuments(const std::string& authority, | |
91 const std::string& document_id, | |
92 const GetChildDocumentsCallback& callback) override { | |
93 EXPECT_EQ(kAuthority, authority); | |
94 base::Optional<std::vector<mojom::DocumentPtr>> result; | |
95 if (document_id == kRootSpec.document_id) { | |
96 result.emplace(); | |
97 result.value().emplace_back(MakeDocument(kDirSpec)); | |
98 result.value().emplace_back(MakeDocument(kDupsSpec)); | |
99 } else if (document_id == kDirSpec.document_id) { | |
100 result.emplace(); | |
101 result.value().emplace_back(MakeDocument(kPhotoSpec)); | |
102 result.value().emplace_back(MakeDocument(kMusicSpec)); | |
103 } else if (document_id == kDupsSpec.document_id) { | |
104 result.emplace(); | |
105 // The order is intentionally shuffled. | |
106 result.value().emplace_back(MakeDocument(kDup2Spec)); | |
107 result.value().emplace_back(MakeDocument(kDup1Spec)); | |
108 result.value().emplace_back(MakeDocument(kDup4Spec)); | |
109 result.value().emplace_back(MakeDocument(kDup3Spec)); | |
110 } | |
111 callback.Run(std::move(result)); | |
112 } | |
113 | |
114 void GetDocument(const std::string& authority, | |
115 const std::string& document_id, | |
116 const GetDocumentCallback& callback) override { | |
117 EXPECT_EQ(kAuthority, authority); | |
118 mojom::DocumentPtr result; | |
119 for (const auto& spec : kAllSpecs) { | |
120 if (document_id == spec.document_id) { | |
121 result = MakeDocument(spec); | |
122 break; | |
123 } | |
124 } | |
125 callback.Run(std::move(result)); | |
126 } | |
127 }; | |
128 | |
129 void ExpectMatchesSpec(const base::File::Info& info, const DocumentSpec& spec) { | 90 void ExpectMatchesSpec(const base::File::Info& info, const DocumentSpec& spec) { |
130 EXPECT_EQ(spec.size, info.size); | 91 EXPECT_EQ(spec.size, info.size); |
131 if (strcmp(spec.mime_type, kAndroidDirectoryMimeType) == 0) { | 92 if (spec.mime_type == kAndroidDirectoryMimeType) { |
132 EXPECT_TRUE(info.is_directory); | 93 EXPECT_TRUE(info.is_directory); |
133 } else { | 94 } else { |
134 EXPECT_FALSE(info.is_directory); | 95 EXPECT_FALSE(info.is_directory); |
135 } | 96 } |
136 EXPECT_FALSE(info.is_symbolic_link); | 97 EXPECT_FALSE(info.is_symbolic_link); |
137 EXPECT_EQ(spec.last_modified, | 98 EXPECT_EQ(spec.last_modified, |
138 static_cast<uint64_t>(info.last_modified.ToJavaTime())); | 99 static_cast<uint64_t>(info.last_modified.ToJavaTime())); |
139 EXPECT_EQ(spec.last_modified, | 100 EXPECT_EQ(spec.last_modified, |
140 static_cast<uint64_t>(info.last_accessed.ToJavaTime())); | 101 static_cast<uint64_t>(info.last_accessed.ToJavaTime())); |
141 EXPECT_EQ(spec.last_modified, | 102 EXPECT_EQ(spec.last_modified, |
142 static_cast<uint64_t>(info.creation_time.ToJavaTime())); | 103 static_cast<uint64_t>(info.creation_time.ToJavaTime())); |
143 } | 104 } |
144 | 105 |
145 class ArcDocumentsProviderRootTest : public testing::Test { | 106 class ArcDocumentsProviderRootTest : public testing::Test { |
146 public: | 107 public: |
147 ArcDocumentsProviderRootTest() | 108 ArcDocumentsProviderRootTest() = default; |
148 : arc_service_manager_(base::MakeUnique<ArcServiceManager>(nullptr)), | 109 ~ArcDocumentsProviderRootTest() override = default; |
149 root_( | 110 |
150 base::MakeUnique<ArcDocumentsProviderRoot>(kAuthority, | 111 void SetUp() override { |
151 kRootSpec.document_id)) { | 112 for (auto spec : kAllSpecs) { |
| 113 fake_file_system_.AddDocument(ToDocument(spec)); |
| 114 } |
| 115 |
| 116 arc_service_manager_ = base::MakeUnique<ArcServiceManager>(nullptr); |
152 arc_service_manager_->AddService( | 117 arc_service_manager_->AddService( |
153 base::MakeUnique<ArcFileSystemOperationRunnerForTest>( | 118 ArcFileSystemOperationRunner::CreateForTesting( |
154 arc_service_manager_->arc_bridge_service())); | 119 arc_service_manager_->arc_bridge_service())); |
| 120 arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( |
| 121 &fake_file_system_); |
| 122 |
| 123 root_ = base::MakeUnique<ArcDocumentsProviderRoot>(kAuthority, |
| 124 kRootSpec.document_id); |
155 } | 125 } |
156 | 126 |
157 ~ArcDocumentsProviderRootTest() override = default; | |
158 | |
159 protected: | 127 protected: |
160 content::TestBrowserThreadBundle thread_bundle_; | 128 content::TestBrowserThreadBundle thread_bundle_; |
| 129 FakeFileSystemInstance fake_file_system_; |
161 std::unique_ptr<ArcServiceManager> arc_service_manager_; | 130 std::unique_ptr<ArcServiceManager> arc_service_manager_; |
162 std::unique_ptr<ArcDocumentsProviderRoot> root_; | 131 std::unique_ptr<ArcDocumentsProviderRoot> root_; |
163 | 132 |
164 private: | 133 private: |
165 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRootTest); | 134 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRootTest); |
166 }; | 135 }; |
167 | 136 |
168 } // namespace | 137 } // namespace |
169 | 138 |
170 TEST_F(ArcDocumentsProviderRootTest, GetFileInfo) { | 139 TEST_F(ArcDocumentsProviderRootTest, GetFileInfo) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 | 264 |
296 TEST_F(ArcDocumentsProviderRootTest, ReadDirectoryDups) { | 265 TEST_F(ArcDocumentsProviderRootTest, ReadDirectoryDups) { |
297 base::RunLoop run_loop; | 266 base::RunLoop run_loop; |
298 root_->ReadDirectory( | 267 root_->ReadDirectory( |
299 base::FilePath(FILE_PATH_LITERAL("dups")), | 268 base::FilePath(FILE_PATH_LITERAL("dups")), |
300 base::Bind( | 269 base::Bind( |
301 [](base::RunLoop* run_loop, base::File::Error error, | 270 [](base::RunLoop* run_loop, base::File::Error error, |
302 const EntryList& file_list, bool has_more) { | 271 const EntryList& file_list, bool has_more) { |
303 EXPECT_EQ(base::File::FILE_OK, error); | 272 EXPECT_EQ(base::File::FILE_OK, error); |
304 ASSERT_EQ(4u, file_list.size()); | 273 ASSERT_EQ(4u, file_list.size()); |
305 // FiIles are sorted lexicographically. | 274 // Files are sorted lexicographically. |
306 EXPECT_EQ(FILE_PATH_LITERAL("dup (1).mp4"), file_list[0].name); | 275 EXPECT_EQ(FILE_PATH_LITERAL("dup (1).mp4"), file_list[0].name); |
307 EXPECT_FALSE(file_list[0].is_directory); | 276 EXPECT_FALSE(file_list[0].is_directory); |
308 EXPECT_EQ(FILE_PATH_LITERAL("dup (2).mp4"), file_list[1].name); | 277 EXPECT_EQ(FILE_PATH_LITERAL("dup (2).mp4"), file_list[1].name); |
309 EXPECT_FALSE(file_list[1].is_directory); | 278 EXPECT_FALSE(file_list[1].is_directory); |
310 EXPECT_EQ(FILE_PATH_LITERAL("dup (3).mp4"), file_list[2].name); | 279 EXPECT_EQ(FILE_PATH_LITERAL("dup (3).mp4"), file_list[2].name); |
311 EXPECT_FALSE(file_list[2].is_directory); | 280 EXPECT_FALSE(file_list[2].is_directory); |
312 EXPECT_EQ(FILE_PATH_LITERAL("dup.mp4"), file_list[3].name); | 281 EXPECT_EQ(FILE_PATH_LITERAL("dup.mp4"), file_list[3].name); |
313 EXPECT_FALSE(file_list[3].is_directory); | 282 EXPECT_FALSE(file_list[3].is_directory); |
314 EXPECT_FALSE(has_more); | 283 EXPECT_FALSE(has_more); |
315 run_loop->Quit(); | 284 run_loop->Quit(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 [](base::RunLoop* run_loop, const GURL& url) { | 337 [](base::RunLoop* run_loop, const GURL& url) { |
369 EXPECT_EQ(GURL("content://org.chromium.test/document/dup3-id"), | 338 EXPECT_EQ(GURL("content://org.chromium.test/document/dup3-id"), |
370 url); | 339 url); |
371 run_loop->Quit(); | 340 run_loop->Quit(); |
372 }, | 341 }, |
373 &run_loop)); | 342 &run_loop)); |
374 run_loop.Run(); | 343 run_loop.Run(); |
375 } | 344 } |
376 | 345 |
377 } // namespace arc | 346 } // namespace arc |
OLD | NEW |