blob: bc8405b9b0c8987f9027338286ee8f6d4b7349e6 [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2017 The Chromium Authors
Shuhei Takahashib1f9a9c2017-08-17 07:44:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Yeunjoo Choief8a4a42022-11-08 04:21:055#include "chrome/browser/ash/fileapi/recent_drive_source.h"
Shuhei Takahashib1f9a9c2017-08-17 07:44:106
Wenbo Jiea26431d2022-05-20 06:16:127#include <iterator>
Shuhei Takahashib1f9a9c2017-08-17 07:44:108#include <utility>
9#include <vector>
10
11#include "base/files/file_path.h"
Avi Drissman02e49e582023-01-07 01:23:1812#include "base/functional/bind.h"
Shuhei Takahashi1b95b4cc2017-08-21 03:02:4513#include "base/metrics/histogram_macros.h"
Yeunjoo Choif23b1362021-03-29 14:31:1414#include "chrome/browser/ash/drive/drive_integration_service.h"
15#include "chrome/browser/ash/drive/file_system_util.h"
Yeunjoo Choi6ecc45b82021-06-22 01:40:0416#include "chrome/browser/ash/file_manager/fileapi_util.h"
Yeunjoo Choief8a4a42022-11-08 04:21:0517#include "chrome/browser/ash/fileapi/recent_file.h"
Henrique Ferreiro197812962022-08-22 23:51:1018#include "chromeos/ash/components/drivefs/drivefs_util.h"
Eric Seckler8652dcd52018-09-20 10:42:2819#include "content/public/browser/browser_task_traits.h"
Shuhei Takahashib1f9a9c2017-08-17 07:44:1020#include "content/public/browser/browser_thread.h"
Bo Majewski965f1c72023-02-06 01:51:4421#include "recent_drive_source.h"
DongJun Kimfebb3c22019-10-21 02:08:0622#include "storage/browser/file_system/file_system_operation.h"
23#include "storage/browser/file_system/file_system_operation_runner.h"
24#include "storage/browser/file_system/file_system_url.h"
DongJun Kimd6930ea2019-10-24 08:49:2525#include "storage/common/file_system/file_system_types.h"
Wenbo Jiea26431d2022-05-20 06:16:1226#include "ui/file_manager/file_types_data.h"
Md. Hasanur Rashid7a5e1d42020-02-12 11:15:2027#include "url/origin.h"
Shuhei Takahashib1f9a9c2017-08-17 07:44:1028
29using content::BrowserThread;
30
Yeunjoo Choi3d9ed38a2022-11-10 02:51:2431namespace ash {
Shuhei Takahashib1f9a9c2017-08-17 07:44:1032
Shuhei Takahashi1b95b4cc2017-08-21 03:02:4533const char RecentDriveSource::kLoadHistogramName[] =
34 "FileBrowser.Recent.LoadDrive";
35
Naoki Fukino44798b12020-01-21 12:02:2536const char kAudioMimeType[] = "audio";
37const char kImageMimeType[] = "image";
38const char kVideoMimeType[] = "video";
39
Bo Majewski65e328462024-02-12 06:15:0440RecentDriveSource::CallContext::CallContext(GetRecentFilesCallback callback)
41 : callback(std::move(callback)), build_start_time(base::TimeTicks::Now()) {}
42
43RecentDriveSource::CallContext::CallContext(CallContext&& context)
44 : callback(std::move(context.callback)),
45 build_start_time(context.build_start_time),
46 files(std::move(context.files)),
47 search_query(std::move(context.search_query)) {}
48
49RecentDriveSource::CallContext::~CallContext() = default;
50
Bo Majewski6f33bc82024-05-28 02:24:0051RecentDriveSource::RecentDriveSource(Profile* profile)
52 : RecentSource(extensions::api::file_manager_private::VolumeType::kDrive),
53 profile_(profile) {
Shuhei Takahashib1f9a9c2017-08-17 07:44:1054 DCHECK_CURRENTLY_ON(BrowserThread::UI);
55}
56
57RecentDriveSource::~RecentDriveSource() {
58 DCHECK_CURRENTLY_ON(BrowserThread::UI);
59}
60
Bo Majewski965f1c72023-02-06 01:51:4461std::vector<std::string> RecentDriveSource::CreateTypeFilters(
62 RecentSource::FileType file_type) {
63 std::vector<std::string> type_filters;
64 switch (file_type) {
65 case FileType::kAudio:
66 type_filters.push_back(kAudioMimeType);
67 break;
68 case FileType::kImage:
69 type_filters.push_back(kImageMimeType);
70 break;
71 case FileType::kVideo:
72 type_filters.push_back(kVideoMimeType);
73 break;
74 case FileType::kDocument: {
75 type_filters.insert(type_filters.end(),
76 file_types_data::kDocumentMIMETypes.begin(),
77 file_types_data::kDocumentMIMETypes.end());
78 break;
79 }
80 default:
81 // Leave the filters empty.
82 break;
83 }
84 return type_filters;
85}
86
Bo Majewski3e5a6bd2024-02-29 03:06:2387void RecentDriveSource::GetRecentFiles(const Params& params,
Bo Majewskib5b18802023-11-22 06:04:5388 GetRecentFilesCallback callback) {
Shuhei Takahashib1f9a9c2017-08-17 07:44:1089 DCHECK_CURRENTLY_ON(BrowserThread::UI);
90
Bo Majewski65e328462024-02-12 06:15:0491 auto context = std::make_unique<CallContext>(std::move(callback));
92 CallContext* context_ptr = context.get();
93 context_map_.AddWithID(std::move(context), params.call_id());
Shuhei Takahashi1b95b4cc2017-08-21 03:02:4594
Sam McNallye4088582018-09-21 06:15:1495 auto* integration_service =
96 drive::util::GetIntegrationServiceByProfile(profile_);
97 if (!integration_service) {
98 // |integration_service| is nullptr if Drive is disabled.
Bo Majewski65e328462024-02-12 06:15:0499 OnComplete(params.call_id());
Shuhei Takahashib1f9a9c2017-08-17 07:44:10100 return;
101 }
102
Sam McNallye4088582018-09-21 06:15:14103 auto query_params = drivefs::mojom::QueryParameters::New();
Munira Tursunovab67fa752024-11-01 08:49:58104 query_params->page_size = params.max_files();
Sam McNallye4088582018-09-21 06:15:14105 query_params->query_source =
106 drivefs::mojom::QueryParameters::QuerySource::kLocalOnly;
107 query_params->sort_field =
mlcui4c76b0a2024-08-02 07:03:38108 drivefs::mojom::QueryParameters::SortField::kLastViewedByMe;
Sam McNallye4088582018-09-21 06:15:14109 query_params->sort_direction =
110 drivefs::mojom::QueryParameters::SortDirection::kDescending;
Bo Majewski965f1c72023-02-06 01:51:44111 std::vector<std::string> type_filters =
Bo Majewskib5b18802023-11-22 06:04:53112 RecentDriveSource::CreateTypeFilters(params.file_type());
mlcui4c76b0a2024-08-02 07:03:38113 query_params->viewed_time = params.cutoff_time();
Bo Majewskib5b18802023-11-22 06:04:53114 query_params->title = params.query();
mlcui4c76b0a2024-08-02 07:03:38115 query_params->viewed_time_operator =
Bo Majewski852dcb12023-08-25 04:55:25116 drivefs::mojom::QueryParameters::DateComparisonOperator::kGreaterThan;
Bo Majewski965f1c72023-02-06 01:51:44117 if (type_filters.size() == 1) {
118 query_params->mime_type = type_filters.front();
119 } else if (type_filters.size() > 1) {
120 query_params->mime_types = std::move(type_filters);
Naoki Fukino44798b12020-01-21 12:02:25121 }
Sam McNallye4088582018-09-21 06:15:14122 integration_service->GetDriveFsInterface()->StartSearchQuery(
Bo Majewski65e328462024-02-12 06:15:04123 context_ptr->search_query.BindNewPipeAndPassReceiver(),
124 std::move(query_params));
125 context_ptr->search_query->GetNextPage(
126 base::BindOnce(&RecentDriveSource::GotSearchResults,
127 weak_ptr_factory_.GetWeakPtr(), params));
Shuhei Takahashib1f9a9c2017-08-17 07:44:10128}
129
Bo Majewski65e328462024-02-12 06:15:04130std::vector<RecentFile> RecentDriveSource::Stop(const int32_t call_id) {
Shuhei Takahashi257ee532017-08-21 09:06:22131 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Bo Majewski65e328462024-02-12 06:15:04132 CallContext* context = context_map_.Lookup(call_id);
133 if (context == nullptr) {
134 return {};
135 }
136 std::vector<RecentFile> files = std::move(context->files);
137 context_map_.Remove(call_id);
138 return files;
139}
140
Bo Majewski3e5a6bd2024-02-29 03:06:23141void RecentDriveSource::OnComplete(const int32_t call_id) {
Bo Majewski65e328462024-02-12 06:15:04142 DCHECK_CURRENTLY_ON(BrowserThread::UI);
143 CallContext* context = context_map_.Lookup(call_id);
144 if (context == nullptr) {
145 return;
146 }
147 DCHECK(!context->build_start_time.is_null());
Shuhei Takahashi257ee532017-08-21 09:06:22148
Shuhei Takahashi1b95b4cc2017-08-21 03:02:45149 UMA_HISTOGRAM_TIMES(kLoadHistogramName,
Bo Majewski65e328462024-02-12 06:15:04150 base::TimeTicks::Now() - context->build_start_time);
151 std::move(context->callback).Run(std::move(context->files));
152 context_map_.Remove(call_id);
Shuhei Takahashib1f9a9c2017-08-17 07:44:10153}
154
Sam McNallye4088582018-09-21 06:15:14155void RecentDriveSource::GotSearchResults(
Munira Tursunovab67fa752024-11-01 08:49:58156 const Params& params,
Sam McNallye4088582018-09-21 06:15:14157 drive::FileError error,
Mohamed Mansour5cf92142023-12-08 23:12:12158 std::optional<std::vector<drivefs::mojom::QueryItemPtr>> results) {
Bo Majewski65e328462024-02-12 06:15:04159 CallContext* context = context_map_.Lookup(params.call_id());
160 if (context == nullptr) {
Sam McNallye4088582018-09-21 06:15:14161 return;
162 }
163
Bo Majewski65e328462024-02-12 06:15:04164 auto* integration_service =
165 drive::util::GetIntegrationServiceByProfile(profile_);
166 if (!results || !integration_service) {
167 OnComplete(params.call_id());
168 return;
169 }
170
Munira Tursunovab67fa752024-11-01 08:49:58171 context->files.reserve(results->size());
Sam McNallye4088582018-09-21 06:15:14172 for (auto& result : *results) {
Sergei Datsenko0adc87272019-07-05 06:14:05173 if (!drivefs::IsAFile(result->metadata->type)) {
Sam McNallye4088582018-09-21 06:15:14174 continue;
175 }
176 base::FilePath path = integration_service->GetMountPointPath().BaseName();
177 if (!base::FilePath("/").AppendRelativePath(result->path, &path)) {
178 path = path.Append(result->path);
179 }
Bo Majewski65e328462024-02-12 06:15:04180 context->files.emplace_back(
Bo Majewskib5b18802023-11-22 06:04:53181 params.file_system_context()->CreateCrackedFileSystemURL(
Ari Chivukulac81e13e2023-02-15 20:44:57182 blink::StorageKey::CreateFirstParty(
Bo Majewskib5b18802023-11-22 06:04:53183 url::Origin::Create(params.origin())),
Md. Hasanur Rashid7a5e1d42020-02-12 11:15:20184 storage::kFileSystemTypeExternal, path),
Wenbo Jiebea72712022-08-08 04:01:31185 // Do not use "modification_time" field here because that will cause
186 // files modified by others recently (e.g. Shared with me) being
187 // treated as recent files.
188 result->metadata->last_viewed_by_me_time);
Sam McNallye4088582018-09-21 06:15:14189 }
Munira Tursunovab67fa752024-11-01 08:49:58190 OnComplete(params.call_id());
Sam McNallye4088582018-09-21 06:15:14191}
192
Yeunjoo Choi3d9ed38a2022-11-10 02:51:24193} // namespace ash