chromium/third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module blink.mojom;

import "third_party/blink/public/mojom/file_system_access/file_system_access_cloud_identifier.mojom";
import "third_party/blink/public/mojom/file_system_access/file_system_access_error.mojom";
import "third_party/blink/public/mojom/file_system_access/file_system_access_file_handle.mojom";
import "third_party/blink/public/mojom/file_system_access/file_system_access_transfer_token.mojom";
import "third_party/blink/public/mojom/permissions/permission_status.mojom";

// Union representing either a file or a directory handle. Used in APIs that
// can return arbitrary handles.
union FileSystemAccessHandle {
  pending_remote<FileSystemAccessFileHandle> file;
  pending_remote<FileSystemAccessDirectoryHandle> directory;
};

struct FileSystemAccessEntry {
  FileSystemAccessHandle entry_handle;
  string name;
};

interface FileSystemAccessDirectoryEntriesListener {
  // Called by FileSystemAccessDirectoryHandle.GetEntries when some entries
  // have been obtained. `has_more_entries` is false when all the entries have
  // been obtained, and  indicates that the callback will not be called again.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  DidReadDirectory(FileSystemAccessError result,
                   array<FileSystemAccessEntry> entries,
                   bool has_more_entries);
};

// This interface represents a handle to a directory in the File System Access
// API.
//
// TODO(https://crbug.com/1248065): Using something similar to (but probably not
// the same as) mojo_base.mojom.SafeBasename to represent names of children
// could help us defend against directory traversal bugs at the IPC layer (not
// the same type though because of https://crbug.com/956231 and the fact that
// our paths really aren't base::FilePath, but instead are virtual paths).
interface FileSystemAccessDirectoryHandle {
  // Queries the current permission status for this handle.
  GetPermissionStatus(bool writable) => (PermissionStatus status);

  // Requests read and/or write permission for this handle. Returns the new
  // permission status for this handle.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  RequestPermission(bool writable) => (FileSystemAccessError result, PermissionStatus status);

  // Returns a file with the given `basename` that is a child of this
  // directory. If no such file exists, and `create` is true, the file is first
  // created. Returns an error if the operation fails, or a handle to the newly
  // created file if the operation succeeds.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  GetFile(string basename, bool create) =>
      (FileSystemAccessError result, pending_remote<FileSystemAccessFileHandle>? file);

  // Returns a directory with the given `basename` that is a child of this
  // directory. If no such directory exists, and `create` is true, the directory
  // is first created.
  // Returns an error if the operation fails, or a handle to the newly created
  // directory if the operation succeeds.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  GetDirectory(string basename, bool create) =>
      (FileSystemAccessError result,
       pending_remote<FileSystemAccessDirectoryHandle>? directory);

  // Returns all the direct children of this directory.
  GetEntries(pending_remote<FileSystemAccessDirectoryEntriesListener> listener);

  // Renames the directory represented by this handle to `new_entry_name`.
  // Returns an error if the directory does not exist.
  Rename(string new_entry_name) => (FileSystemAccessError result);

  // Same as above, but `destination_directory` is resolved into a directory to
  // be used as the destination directory for the move operation. This is only
  // guaranteed to be atomic if the directory is moved within the same file
  // system. Moving across file systems may result in partially written data if
  // the move fails. Returns an error if the directory does not exist or the
  // move operation fails.
  Move(pending_remote<FileSystemAccessTransferToken> destination_directory,
                      string new_entry_name) => (FileSystemAccessError result);

  // Deletes the directory represented by this handle.
  // To delete recursively, set `recurse` to true.
  // Returns an error if the directory does not exist or is not empty and
  // `recurse` is not specified.
  Remove(bool recurse) => (FileSystemAccessError result);

  // Deletes an entry which is a child of this directory.
  // To delete recursively, set `recurse` to true.
  RemoveEntry(string basename, bool recurse) => (FileSystemAccessError result);

  // If `possible_child` is not a descendant of this directory, `path` will be
  // null. If `possible_child` is equal to this directory, `path` will be an
  // empty array. And if `possible_child` is a descendant of this directory,
  // `path` will contain the path components making up the path of
  // `possible_child` relative to this directory.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  Resolve(pending_remote<FileSystemAccessTransferToken> possible_child) =>
      (FileSystemAccessError result, array<string>? path);

  // Create a TransferToken for this directory. This token can be used to pass
  // a reference to this directory to other methods, for example to copy or move
  // the directory, or when transferring the handle over postMessage.
  Transfer(pending_receiver<FileSystemAccessTransferToken> token);

  // Returns a uniquely identifying string for the handle.
  // `id` must be in GUID version 4 format.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  GetUniqueId() => (FileSystemAccessError result, string id);

  // Returns a list of cloud identifiers (`provider_name` and `id`) if the
  // directory is synced to the cloud and its syncing client has registered to
  // the browser.
  // TODO(https://crbug.com/1327821): Replace this with expected<T, E> if/when
  // it becomes available for mojom.
  GetCloudIdentifiers() =>
      (FileSystemAccessError result, array<FileSystemAccessCloudIdentifier> cloud_identifiers);
};