Avi Drissman | 4a8573c | 2022-09-09 19:35:54 | [diff] [blame] | 1 | // Copyright 2017 The Chromium Authors |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Yeunjoo Choi | ef8a4a4 | 2022-11-08 04:21:05 | [diff] [blame] | 5 | #ifndef CHROME_BROWSER_ASH_FILEAPI_RECENT_DISK_SOURCE_H_ |
| 6 | #define CHROME_BROWSER_ASH_FILEAPI_RECENT_DISK_SOURCE_H_ |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 7 | |
| 8 | #include <memory> |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 9 | #include <string> |
| 10 | #include <vector> |
| 11 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 12 | #include "base/containers/id_map.h" |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 13 | #include "base/files/file.h" |
| 14 | #include "base/files/file_path.h" |
| 15 | #include "base/gtest_prod_util.h" |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 16 | #include "base/memory/weak_ptr.h" |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 17 | #include "base/time/time.h" |
Bo Majewski | 3201191 | 2023-11-07 10:04:17 | [diff] [blame] | 18 | #include "chrome/browser/ash/fileapi/file_accumulator.h" |
Yeunjoo Choi | ef8a4a4 | 2022-11-08 04:21:05 | [diff] [blame] | 19 | #include "chrome/browser/ash/fileapi/recent_file.h" |
| 20 | #include "chrome/browser/ash/fileapi/recent_model.h" |
| 21 | #include "chrome/browser/ash/fileapi/recent_source.h" |
DongJun Kim | febb3c2 | 2019-10-21 02:08:06 | [diff] [blame] | 22 | #include "storage/browser/file_system/file_system_operation.h" |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 23 | |
Yeunjoo Choi | 3d9ed38a | 2022-11-10 02:51:24 | [diff] [blame] | 24 | namespace ash { |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 25 | |
| 26 | // RecentSource implementation for local disks. |
| 27 | // Used for Downloads and fuse-based Crostini. |
| 28 | // |
| 29 | // All member functions must be called on the UI thread. |
| 30 | class RecentDiskSource : public RecentSource { |
| 31 | public: |
Bo Majewski | a50b657 | 2023-11-15 00:03:26 | [diff] [blame] | 32 | // Create a RecentDiskSource for the volume registered to `mount_point_name`. |
| 33 | // Does nothing if no volume is registered at `mount_point_name`. |
| 34 | // If `ignore_dotfiles` is true, recents will ignore directories and files |
| 35 | // starting with a dot. Set `max_depth` to zero for unlimited depth. |
Bo Majewski | 6f33bc8 | 2024-05-28 02:24:00 | [diff] [blame] | 36 | RecentDiskSource( |
| 37 | extensions::api::file_manager_private::VolumeType volume_type, |
| 38 | std::string mount_point_name, |
| 39 | bool ignore_dotfiles, |
| 40 | int max_depth, |
| 41 | std::string uma_histogram_name); |
Peter Boström | 53c6c595 | 2021-09-17 09:41:26 | [diff] [blame] | 42 | |
| 43 | RecentDiskSource(const RecentDiskSource&) = delete; |
| 44 | RecentDiskSource& operator=(const RecentDiskSource&) = delete; |
| 45 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 46 | ~RecentDiskSource() override; |
| 47 | |
| 48 | // RecentSource overrides: |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 49 | void GetRecentFiles(const Params& params, |
| 50 | GetRecentFilesCallback callback) override; |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 51 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 52 | // Stops the recent files search. Returns any partial results already |
| 53 | // collected. |
| 54 | std::vector<RecentFile> Stop(const int32_t call_id) override; |
| 55 | |
Bo Majewski | 965f1c7 | 2023-02-06 01:51:44 | [diff] [blame] | 56 | // Helper function that determines a match between file type inferred from the |
| 57 | // path and the desired file_type. |
| 58 | static bool MatchesFileType(const base::FilePath& path, |
| 59 | RecentSource::FileType file_type); |
| 60 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 61 | private: |
| 62 | FRIEND_TEST_ALL_PREFIXES(RecentDiskSourceTest, GetRecentFiles_UmaStats); |
| 63 | |
| 64 | static const char kLoadHistogramName[]; |
| 65 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 66 | void ScanDirectory(const int32_t call_id, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 67 | const base::FilePath& path, |
| 68 | int depth); |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 69 | void OnReadDirectory(const int32_t call_id, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 70 | const base::FilePath& path, |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 71 | int depth, |
| 72 | base::File::Error result, |
| 73 | storage::FileSystemOperation::FileEntryList entries, |
| 74 | bool has_more); |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 75 | void OnGotMetadata(const int32_t call_id, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 76 | const storage::FileSystemURL& url, |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 77 | base::File::Error result, |
| 78 | const base::File::Info& info); |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 79 | void OnReadOrStatFinished(int32_t call_id); |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 80 | |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 81 | storage::FileSystemURL BuildDiskURL(const Params& params, |
| 82 | const base::FilePath& path) const; |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 83 | |
| 84 | const std::string mount_point_name_; |
| 85 | const bool ignore_dotfiles_; |
| 86 | const int max_depth_; |
| 87 | const std::string uma_histogram_name_; |
| 88 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 89 | // CallContext gather information for a single GetRecentFiles call. As |
| 90 | // GetRecentFiles call can take time, and some data is collected on IO thread, |
| 91 | // we cannot guarantee that two calls will not overlap. To solve this each |
| 92 | // call receives a unique call_id and its context is stored in the map. As the |
| 93 | // map is only accessed on the UI thread we do not need to use additional |
| 94 | // locks to guarantee its consistency. |
| 95 | struct CallContext { |
Bo Majewski | 3fbd2440 | 2024-05-16 01:06:14 | [diff] [blame] | 96 | CallContext(const Params& params, GetRecentFilesCallback callback); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 97 | // Move constructor; necessary as callback is a move-only type. |
| 98 | CallContext(CallContext&& context); |
| 99 | |
| 100 | ~CallContext(); |
| 101 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 102 | // The parameters of the GetRecentFiles call. |
| 103 | const Params params; |
| 104 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 105 | // The callback called when the files and their metadata is ready. |
| 106 | GetRecentFilesCallback callback; |
| 107 | // Time when the build started. |
| 108 | base::TimeTicks build_start_time; |
| 109 | // Number of ReadDirectory() calls in flight. |
| 110 | int inflight_readdirs = 0; |
| 111 | // Number of GetMetadata() calls in flight. |
| 112 | int inflight_stats = 0; |
| 113 | // Most recently modified files. |
| 114 | FileAccumulator accumulator; |
| 115 | }; |
| 116 | |
| 117 | // A map from call_id to the context of the call. |
| 118 | base::IDMap<std::unique_ptr<CallContext>> context_map_; |
| 119 | |
Jeremy Roman | 47d432e | 2019-08-20 14:24:00 | [diff] [blame] | 120 | base::WeakPtrFactory<RecentDiskSource> weak_ptr_factory_{this}; |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 121 | }; |
| 122 | |
Yeunjoo Choi | 3d9ed38a | 2022-11-10 02:51:24 | [diff] [blame] | 123 | } // namespace ash |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 124 | |
Yeunjoo Choi | ef8a4a4 | 2022-11-08 04:21:05 | [diff] [blame] | 125 | #endif // CHROME_BROWSER_ASH_FILEAPI_RECENT_DISK_SOURCE_H_ |