File: virtual_file_tasks.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (154 lines) | stat: -rw-r--r-- 5,426 bytes parent folder | download | duplicates (6)
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