chromium/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom

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

module ash.shortcut_customization.mojom;

import "ash/public/mojom/accelerator_configuration.mojom";
import "ash/public/mojom/accelerator_info.mojom";
import "ash/public/mojom/accelerator_keys.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "ui/base/accelerators/mojom/accelerator.mojom";
import "ui/events/ash/mojom/meta_key.mojom";

// A struct that is returned from modifying an accelerator. It contains
// an optional field for the accelerator name if the action has a conflict with
// an existing accelerator. Otherwise it is left empty.
struct AcceleratorResultData {
  // Optional field - the name of the confliction shortcut name.
  // Used in the frontend to display to users what the conflicting shortcut
  // name.
  mojo_base.mojom.String16? shortcut_name;

  // Result of the configuration action.
  ash.mojom.AcceleratorConfigResult result;
};

// Represents an accelerator with only the KeyCode, Modifier, and key state.
// This struct should only be used for sending data from the renderer to the
// browser process.
struct SimpleAccelerator {
  ash.mojom.VKey key_code;
  int32 modifiers;
  ui.mojom.AcceleratorKeyState key_state;
};

// Enum of possible options for text accelerators.
enum UserAction {
  kOpenEditDialog,
  kStartAddAccelerator,
  kStartReplaceAccelerator,
  kRemoveAccelerator,
  kSuccessfulModification,
  kResetAction,
  kResetAll,
};

// Enum of all possible actions that can be done within the accelerator edit
// dialog.
// The enum is ordered by bit order of the actions:
// 0000: No Action
// 0001: Add
// 0010: Edit
// 0100: Remove
// 1000: Reset
// This should be kept in sync with the enum
// `ShortcutCustomizationEditDialogCompletedActions` in
// `tools/metrics/histograms/enums.xml`.
enum EditDialogCompletedActions {
  kNoAction,
  kAdd,
  kEdit,
  kEditAdd,
  kRemove,
  kRemoveAdd,
  kRemoveEdit,
  kRemoveEditAdd,
  kReset,
  kResetAdd,
  kResetEdit,
  kResetEditAdd,
  kResetRemove,
  kResetRemoveAdd,
  kResetRemoveEdit,
  kResetRemoveEditAdd,
};

// Enum of possible subactions done during either adding or editing an
// accelerator.
// Important: Do not change the ordering of this enum, these are used directly
// in metrics.
enum Subactions {
  kNoErrorCancel,
  kNoErrorSuccess,
  kErrorCancel,
  kErrorSuccess,
};

// Observer interface, to be implemented by the Shortcut Customization SWA to
// receive updated accelerators.
interface AcceleratorsUpdatedObserver {
  // Called whenever there is an observable change with accelerators. This
  // includes any modifications to accelerators, change of accelerator-related
  // prefs (i.e. TreatTopRowAsFKey), or keyboard device connected/disconnected.
  // `config` encapsulates the entire accelerator mapping that has been updated
  // It is formatted as:
  // AcceleratorSource -> map<AcceleratorActionId, Array<AcceleratorInfo>>.
  // Where AcceleratorActionId represents the unique ID of a shortcut.
  OnAcceleratorsUpdated(
      map<ash.mojom.AcceleratorSource,
      map<uint32, array<ash.mojom.AcceleratorInfo>>> config);
};

// Observer interface, to be implemented by the Shortcut Customization SWA to
// receive updates related to shortcut customization policies.
interface PolicyUpdatedObserver {
  // Called whenever there is a change in the kShortcutCustomizationAllowed
  // policy. This informs the observer about the changes in policy settings.
  OnCustomizationPolicyUpdated();
};

// Provides methods to allow the Shortcut Customization SWA to call on the
// shortcut provider implementor. Interface is implemented by C++ accelerator
// source configurators, e.g. BrowserAcceleratorConfiguration,
// AcceleratorController, EventRewriterConfiguration. Remote is to be used by
// the Shortcut Customization webui app (JS).
interface AcceleratorConfigurationProvider {
  // Whether the source is mutable and shortcuts can be changed.
  IsMutable(ash.mojom.AcceleratorSource source) => (bool is_mutable);

  // Returns true if the user is allowed to customize system shortcuts.
  // (default value is true for non-managed users).
  IsCustomizationAllowedByPolicy() => (bool is_customization_allowed_by_policy);

