File: arc_file_system_operation_runner.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (256 lines) | stat: -rw-r--r-- 10,841 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_ARC_FILEAPI_ARC_FILE_SYSTEM_OPERATION_RUNNER_H_
#define CHROME_BROWSER_ASH_ARC_FILEAPI_ARC_FILE_SYSTEM_OPERATION_RUNNER_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/ash/arc/fileapi/arc_file_system_bridge.h"
#include "chrome/browser/ash/arc/session/arc_session_manager_observer.h"
#include "chromeos/ash/experiences/arc/mojom/file_system.mojom-forward.h"
#include "chromeos/ash/experiences/arc/session/connection_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "storage/browser/file_system/watcher_manager.h"

class BrowserContextKeyedServiceFactory;

namespace ash {
class RecentArcMediaSourceTest;
}

namespace content {
class BrowserContext;
}  // namespace content

namespace arc {

class ArcBridgeService;

// Runs ARC file system operations.
//
// This is an abstraction layer on top of mojom::FileSystemInstance. ARC file
// system operations from chrome to the ARC container which can be initiated
// before the ARC container gets ready should go through this class, rather than
// invoking mojom::FileSystemInstance directly.
//
// When ARC is disabled or ARC has already booted, file system operations are
// performed immediately. While ARC boot is under progress, file operations are
// deferred until ARC boot finishes or the user disables ARC.
//
// This file system operation runner provides better UX when the user attempts
// to perform file operations while ARC is booting. For example:
//
// - Media views are mounted in Files app soon after the user logs into
//   the system. If the user attempts to open media views before ARC boots,
//   a spinner is shown until file system gets ready because ReadDirectory
//   operations are deferred.
// - When an Android content URL is opened soon after the user logs into
//   the system (because the user opened the tab before they logged out for
//   instance), the tab keeps loading until ARC boot finishes, instead of
//   failing immediately.
//
// All member functions must be called on the UI thread.
class ArcFileSystemOperationRunner
    : public KeyedService,
      public ArcFileSystemBridge::Observer,
      public ArcSessionManagerObserver,
      public ConnectionObserver<mojom::FileSystemInstance> {
 public:
  using GetFileSizeCallback = mojom::FileSystemInstance::GetFileSizeCallback;
  using GetMimeTypeCallback = mojom::FileSystemInstance::GetMimeTypeCallback;
  using OpenThumbnailCallback =
      mojom::FileSystemInstance::OpenThumbnailCallback;
  using OpenFileSessionToWriteCallback =
      mojom::FileSystemInstance::OpenFileSessionToWriteCallback;
  using OpenFileSessionToReadCallback =
      mojom::FileSystemInstance::OpenFileSessionToReadCallback;
  using GetDocumentCallback = mojom::FileSystemInstance::GetDocumentCallback;
  using GetChildDocumentsCallback =
      mojom::FileSystemInstance::GetChildDocumentsCallback;
  using GetRecentDocumentsCallback =
      mojom::FileSystemInstance::GetRecentDocumentsCallback;
  using GetRootsCallback = mojom::FileSystemInstance::GetRootsCallback;
  using GetRootSizeCallback = mojom::FileSystemInstance::GetRootSizeCallback;
  using DeleteDocumentCallback =
      mojom::FileSystemInstance::DeleteDocumentCallback;
  using RenameDocumentCallback =
      mojom::FileSystemInstance::RenameDocumentCallback;
  using CreateDocumentCallback =
      mojom::FileSystemInstance::CreateDocumentCallback;
  using CopyDocumentCallback = mojom::FileSystemInstance::CopyDocumentCallback;
  using MoveDocumentCallback = mojom::FileSystemInstance::MoveDocumentCallback;
  using AddWatcherCallback = base::OnceCallback<void(int64_t watcher_id)>;
  using RemoveWatcherCallback = base::OnceCallback<void(bool success)>;
  using ChangeType = storage::WatcherManager::ChangeType;
  using WatcherCallback = base::RepeatingCallback<void(ChangeType type)>;

  class Observer {
   public:
    // Called when the installed watchers are invalidated.
    // This can happen when Android system restarts, for example.
    // After this event is fired, watcher IDs issued before the event can be
    // reused.
    virtual void OnWatchersCleared() = 0;

   protected:
    virtual ~Observer() = default;
  };

  // Returns singleton instance for the given BrowserContext,
  // or nullptr if the browser |context| is not allowed to use ARC.
  static ArcFileSystemOperationRunner* GetForBrowserContext(
      content::BrowserContext* context);

  // Creates an instance suitable for unit tests.
  // This instance will run all operations immediately without deferring by
  // default. Also, deferring can be enabled/disabled by calling
  // SetShouldDefer() from friend classes.
  static std::unique_ptr<ArcFileSystemOperationRunner> CreateForTesting(
      content::BrowserContext* context,
      ArcBridgeService* bridge_service);

  // Returns Factory instance for ArcFileSystemOperationRunner.
  static BrowserContextKeyedServiceFactory* GetFactory();

  ArcFileSystemOperationRunner(content::BrowserContext* context,
                               ArcBridgeService* bridge_service);

  ArcFileSystemOperationRunner(const ArcFileSystemOperationRunner&) = delete;
  ArcFileSystemOperationRunner& operator=(const ArcFileSystemOperationRunner&) =
      delete;

  ~ArcFileSystemOperationRunner() override;

  // Adds or removes observers.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Runs file system operations. See file_system.mojom for documentation.
  void GetFileSize(const GURL& url, GetFileSizeCallback callback);
  void GetMimeType(const GURL& url, GetMimeTypeCallback callback);
  void OpenThumbnail(const GURL& url,
                     const gfx::Size& size,
                     OpenThumbnailCallback callback);
  void CloseFileSession(const std::string& session_id,
                        const std::string& error_message);
  void OpenFileSessionToWrite(const GURL& url,
                              OpenFileSessionToWriteCallback callback);
  void OpenFileSessionToRead(const GURL& url,
                             OpenFileSessionToReadCallback callback);
  void GetDocument(const std::string& authority,
                   const std::string& document_id,
                   GetDocumentCallback callback);
  void GetChildDocuments(const std::string& authority,
                         const std::string& parent_document_id,
                         GetChildDocumentsCallback callback);
  void GetRecentDocuments(const std::string& authority,
                          const std::string& root_id,
                          GetRecentDocumentsCallback callback);
  void GetRoots(GetRootsCallback callback);
  void GetRootSize(const std::string& authority,
                   const std::string& root_id,
                   GetRootSizeCallback callback);
  void DeleteDocument(const std::string& authority,
                      const std::string& document_id,
                      DeleteDocumentCallback callback);
  void RenameDocument(const std::string& authority,
                      const std::string& document_id,
                      const std::string& display_name,
                      RenameDocumentCallback callback);
  void CreateDocument(const std::string& authority,
                      const std::string& parent_document_id,
                      const std::string& mime_type,
                      const std::string& display_name,
                      CreateDocumentCallback callback);
  void CopyDocument(const std::string& authority,
                    const std::string& source_document_id,
                    const std::string& target_parent_document_id,
                    CopyDocumentCallback callback);
  void MoveDocument(const std::string& authority,
                    const std::string& source_document_id,
                    const std::string& source_parent_document_id,
                    const std::string& target_parent_document_id,
                    MoveDocumentCallback callback);
  void AddWatcher(const std::string& authority,
                  const std::string& document_id,
                  const WatcherCallback& watcher_callback,
                  AddWatcherCallback callback);
  void RemoveWatcher(int64_t watcher_id, RemoveWatcherCallback callback);

  // KeyedService overrides:
  void Shutdown() override;

  // ArcFileSystemBridge::Observer overrides:
  void OnDocumentChanged(int64_t watcher_id, ChangeType type) override;

  // ArcSessionManagerObserver overrides:
  void OnArcPlayStoreEnabledChanged(bool enabled) override;

  // ConnectionObserver<mojom::FileSystemInstance> overrides:
  void OnConnectionReady() override;
  void OnConnectionClosed() override;

  // Returns true if operations will be deferred.
  bool WillDefer() const { return should_defer_; }

  static void EnsureFactoryBuilt();

 private:
  friend class ArcFileSystemOperationRunnerTest;
  friend class ash::RecentArcMediaSourceTest;

  ArcFileSystemOperationRunner(content::BrowserContext* context,
                               ArcBridgeService* bridge_service,
                               bool set_should_defer_by_events);

  void OnWatcherAdded(const WatcherCallback& watcher_callback,
                      AddWatcherCallback callback,
                      int64_t watcher_id);

  // Called whenever ARC states related to |should_defer_| are changed.
  void OnStateChanged();

  // Enables/disables deferring.
  // Friend unit tests can call this function to simulate enabling/disabling
  // deferring.
  void SetShouldDefer(bool should_defer);

  // Maybe nullptr in unittests.
  const raw_ptr<content::BrowserContext> context_;
  const raw_ptr<ArcBridgeService>
      arc_bridge_service_;  // Owned by ArcServiceManager

  // Indicates if this instance should enable/disable deferring by events.
  // Usually true, but set to false in unit tests.
  bool set_should_defer_by_events_;

  // Set to true if operations should be deferred at this moment.
  // The default is set to false so that operations are not deferred in
  // unit tests.
  bool should_defer_ = false;

  // List of deferred operations.
  std::vector<base::OnceClosure> deferred_operations_;

  // Map from a watcher ID to a watcher callback.
  std::map<int64_t, WatcherCallback> watcher_callbacks_;

  base::ObserverList<Observer>::Unchecked observer_list_;

  base::WeakPtrFactory<ArcFileSystemOperationRunner> weak_ptr_factory_{this};
};

}  // namespace arc

#endif  // CHROME_BROWSER_ASH_ARC_FILEAPI_ARC_FILE_SYSTEM_OPERATION_RUNNER_H_