1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/file_manager/virtual_file_tasks.h"
#include <initializer_list>
#include <vector>
#include "base/containers/contains.h"
#include "base/no_destructor.h"
#include "chrome/browser/ash/file_manager/file_tasks.h"
#include "chrome/browser/ash/file_manager/virtual_tasks/drive_upload_virtual_task.h"
#include "chrome/browser/ash/file_manager/virtual_tasks/install_isolated_web_app_virtual_task.h"
#include "chrome/browser/ash/file_manager/virtual_tasks/ms365_virtual_task.h"
#include "chromeos/ash/components/file_manager/app_id.h"
#include "components/services/app_service/public/cpp/intent_util.h"
namespace file_manager::file_tasks {
namespace {
// The set of virtual tasks is statically determined. Tasks can turn themselves
// on or off dynamically by implementing |IsEnabled()|.
const std::vector<VirtualTask*>& GetVirtualTasks() {
static const base::NoDestructor<std::vector<VirtualTask*>> virtual_tasks(
std::initializer_list<VirtualTask*>({
new InstallIsolatedWebAppVirtualTask(),
new Ms365VirtualTask(),
new DocsUploadVirtualTask(),
new SheetsUploadVirtualTask(),
new SlidesUploadVirtualTask(),
}));
if (!GetTestVirtualTasks().empty()) {
return GetTestVirtualTasks();
}
return *virtual_tasks;
}
bool LooksLikeVirtualTask(const TaskDescriptor& task) {
return task.app_id == kFileManagerSwaAppId &&
task.task_type == TASK_TYPE_WEB_APP;
}
// Validates that each entry from `entries` matches any mime type from
// `mime_types`.
bool AllEntriesMatchAtLeastOneMimeType(
const std::vector<extensions::EntryInfo>& entries,
const std::vector<std::string>& mime_types) {
return std::ranges::all_of(
entries,
[&](const std::string& entry_mime_type) {
return std::ranges::any_of(
mime_types, [&](const std::string& mime_type) {
return apps_util::MimeTypeMatched(entry_mime_type, mime_type);
});
},
&extensions::EntryInfo::mime_type);
}
// Validates that each file url from `file_urls` matches any file extension from
// `file_extensions`
bool AllUrlsMatchAtLeastOneFileExtension(
const std::vector<GURL>& file_urls,
const std::vector<std::string>& file_extensions) {
return std::ranges::all_of(
file_urls,
[&](const std::string& file_name) {
return std::ranges::any_of(
file_extensions, [&](const std::string& file_extension) {
return apps_util::ExtensionMatched(file_name, file_extension);
});
},
&GURL::ExtractFileName);
}
} // namespace
void MatchVirtualTasks(Profile* profile,
const std::vector<extensions::EntryInfo>& entries,
const std::vector<GURL>& file_urls,
const std::vector<std::string>& dlp_source_urls,
std::vector<FullTaskDescriptor>* result_list) {
DCHECK_EQ(entries.size(), file_urls.size());
if (entries.empty()) {
return;
}
for (const VirtualTask* virtual_task : GetVirtualTasks()) {
if (virtual_task->IsEnabled(profile) &&
virtual_task->Matches(entries, file_urls)) {
// TODO(b/284800493): Correct values below.
result_list->emplace_back(
TaskDescriptor{kFileManagerSwaAppId, TASK_TYPE_WEB_APP,
virtual_task->id()},
virtual_task->title(), virtual_task->icon_url(),
/* is_default=*/false,
/* is_generic_file_handler=*/false,
/* is_file_extension_match=*/false,
virtual_task->IsDlpBlocked(dlp_source_urls));
}
}
}
bool ExecuteVirtualTask(Profile* profile,
const TaskDescriptor& task,
const std::vector<FileSystemURL>& file_urls) {
auto* virtual_task = FindVirtualTask(task);
if (!virtual_task || !virtual_task->IsEnabled(profile)) {
return false;
}
return virtual_task->Execute(profile, task, file_urls);
}
bool IsVirtualTask(const TaskDescriptor& task) {
return LooksLikeVirtualTask(task) &&
base::Contains(GetVirtualTasks(), task.action_id, &VirtualTask::id);
}
VirtualTask* FindVirtualTask(const TaskDescriptor& task) {
if (!LooksLikeVirtualTask(task)) {
return nullptr;
}
const auto& tasks = GetVirtualTasks();
auto itr = std::ranges::find(tasks, task.action_id, &VirtualTask::id);
if (itr == tasks.end()) {
return nullptr;
}
return *itr;
}
std::vector<VirtualTask*>& GetTestVirtualTasks() {
static base::NoDestructor<std::vector<VirtualTask*>> virtual_tasks;
return *virtual_tasks;
}
VirtualTask::VirtualTask() = default;
VirtualTask::~VirtualTask() = default;
bool VirtualTask::Matches(const std::vector<extensions::EntryInfo>& entries,
const std::vector<GURL>& file_urls) const {
// Try to match mime types
bool mime_types_matched =
AllEntriesMatchAtLeastOneMimeType(entries, matcher_mime_types_);
// Try to match extensions
bool extensions_matched =
AllUrlsMatchAtLeastOneFileExtension(file_urls, matcher_file_extensions_);
// TODO(b/284800493): Should this be able to mix and match mimes and
// extensions too?
return mime_types_matched || extensions_matched;
}
} // namespace file_manager::file_tasks
|