| 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 DocumentSpec = arc::FakeFileSystemInstance::DocumentSpec; |
| 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 |
| 31 struct DocumentSpec { | |
| 32 const char* document_id; | |
| 33 const char* display_name; | |
| 34 const char* mime_type; | |
| 35 int64_t size; | |
| 36 uint64_t last_modified; | |
| 37 }; | |
| 38 | |
| 39 // Fake file system hierarchy: | 33 // Fake file system hierarchy: |
| 40 // | 34 // |
| 41 // <path> <type> <ID> | 35 // <path> <type> <ID> |
| 42 // (root)/ dir root-id | 36 // (root)/ dir root-id |
| 43 // dir/ dir dir-id | 37 // dir/ dir dir-id |
| 44 // photo.jpg image/jpeg photo-id | 38 // photo.jpg image/jpeg photo-id |
| 45 // music.bin audio/mp3 music-id | 39 // music.bin audio/mp3 music-id |
| 46 // dups/ dir dups-id | 40 // dups/ dir dups-id |
| 47 // dup.mp4 video/mp4 dup1-id | 41 // dup.mp4 video/mp4 dup1-id |
| 48 // dup.mp4 video/mp4 dup2-id | 42 // dup.mp4 video/mp4 dup2-id |
| 49 // dup.mp4 video/mp4 dup3-id | 43 // dup.mp4 video/mp4 dup3-id |
| 50 // dup.mp4 video/mp4 dup4-id | 44 // dup.mp4 video/mp4 dup4-id |
| 51 constexpr char kAuthority[] = "org.chromium.test"; | 45 constexpr char kAuthority[] = "org.chromium.test"; |
| 52 // NOTE: ArcDocumentsProviderRoot::GetFileInfo() returns hard-coded info | 46 // NOTE: ArcDocumentsProviderRoot::GetFileInfo() returns hard-coded info |
| 53 // for root documents. | 47 // for root documents. |
| 54 constexpr DocumentSpec kRootSpec = {"root-id", nullptr /* not used */, | 48 constexpr DocumentSpec kRootSpec{ |
| 55 kAndroidDirectoryMimeType, -1, 0}; | 49 kAuthority, "root-id", nullptr, "", kAndroidDirectoryMimeType, -1, 0}; |
| 56 constexpr DocumentSpec kDirSpec = {"dir-id", "dir", kAndroidDirectoryMimeType, | 50 constexpr DocumentSpec kDirSpec{kAuthority, |
| 57 -1, 22}; | 51 "dir-id", |
| 58 constexpr DocumentSpec kPhotoSpec = {"photo-id", "photo.jpg", "image/jpeg", 3, | 52 kRootSpec.document_id, |
| 59 33}; | 53 "dir", |
| 60 constexpr DocumentSpec kMusicSpec = {"music-id", "music.bin", "audio/mp3", 4, | 54 kAndroidDirectoryMimeType, |
| 61 44}; | 55 -1, |
| 62 constexpr DocumentSpec kDupsSpec = {"dups-id", "dups", | 56 22}; |
| 63 kAndroidDirectoryMimeType, -1, 55}; | 57 constexpr DocumentSpec kPhotoSpec{ |
| 64 constexpr DocumentSpec kDup1Spec = {"dup1-id", "dup.mp4", "video/mp4", 6, 66}; | 58 kAuthority, "photo-id", kDirSpec.document_id, "photo.jpg", "image/jpeg", |
| 65 constexpr DocumentSpec kDup2Spec = {"dup2-id", "dup.mp4", "video/mp4", 7, 77}; | 59 3, 33}; |
| 66 constexpr DocumentSpec kDup3Spec = {"dup3-id", "dup.mp4", "video/mp4", 8, 88}; | 60 constexpr DocumentSpec kMusicSpec{ |
| 67 constexpr DocumentSpec kDup4Spec = {"dup4-id", "dup.mp4", "video/mp4", 9, 99}; | 61 kAuthority, "music-id", kDirSpec.document_id, "music.bin", "audio/mp3", |
| 62 4, 44}; |
| 63 constexpr DocumentSpec kDupsSpec{kAuthority, |
| 64 "dups-id", |
| 65 kRootSpec.document_id, |
| 66 "dups", |
| 67 kAndroidDirectoryMimeType, |
| 68 -1, |
| 69 55}; |
| 70 constexpr DocumentSpec kDup1Spec{kAuthority, "dup1-id", kDupsSpec.document_id, |
| 71 "dup.mp4", "video/mp4", 6, |
| 72 66}; |
| 73 constexpr DocumentSpec kDup2Spec{kAuthority, "dup2-id", kDupsSpec.document_id, |
| 74 "dup.mp4", "video/mp4", 7, |
| 75 77}; |
| 76 constexpr DocumentSpec kDup3Spec{kAuthority, "dup3-id", kDupsSpec.document_id, |
| 77 "dup.mp4", "video/mp4", 8, |
| 78 88}; |
| 79 constexpr DocumentSpec kDup4Spec{kAuthority, "dup4-id", kDupsSpec.document_id, |
| 80 "dup.mp4", "video/mp4", 9, |
| 81 99}; |
| 82 |
| 83 // The order is intentionally shuffled here so that |
| 84 // FileSystemInstance::GetChildDocuments() returns documents in shuffled order. |
| 85 // See ResolveToContentUrlDups test below. |
| 68 constexpr DocumentSpec kAllSpecs[] = {kRootSpec, kDirSpec, kPhotoSpec, | 86 constexpr DocumentSpec kAllSpecs[] = {kRootSpec, kDirSpec, kPhotoSpec, |
| 69 kMusicSpec, kDupsSpec, kDup1Spec, | 87 kMusicSpec, kDupsSpec, kDup2Spec, |
| 70 kDup2Spec, kDup3Spec, kDup4Spec}; | 88 kDup1Spec, kDup4Spec, kDup3Spec}; |
| 71 | |
| 72 mojom::DocumentPtr MakeDocument(const DocumentSpec& spec) { | |
| 73 mojom::DocumentPtr document = mojom::Document::New(); | |
| 74 document->document_id = spec.document_id; | |
| 75 document->display_name = spec.display_name; | |
| 76 document->mime_type = spec.mime_type; | |
| 77 document->size = spec.size; | |
| 78 document->last_modified = spec.last_modified; | |
| 79 return document; | |
| 80 } | |
| 81 | |
| 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 | 89 |
| 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 (strcmp(spec.mime_type, kAndroidDirectoryMimeType) == 0) { |
| 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(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 |