chromium/components/services/storage/public/mojom/filesystem/directory.mojom

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

module storage.mojom;

import "mojo/public/mojom/base/big_string.mojom";
import "mojo/public/mojom/base/file.mojom";
import "mojo/public/mojom/base/file_error.mojom";
import "mojo/public/mojom/base/file_info.mojom";
import "mojo/public/mojom/base/file_path.mojom";

// Determines how |Directory.GetEntries()| operates.
enum GetEntriesMode {
  // Only regular files will be enumerated.
  kFilesOnly,

  // Both files and directories will be enumerated.
  kFilesAndDirectories,
};

// A special type of file path which, unlike mojo_base.mojom.FilePath, is
// restricted to descending (i.e. no references to parent directories via "..")
// relative (i.e. non-absolute) paths only. For C++ bindings, this is enforced
// by type-mapping traits.
struct StrictRelativePath {
  // The actual path data.
  mojo_base.mojom.FilePath path;
};

// Indicates how a file should be opened and/or created by
// |Directory.OpenFile()|.
enum FileOpenMode {
  // Only opens the file if it already exists.
  kOpenIfExists,

  // Only creates and opens the file if it did not already exist.
  kCreateAndOpenOnlyIfNotExists,

  // Always opens the file, creating a new one only if it didn't already exist.
  kAlwaysOpen,

  // Always creates a new file, overwriting any old file that may exist.
  kAlwaysCreate,

  // Only opens the file if it already exists, truncating the file on open.
  kOpenIfExistsAndTruncate,
};

// Indicates the type of read access a file should have when opened by
// |Directory.OpenFile()|.
enum FileReadAccess {
  // No read access.
  kReadNotAllowed,

  // Read access allowed.
  kReadAllowed,
};

// Indicates the type of write access a file should have when opened by
// |Directory.OpenFile()|.
enum FileWriteAccess {
  // No write access.
  kWriteNotAllowed,

  // Full write access allowed.
  kWriteAllowed,

  // Append-only write access allowed.
  kAppendOnly,
};

// A structure used to describe access rights for a specific path in the
// filesystem.
struct PathAccessInfo {
  // Indicates whether the path can be opened for reading.
  bool can_read;

  // Indicates whether the path can be opened for writing.
  bool can_write;
};

// An empty interface used to hold remote ownership of a lock acquired via
// |Directory.LockFile()| below. Closing the remote endpoint of this interface
// effectively releases the corresponding lock even if |Release()| is not
// called.
interface FileLock {
  // Immediately releases the lock. After this is called once, the FileLock is
  // permanently released. Subsequent disconnection or calls to |Release()| will
  // have no interesting side-effects.
  [Sync] Release() => (mojo_base.mojom.FileError error);
};

// A client interface consumed by the Storage Service in order to access
// directory contents from within a sandboxed process. Must be implemented by
// a more privileged process like the browser.
//
// Each bound Directory interface corresponds to a fixed directory in the
// filesystem, and all StrictRelatvePath references must be interpreted as
// relative to that directory.
interface Directory {
  // Binds a new Directory receiver scoped to the same root as this Directory.
  Clone(pending_receiver<Directory> receiver);

  // Indicates whether |path| exists.
  [Sync]
  PathExists(StrictRelativePath path) => (bool exists);

  // Enumerates all files and/or subdirectories within |path|. Not recursive.
  // All returned paths are relative to |path|.
  [Sync]
  GetEntries(StrictRelativePath path, GetEntriesMode mode)
      => (mojo_base.mojom.FileError error,
          array<mojo_base.mojom.FilePath> entries);

  // Opens a file at |path|.
  [Sync]
  OpenFile(StrictRelativePath path,
           FileOpenMode mode,
           FileReadAccess read_access,
           FileWriteAccess write_access)
      => (mojo_base.mojom.FileError error, mojo_base.mojom.File? file);

  // Creates a new directory at |path|.
  [Sync]
  CreateDirectory(StrictRelativePath path) => (mojo_base.mojom.FileError error);

  // Deletes the file or directory at |path| if it exists and returns true iff
  // successful.  Not recursive.  Will fail if there are subdirectories.  This
  // will return true if |path| does not exist.
  [Sync]
  DeleteFile(StrictRelativePath path) => (bool success);

  // Retrieves information about a specific filesystem entry at |path|. Returns
  // null on failure, or a populated |info| struct on success.
  [Sync]
  GetFileInfo(StrictRelativePath path) => (mojo_base.mojom.FileInfo? info);

  // Retrieves access information about a specific filesystem entry at |path|.
  // Returns null on failure or a populated |info| struct on success.
  [Sync]
  GetPathAccess(StrictRelativePath path) => (PathAccessInfo? info);

  // Renames a file from |old_path| to |new_path|. Note that if |new_path|
  // already exists, it will be overwritten by this call.
  [Sync]
  RenameFile(StrictRelativePath old_path, StrictRelativePath new_path)
      => (mojo_base.mojom.FileError error);

  // Attempts to acquire an exclusive lock on the lock file identified by
  // |path|, creating a new file if it didn't already exist. Upon success,
  // |error| will be FILE_OK, and |lock| will be valid. As long as the caller
  // retains |lock|, the acquired lock will be held. Destroying |lock| or
  // explicitly calling |Release()| on it releases the lock.
  [Sync]
  LockFile(StrictRelativePath path) => (mojo_base.mojom.FileError error,
                                        pending_remote<FileLock>? lock);
};