Avi Drissman | 4a8573c | 2022-09-09 19:35:54 | [diff] [blame] | 1 | // Copyright 2017 The Chromium Authors |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [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 | #include "chrome/browser/ash/fileapi/recent_disk_source.h" |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 6 | |
| 7 | #include <utility> |
| 8 | |
| 9 | #include "base/files/file_path.h" |
Avi Drissman | 02e49e58 | 2023-01-07 01:23:18 | [diff] [blame] | 10 | #include "base/functional/bind.h" |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 11 | #include "base/metrics/histogram_functions.h" |
| 12 | #include "base/strings/string_util.h" |
Bo Majewski | d5190897 | 2023-10-30 04:40:01 | [diff] [blame] | 13 | #include "base/strings/utf_string_conversions.h" |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 14 | #include "base/time/time.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 15 | #include "content/public/browser/browser_task_traits.h" |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 16 | #include "content/public/browser/browser_thread.h" |
Naoki Fukino | 14a30c26 | 2020-01-21 10:39:32 | [diff] [blame] | 17 | #include "net/base/mime_util.h" |
DongJun Kim | febb3c2 | 2019-10-21 02:08:06 | [diff] [blame] | 18 | #include "storage/browser/file_system/external_mount_points.h" |
| 19 | #include "storage/browser/file_system/file_system_context.h" |
| 20 | #include "storage/browser/file_system/file_system_operation.h" |
| 21 | #include "storage/browser/file_system/file_system_operation_runner.h" |
| 22 | #include "storage/browser/file_system/file_system_url.h" |
Kyra Seevers | c5cba52c | 2021-08-20 16:31:27 | [diff] [blame] | 23 | #include "third_party/blink/public/common/storage_key/storage_key.h" |
Wenbo Jie | 055062ff | 2022-03-01 06:05:58 | [diff] [blame] | 24 | #include "ui/file_manager/file_types_data.h" |
Md. Hasanur Rashid | 7093fad0 | 2020-02-06 03:53:23 | [diff] [blame] | 25 | #include "url/origin.h" |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 26 | |
| 27 | using content::BrowserThread; |
| 28 | |
Yeunjoo Choi | 3d9ed38a | 2022-11-10 02:51:24 | [diff] [blame] | 29 | namespace ash { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 30 | |
| 31 | namespace { |
| 32 | |
Naoki Fukino | 14a30c26 | 2020-01-21 10:39:32 | [diff] [blame] | 33 | constexpr char kAudioMimeType[] = "audio/*"; |
| 34 | constexpr char kImageMimeType[] = "image/*"; |
| 35 | constexpr char kVideoMimeType[] = "video/*"; |
| 36 | |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 37 | void OnReadDirectoryOnIOThread( |
| 38 | const storage::FileSystemOperation::ReadDirectoryCallback& callback, |
| 39 | base::File::Error result, |
tzik | a40b440 | 2017-08-28 14:46:12 | [diff] [blame] | 40 | storage::FileSystemOperation::FileEntryList entries, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 41 | bool has_more) { |
| 42 | DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 43 | |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 44 | content::GetUIThreadTaskRunner({})->PostTask( |
| 45 | FROM_HERE, |
tzik | a40b440 | 2017-08-28 14:46:12 | [diff] [blame] | 46 | base::BindOnce(callback, result, std::move(entries), has_more)); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | void ReadDirectoryOnIOThread( |
| 50 | scoped_refptr<storage::FileSystemContext> file_system_context, |
| 51 | const storage::FileSystemURL& url, |
| 52 | const storage::FileSystemOperation::ReadDirectoryCallback& callback) { |
| 53 | DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 54 | |
| 55 | file_system_context->operation_runner()->ReadDirectory( |
tzik | a40b440 | 2017-08-28 14:46:12 | [diff] [blame] | 56 | url, base::BindRepeating(&OnReadDirectoryOnIOThread, callback)); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | void OnGetMetadataOnIOThread( |
Marijn Kruisselbrink | 94893f7 | 2018-10-01 23:36:04 | [diff] [blame] | 60 | storage::FileSystemOperation::GetMetadataCallback callback, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 61 | base::File::Error result, |
| 62 | const base::File::Info& info) { |
| 63 | DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 64 | |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 65 | content::GetUIThreadTaskRunner({})->PostTask( |
| 66 | FROM_HERE, base::BindOnce(std::move(callback), result, info)); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 67 | } |
| 68 | |
| 69 | void GetMetadataOnIOThread( |
| 70 | scoped_refptr<storage::FileSystemContext> file_system_context, |
| 71 | const storage::FileSystemURL& url, |
Nigel Tao | aa2cf6a | 2023-12-03 23:07:14 | [diff] [blame] | 72 | storage::FileSystemOperation::GetMetadataFieldSet fields, |
Marijn Kruisselbrink | 94893f7 | 2018-10-01 23:36:04 | [diff] [blame] | 73 | storage::FileSystemOperation::GetMetadataCallback callback) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 74 | DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 75 | |
| 76 | file_system_context->operation_runner()->GetMetadata( |
Marijn Kruisselbrink | 94893f7 | 2018-10-01 23:36:04 | [diff] [blame] | 77 | url, fields, |
| 78 | base::BindOnce(&OnGetMetadataOnIOThread, std::move(callback))); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | } // namespace |
| 82 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 83 | RecentDiskSource::RecentDiskSource::CallContext::CallContext( |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 84 | const Params& params, |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 85 | GetRecentFilesCallback callback) |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 86 | : params(params), |
| 87 | callback(std::move(callback)), |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 88 | build_start_time(base::TimeTicks::Now()), |
Bo Majewski | 3fbd2440 | 2024-05-16 01:06:14 | [diff] [blame] | 89 | accumulator(params.max_files()) {} |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 90 | |
| 91 | RecentDiskSource::RecentDiskSource::CallContext::CallContext( |
| 92 | CallContext&& context) |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 93 | : params(context.params), |
| 94 | callback(std::move(context.callback)), |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 95 | build_start_time(context.build_start_time), |
| 96 | inflight_readdirs(context.inflight_readdirs), |
| 97 | inflight_stats(context.inflight_stats), |
| 98 | accumulator(std::move(context.accumulator)) {} |
| 99 | |
| 100 | RecentDiskSource::RecentDiskSource::CallContext::~CallContext() = default; |
| 101 | |
Bo Majewski | 6f33bc8 | 2024-05-28 02:24:00 | [diff] [blame] | 102 | RecentDiskSource::RecentDiskSource( |
| 103 | extensions::api::file_manager_private::VolumeType volume_type, |
| 104 | std::string mount_point_name, |
| 105 | bool ignore_dotfiles, |
| 106 | int max_depth, |
| 107 | std::string uma_histogram_name) |
| 108 | : RecentSource(volume_type), |
| 109 | mount_point_name_(std::move(mount_point_name)), |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 110 | ignore_dotfiles_(ignore_dotfiles), |
| 111 | max_depth_(max_depth), |
Bo Majewski | 3fbd2440 | 2024-05-16 01:06:14 | [diff] [blame] | 112 | uma_histogram_name_(std::move(uma_histogram_name)) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 113 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 114 | } |
| 115 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 116 | RecentDiskSource::~RecentDiskSource() { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 117 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 118 | } |
| 119 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 120 | void RecentDiskSource::GetRecentFiles(const Params& params, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 121 | GetRecentFilesCallback callback) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 122 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 123 | DCHECK(context_map_.Lookup(params.call_id()) == nullptr); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 124 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 125 | // Return immediately if mount point does not exist. |
| 126 | storage::ExternalMountPoints* mount_points = |
| 127 | storage::ExternalMountPoints::GetSystemInstance(); |
| 128 | base::FilePath path; |
| 129 | if (!mount_points->GetRegisteredPath(mount_point_name_, &path)) { |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 130 | std::move(callback).Run({}); |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 131 | return; |
| 132 | } |
| 133 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 134 | // Create a unique context for this call. |
Bo Majewski | 3fbd2440 | 2024-05-16 01:06:14 | [diff] [blame] | 135 | auto context = std::make_unique<CallContext>(params, std::move(callback)); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 136 | context_map_.AddWithID(std::move(context), params.call_id()); |
Shuhei Takahashi | 1c79df0 | 2017-08-17 08:07:30 | [diff] [blame] | 137 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 138 | ScanDirectory(params.call_id(), base::FilePath(), 1); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 139 | } |
| 140 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 141 | std::vector<RecentFile> RecentDiskSource::Stop(const int32_t call_id) { |
| 142 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 143 | CallContext* context = context_map_.Lookup(call_id); |
| 144 | if (context == nullptr) { |
| 145 | // The Stop method was called after we already responded. Just return empty |
| 146 | // list of files. |
| 147 | return {}; |
| 148 | } |
| 149 | // Proper stop; get the files and erase the context. |
| 150 | const std::vector<RecentFile> files = context->accumulator.Get(); |
| 151 | context_map_.Remove(call_id); |
| 152 | return files; |
| 153 | } |
| 154 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 155 | void RecentDiskSource::ScanDirectory(const int32_t call_id, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 156 | const base::FilePath& path, |
| 157 | int depth) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 158 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 159 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 160 | // If context is gone, that is Stop() has been called, exit immediately. |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 161 | CallContext* context = context_map_.Lookup(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 162 | if (context == nullptr) { |
| 163 | return; |
| 164 | } |
| 165 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 166 | storage::FileSystemURL url = BuildDiskURL(context->params, path); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 167 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 168 | ++context->inflight_readdirs; |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 169 | content::GetIOThreadTaskRunner({})->PostTask( |
| 170 | FROM_HERE, |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 171 | base::BindOnce( |
| 172 | &ReadDirectoryOnIOThread, |
| 173 | base::WrapRefCounted(context->params.file_system_context()), url, |
| 174 | base::BindRepeating(&RecentDiskSource::OnReadDirectory, |
| 175 | weak_ptr_factory_.GetWeakPtr(), call_id, path, |
| 176 | depth))); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 177 | } |
| 178 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 179 | void RecentDiskSource::OnReadDirectory( |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 180 | const int32_t call_id, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 181 | const base::FilePath& path, |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 182 | const int depth, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 183 | base::File::Error result, |
tzik | a40b440 | 2017-08-28 14:46:12 | [diff] [blame] | 184 | storage::FileSystemOperation::FileEntryList entries, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 185 | bool has_more) { |
| 186 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 187 | // If context is gone, that is Stop() has been called, exit immediately. |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 188 | CallContext* context = context_map_.Lookup(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 189 | if (context == nullptr) { |
| 190 | return; |
| 191 | } |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 192 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 193 | const std::u16string q16 = base::UTF8ToUTF16(context->params.query()); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 194 | for (const auto& entry : entries) { |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 195 | // Ignore directories and files that start with dot. |
| 196 | if (ignore_dotfiles_ && |
| 197 | base::StartsWith(entry.name.value(), ".", |
| 198 | base::CompareCase::INSENSITIVE_ASCII)) { |
| 199 | continue; |
| 200 | } |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 201 | base::FilePath subpath = path.Append(entry.name); |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 202 | |
Luciano Pacheco | 99533e8 | 2018-03-28 07:49:07 | [diff] [blame] | 203 | if (entry.type == filesystem::mojom::FsFileType::DIRECTORY) { |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 204 | if ((max_depth_ > 0 && depth >= max_depth_) || context->params.IsLate()) { |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 205 | continue; |
| 206 | } |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 207 | ScanDirectory(call_id, subpath, depth + 1); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 208 | } else { |
Joel Hockey | dab864e | 2024-10-15 22:46:12 | [diff] [blame] | 209 | if (!MatchesFileType(entry.name.path(), context->params.file_type())) { |
Naoki Fukino | 14a30c26 | 2020-01-21 10:39:32 | [diff] [blame] | 210 | continue; |
| 211 | } |
Bo Majewski | d5190897 | 2023-10-30 04:40:01 | [diff] [blame] | 212 | if (!FileNameMatches(base::UTF8ToUTF16(entry.name.value()), q16)) { |
| 213 | continue; |
| 214 | } |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 215 | storage::FileSystemURL url = BuildDiskURL(context->params, subpath); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 216 | ++context->inflight_stats; |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 217 | content::GetIOThreadTaskRunner({})->PostTask( |
| 218 | FROM_HERE, |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 219 | base::BindOnce( |
| 220 | &GetMetadataOnIOThread, |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 221 | base::WrapRefCounted(context->params.file_system_context()), url, |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 222 | storage::FileSystemOperation::GetMetadataFieldSet( |
| 223 | {storage::FileSystemOperation::GetMetadataField:: |
| 224 | kLastModified}), |
| 225 | base::BindOnce(&RecentDiskSource::OnGotMetadata, |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 226 | weak_ptr_factory_.GetWeakPtr(), call_id, url))); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 227 | } |
| 228 | } |
| 229 | |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 230 | if (has_more) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 231 | return; |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 232 | } |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 233 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 234 | --context->inflight_readdirs; |
| 235 | if (context->inflight_stats == 0 && context->inflight_readdirs == 0) { |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 236 | OnReadOrStatFinished(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 237 | } |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 238 | } |
| 239 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 240 | void RecentDiskSource::OnGotMetadata(const int32_t call_id, |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 241 | const storage::FileSystemURL& url, |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 242 | base::File::Error result, |
| 243 | const base::File::Info& info) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 244 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 245 | // If context is gone, that is Stop() has been called, exit immediately. |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 246 | CallContext* context = context_map_.Lookup(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 247 | if (context == nullptr) { |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 248 | return; |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 249 | } |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 250 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 251 | if (result == base::File::FILE_OK && |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 252 | info.last_modified >= context->params.cutoff_time()) { |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 253 | context->accumulator.Add(RecentFile(url, info.last_modified)); |
| 254 | } |
| 255 | |
| 256 | --context->inflight_stats; |
| 257 | if (context->inflight_stats == 0 && context->inflight_readdirs == 0) { |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 258 | OnReadOrStatFinished(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 259 | } |
| 260 | } |
| 261 | |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 262 | void RecentDiskSource::OnReadOrStatFinished(const int32_t call_id) { |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 263 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 264 | CallContext* context = context_map_.Lookup(call_id); |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 265 | // If context is gone, that is Stop() has been called, exit immediately. |
| 266 | if (context == nullptr) { |
| 267 | return; |
| 268 | } |
| 269 | |
| 270 | DCHECK(context->inflight_stats == 0); |
| 271 | DCHECK(context->inflight_readdirs == 0); |
| 272 | DCHECK(!context->build_start_time.is_null()); |
| 273 | |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 274 | // All reads/scans completed. |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 275 | UmaHistogramTimes(uma_histogram_name_, |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 276 | base::TimeTicks::Now() - context->build_start_time); |
Shuhei Takahashi | 1c79df0 | 2017-08-17 08:07:30 | [diff] [blame] | 277 | |
Bo Majewski | 65e32846 | 2024-02-12 06:15:04 | [diff] [blame] | 278 | std::move(context->callback).Run(context->accumulator.Get()); |
Bo Majewski | 3e5a6bd | 2024-02-29 03:06:23 | [diff] [blame] | 279 | context_map_.Remove(call_id); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 280 | } |
| 281 | |
Joel Hockey | c7649cc0 | 2019-03-08 00:38:42 | [diff] [blame] | 282 | storage::FileSystemURL RecentDiskSource::BuildDiskURL( |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 283 | const Params& params, |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 284 | const base::FilePath& path) const { |
| 285 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 286 | |
| 287 | storage::ExternalMountPoints* mount_points = |
| 288 | storage::ExternalMountPoints::GetSystemInstance(); |
Md. Hasanur Rashid | 7093fad0 | 2020-02-06 03:53:23 | [diff] [blame] | 289 | return mount_points->CreateExternalFileSystemURL( |
Bo Majewski | b5b1880 | 2023-11-22 06:04:53 | [diff] [blame] | 290 | blink::StorageKey::CreateFirstParty(url::Origin::Create(params.origin())), |
Kyra Seevers | c5cba52c | 2021-08-20 16:31:27 | [diff] [blame] | 291 | mount_point_name_, path); |
Shuhei Takahashi | 882a4dbb | 2017-08-16 06:40:40 | [diff] [blame] | 292 | } |
| 293 | |
Bo Majewski | 965f1c7 | 2023-02-06 01:51:44 | [diff] [blame] | 294 | bool RecentDiskSource::MatchesFileType(const base::FilePath& path, |
| 295 | RecentSource::FileType file_type) { |
| 296 | if (file_type == RecentSource::FileType::kAll) { |
| 297 | return true; |
| 298 | } |
| 299 | |
| 300 | // File type for |path| is guessed by data generated from file_types.json5. |
| 301 | // It guesses mime types based on file extensions, but it has a limited set |
| 302 | // of file extensions. |
| 303 | // TODO(fukino): It is better to have better coverage of file extensions to be |
| 304 | // consistent with file-type detection on Android system. crbug.com/1034874. |
| 305 | const auto ext = base::ToLowerASCII(path.Extension()); |
| 306 | if (!file_types_data::kExtensionToMIME.contains(ext)) { |
| 307 | return false; |
| 308 | } |
| 309 | std::string mime_type = file_types_data::kExtensionToMIME.at(ext); |
| 310 | |
| 311 | switch (file_type) { |
| 312 | case RecentSource::FileType::kAudio: |
| 313 | return net::MatchesMimeType(kAudioMimeType, mime_type); |
| 314 | case RecentSource::FileType::kImage: |
| 315 | return net::MatchesMimeType(kImageMimeType, mime_type); |
| 316 | case RecentSource::FileType::kVideo: |
| 317 | return net::MatchesMimeType(kVideoMimeType, mime_type); |
| 318 | case RecentSource::FileType::kDocument: |
| 319 | return file_types_data::kDocumentMIMETypes.contains(mime_type); |
| 320 | default: |
| 321 | return false; |
| 322 | } |
| 323 | } |
| 324 | |
Yeunjoo Choi | 3d9ed38a | 2022-11-10 02:51:24 | [diff] [blame] | 325 | } // namespace ash |