  // Returns the meta key to display in the UI to represent the overall current
  // keyboard situation. This will only return either Launcher, Search, or
  // LauncherRefresh.
  GetMetaKeyToDisplay() => (ui.mojom.MetaKey meta_key);

  // Checks if the `accelerator` from `action_id` is used by another
  // accelerator. If an error is found with the input accelerator, return
  // the error without the accelerator name.
  GetConflictAccelerator(ash.mojom.AcceleratorSource source,
                         uint32 action_id, SimpleAccelerator accelerator)
      => (AcceleratorResultData result);

  // Get the default accelerators for the given accelerator id. The
  // accelerators are filtered and aliased accelerators are included.
  GetDefaultAcceleratorsForId(uint32 action_id)
    => (array<SimpleAccelerator> accelerators);

  // Get the accelerator mappings for all sources. This is formatted as
  // AcceleratorSource -> map<AcceleratorActionId, Array<AcceleratorInfo>>.
  // Note that an accelerator action can have multiple accelerators associated
  // with it.
  GetAccelerators() =>
      (map<ash.mojom.AcceleratorSource,
       map<uint32, array<ash.mojom.AcceleratorInfo>>> config);

  // Registers an observer that will be notified whenever there is an update
  // to either the accelerator mapping or on keyboard device connected event.
  AddObserver(pending_remote<AcceleratorsUpdatedObserver> observer);

  // Registers an observer that will be notified whenever there is a change
  // in the shortcut customization policy settings.
  AddPolicyObserver(pending_remote<PolicyUpdatedObserver> observer);

  // Get a list of all shortcuts with their corresponding category,
  // sub-category, styling, description, source and action. The order of the
  // layoutInfos are tied to its accelerator order representation in the app.
  // The app uses this to generate the layout structure.
  GetAcceleratorLayoutInfos()
      => (array<ash.mojom.AcceleratorLayoutInfo> layout_infos);

  // If `prevent_processing_accelerators` is true, will prevent the system from
  // processing Ash Accelerators. If false, will enable processing Ash
  // accelerators. This returns an empty promise so that clients will be able
  // to continue processing inputs after accelerators have been
  // disabled/enabled.
  // This also serves as the mechanism to inform the service when the user has
  // started/stopped inputting an accelerator.
  PreventProcessingAccelerators(bool prevent_processing_accelerators) => ();

  // Adds an accelerator to `action_id`. If there is a conflict when attempting
  // to add the accelerator, this will return the conflict accelerator's
  // name. The browser process implementor will handle validation of the
  // requested accelerator.
  AddAccelerator(ash.mojom.AcceleratorSource source, uint32 action_id,
                 SimpleAccelerator accelerator)
      => (AcceleratorResultData result);

  // Remove an accelerator from `action`. If permitted, this deletes
  // user-defined accelerators or disables default accelerators.
  // Removing an accelerator cannot result in a conflict.
  RemoveAccelerator(ash.mojom.AcceleratorSource source, uint32 action_id,
                    SimpleAccelerator accelerator)
        => (AcceleratorResultData result);

  // Atomic version of `RemoveAccelerator(old_accelerator)` then
  // `AddAccelerator(new_accelerator)`. This follows behaviors detailed by both
  // respective sub-actions.
  ReplaceAccelerator(ash.mojom.AcceleratorSource source, uint32 action_id,
                     SimpleAccelerator old_accelerator,
                     SimpleAccelerator new_accelerator)
        => (AcceleratorResultData result);

  // Resets the accelerators of `action_id` to the system defaults. This will
  // remove any user added accelerators. If a default accelerator is used by
  // another accelerator, it will be disable for `action_id`.
  RestoreDefault(ash.mojom.AcceleratorSource source,
                 uint32 action_id)
        => (AcceleratorResultData result);

  // Restore all accelerators to their system-provided default state, overriding
  // user customization.
  RestoreAllDefaults() => (AcceleratorResultData result);

  // Records the specific user action histogram.
  RecordUserAction(UserAction user_action);

  // Records the side panel category the user navigates to.
  RecordMainCategoryNavigation(ash.mojom.AcceleratorCategory category);

  // Record the actions done in the accelerator edit dialog before it was
  // closed.
  RecordEditDialogCompletedActions(
      EditDialogCompletedActions completed_actions);

  // Records the subactions done when adding or editing an accelerator.
  RecordAddOrEditSubactions(bool is_add, Subactions subactions);
};