chromium/chromeos/crosapi/mojom/test_controller.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 crosapi.mojom;

import "chromeos/crosapi/mojom/app_service_types.mojom";
import "chromeos/crosapi/mojom/extension_keeplist.mojom";
import "chromeos/crosapi/mojom/tts.mojom";
import "mojo/public/mojom/base/file_path.mojom";
import "mojo/public/mojom/base/values.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/range/mojom/range.mojom";
import "url/mojom/url.mojom";

// The enum of possible states for a shelf item.
// Each value must be a power of 2.
[Stable, Extensible]
enum ShelfItemState {
  // Usually represents an app with no running instance.
  [Default] kNormal = 0,
  // Shelf item has a running instance.
  kRunning = 1,
  // Shelf item owns the window that is currently active.
  kActive = 2,
  // App has at least 1 notification.
  kNotification = 4
};

[Stable, Extensible]
enum TouchEventType {
  kUnknown = 0,
  kPressed = 1,
  kMoved = 2,
  kReleased = 3,
  // Touch events can be cancelled if mouse capture or touch capture changes in
  // the middle of a gesture. For example, a long-press might change window or
  // focus activation state in a way that cancels the gesture, even though the
  // user has not released their finger. See ui::GestureRecognizer.
  kCancelled = 4
};

// Augments a bool to include an 'unknown' value.
[Stable, Extensible]
enum OptionalBoolean {
  [Default] kUnknown = 0,
  kFalse,
  kTrue,
};

[Stable, Extensible]
enum MachineStatisticKeyType {
  [Default] kUnknown = 0,
  kOemDeviceRequisitionKey = 1,
  kHardwareClassKey = 2,
  kCustomizationIdKey = 3,
};

// Dev mode IWAs are either installed from a proxy origin, or from a Web Bundle
// file.
[Stable]
union IsolatedWebAppLocation {
  url.mojom.Url proxy_origin;
  mojo_base.mojom.FilePath bundle_path;
};

[Stable]
union InstallWebAppResult {
  string app_id;
  string error_message;
};

[Stable]
struct AppListItemAttributes {
  string item_position@0;
  string pin_position@1;
};

// For use with StandaloneBrowserTestController's ObserveDomMessages method.
[Stable]
interface DomMessageObserver {
  // Invoked when a message arrived.
  OnMessage@0(string message);
};

// Implemented in lacros-chrome.
// Lets the Ash browser tests that require Lacros to send commands to this
// lacros-chrome instance.
// Next version: 12
// Next method id: 14
[Stable, Uuid="20e7f031-f4e1-4ad9-bd91-ad59eb8b1504"]
interface StandaloneBrowserTestController {
  // Installs a test web app in lacros-chrome given a start URL and mode (open
  // in a tab or window) and returns the ID of the installed app (see
  // |web_app::GenerateAppId|).
  InstallWebApp@0(string start_url, WindowMode mode) => (string app_id);

  // Loads a fake extension in lacros-chrome, assigns it the given name and
  // returns the ID of the loaded extension.
  [MinVersion=1]
  LoadVpnExtension@1(string extension_name) => (string extension_id);

  // Returns all available voices in lacros-chrome.
  [MinVersion=2]
  GetTtsVoices@2() => (array<TtsVoice> voices);

  // Returns Ash extension keeplist data from Lacros.
  [MinVersion=3]
  GetExtensionKeeplist@3() => (ExtensionKeepList keep_list);

  // Requests Tts(text to speech) to speak an utterance from Lacros browser.
  [MinVersion=4]
  TtsSpeak@4(TtsUtterance utterance,
             pending_remote<TtsUtteranceClient> utterance_client);

  // Installs an app with the start URL "parent_app_origin/'sub_app_path'" as a
  // sub app of the given parent app in Lacros.
  [MinVersion=5]
  InstallSubApp@5(string parent_app_id, string sub_app_path)
    => (string sub_app_id);

  // Installs the isolated web app hosted at 'location' in lacros-chrome and
  // returns the ID of the installed app or the error message if the install
  // failed.
  [MinVersion=6]
  InstallIsolatedWebApp@6(IsolatedWebAppLocation location, bool dev_mode)
    => (InstallWebAppResult result);

  // Sets WebAppSettings pref for a primary user profile.
  [MinVersion=7]
  SetWebAppSettingsPref@7(string policy) => (bool success);

  // Installs an unpacked extension located at the given directory in Lacros and
  // returns its id once the extensions registry signals loading is complete
  // (which does NOT guarantee that any background script or views have finished
  // loading). If installation/loading fails, the callback is never run.
  [MinVersion=8]
  InstallUnpackedExtension@8(string path) => (string extension_id);

  // Removes the given component extension from Lacros.
  [MinVersion=8]
  RemoveComponentExtension@9(string extension_id) => ();

  // Informs the given observer of future messages from the
  // DOMAutomationController.
  [MinVersion=8]
  ObserveDomMessages@10(pending_remote<DomMessageObserver> observer) => ();

  // Sets WebAppInstallForceList pref for a primary user profile.
  [MinVersion=9]
  SetWebAppInstallForceListPref@11(string policy) => (bool success);

  // Installs a component extension at the given directory with the given
  // extension id in Lacros.
  [MinVersion=10]
  InstallComponentExtension@12(string path, string extension_id) => ();

  // Injects a fake extension printer handler in lacros.
  [MinVersion=11]
  SetFakeExtensionPrinterHandler@13() => ();
};

// Allows callers running in lacros to trigger test events that are passed to
// the active Vpn configuration.
// See chrome/browser/lacros/vpn_provider_lacros_apitest.cc for details.
// Next version: 1
// Next method id: 2
[Stable, Uuid="e2bca22e-32e9-40b3-a0bc-035b41534496"]
interface TestShillController {
  // Simulate |data| being received by the configuration determined by
  // |extension_id| and |configuration_name|.
  OnPacketReceived@0(string extension_id, string configuration_name,
      array<uint8> data);

  // Simulate |message| being received by the configuration determined by
  // |extension_id| and |configuration_name|.
  OnPlatformMessage@1(string extension_id, string configuration_name,
      uint32 message);
};

// This interface is implemented by Ash-Chrome.
// It enables tests in Lacros-Chrome to access the TestInterfaces
// of ash::Shill*Client classes.
[Stable, Uuid="12d5dbb4-e974-4f41-820e-6d92c2215452"]
interface ShillClientTestInterface {
  // From ash::ShillDeviceClient::TestInterface:

  // Adds a fake networking device.
  AddDevice@0(string device_path, string type,string name) => ();
  // Clear all fake networking devices.
  ClearDevices@1() => ();
  // Sets a property on the given fake device.
  SetDeviceProperty@2(string device_path,
      string name,
      mojo_base.mojom.Value value,
      bool notify_changed) => ();
  // Sets whether the SIM in the given fake device should be locked.
  SetSimLocked@3(string device_path, bool enabled) => ();

  // From ash::ShillServiceClient::TestInterface:

  // Adds a Service to the Manager and Service stubs.
  AddService@4(string service_path,
      string guid,
      string name,
      string type,
      string state,
      bool visible) => ();
  // Clears all Services from the Manager and Service stubs.
  ClearServices@5() => ();
  // Sets a property of the specified service.
  SetServiceProperty@6(string service_path, string property,
      mojo_base.mojom.Value value) => ();

  // From ash::ShillProfileClient::TestInterface:

  // Adds a profile.
  AddProfile@7(string profile_path, string userhash) => ();
  // Adds a service to the profile, copying properties from the
  // ShillServiceClient entry matching |service_path|.
  AddServiceToProfile@8(string profile_path, string service_path) => ();

  // From ash::ShillIPConfigClient::TestInterface:

  // Adds an IPConfig entry.
  AddIPConfig@9(string ip_config_path, mojo_base.mojom.Value properties) => ();
};

[Stable, Extensible]
enum KeyEventType {
  [Default] kKeyPress = 0,
  kKeyRelease = 1
};

// Next version: 2
// Next id: 5
[Stable]
struct KeyEvent {
  KeyEventType type@0;
  int32 dom_key@1;
  int32 dom_code@2;
  int32 key_code@3;
  // This corresponds to ui::EventFlags from:
  // https://source.chromium.org/chromium/chromium/src/+/main:ui/events/event_constants.h;l=16;drc=19f3c214cd4f78e0fe47b2ccafaca406aaacd42f
  [MinVersion=1] int32 flags@4;
};

// Next version: 2
// Next id: 1
[Stable]
struct InputMethod {
  string xkb_layout@0;
};

// This interface is implemented by Ash-Chrome.
// It enables tests in Lacros-Chrome to send commands as an input method.
// By default, this changes Ash to use a US keyboard layout, but this can be
// changed with `InstallAndSwitchToInputMethod` during a test.
// Next version: 9
// Next method id: 10
[Stable, Uuid="c214f4f5-c583-44d1-9547-bb2456d9e70b"]
interface InputMethodTestInterface {
  // Calls the callback when the input method has focused on some input field.
  WaitForFocus@0() => ();

  // Calls `ash::InputMethodAsh::CommitText` with
  // InsertTextCursorBehavior::kMoveCursorAfterText.
  CommitText@1(string text) => ();

  // Calls `ash::InputMethodAsh::UpdateComposition`.
  [MinVersion=1] SetComposition@2(string text, uint32 index) => ();

  // Calls `ash::InputMethodAsh::SendKeyEvent`.
  //
  // The key will be stuck in a pending state until KeyEventHandled is called.
  // While the key is pending, other methods in this test interface can be
  // called to simulate the input method performing input operations as a
  // result of the key events.
  //
  // The key event is resolved once KeyEventHandled is called with the
  // corresponding `key_event_id` that is returned by this call.
  //
  // For example, this will simulate a Korean input method for the key 'g':
  //
  //   SendKeyEventAsync(KeyEvent('g'),
  //     base::BindLambdaForTesting([&](uint64 key_event_id){
  //       SetComposition("ㅎ", 1);
  //       KeyEventHandled(key_event_id, true);
  //     });
  [MinVersion=2] SendKeyEvent@3(KeyEvent event)
      => ([MinVersion=3] uint64 key_event_id);

  // Calls `ash::InputMethodAsh::SendKeyEvent`.
  // Handle the pending key event with ID `key_event_id` with result of
  // `handled`.
  [MinVersion=3] KeyEventHandled@4(uint64 key_event_id, bool handled) => ();

  // Waits for the next surrounding text change since the last
  // WaitForNextSurroundingTextChange call (or since InputMethodTestInterface
  // was instantiated if there are no previous calls to
  // WaitForNextSurroundingTextChange).
  //
  // In other words, starting from when InputMethodTestInterface is created, any
  // surrounding text changes are queued. WaitForNextSurroundingTextChange
  // pops the front of the queue, or waits for a new surrounding text change if
  // the queue is empty.
  //
  // This avoids timing issues so that calling WaitForNextSurroundingTextChange
  // always returns the same set of values for the same set of operations.
  [MinVersion=4] WaitForNextSurroundingTextChange@5() =>
      (string surrounding_text, gfx.mojom.Range selection_range);

  // Returns whether every capability in `capabilities` is supported by Ash.
  // Capabilities are listed as string constants in
  // //chromeos/crosapi/cpp/input_method_test_interface_constants.h
  [MinVersion=5] HasCapabilities@6(array<string> capabilities)
      => (bool has_capabilities);

  // Calls `ash::InputMethodAsh::ConfirmCompositionText`.
  [MinVersion=6] ConfirmComposition@7() => ();

  // Calls `ash::InputMethodAsh::DeleteSurroundingText`.
  [MinVersion=7] DeleteSurroundingText@8(uint32 length_before_selection,
                                         uint32 length_after_selection) => ();

  // Installs a new input method `input_method` in Ash and switches to it.
  [MinVersion=8] InstallAndSwitchToInputMethod@9(InputMethod input_method)
      => ();
};

// Types of accessibility features in Ash that Lacros needs to be able
// to set for testing.
[Stable, Extensible]
enum AssistiveTechnologyType {
  [Default] kUnknown = 0,
  kChromeVox = 1,
  kSelectToSpeak = 2,
  kSwitchAccess = 3,
  [MinVersion=1] kFocusHighlight = 4,
};

[Stable, Extensible]
enum SnapPosition {
  [Default] kPrimary = 0,
  kSecondary = 1,
};

// This interface is implemented by Ash-Chrome.
// This interface provides tests a mechanism to mutate or query ash.
// In the future, this interface may merge with an automation or a11y interface.
// Next version: 37
// Next method id: 54
[Stable, Uuid="1f93f9d7-e466-466c-a675-c21b48cf30d3"]
interface TestController {
  // Clicks the middle of the views element identified by |element_name|.
  [MinVersion=11]
  ClickElement@20(string element_name) => (bool success);

  // Clicks the middle of the window. Assumes that the window exists and is
  // visible on screen. |window_id| should be obtained from
  // PlatformWindow::GetWindowUniqueId(). A typical format might be:
  // "org.chromium.lacros.9A82A161B2A0B9BADF75E9BB958B9FCB"
  ClickWindow@1(string window_id);

  // Checks whether an item with a given ID exists in the shelf.
  [MinVersion=5]
  DoesItemExistInShelf@9(string item_id) => (bool exists);

  // Checks if ash is currently showing any views UI element with the given
  // element_name.
  [MinVersion=11]
  DoesElementExist@19(string element_name) => (bool exists);

  // Queries whether a window with the given |window_id| exists and is either
  // visible or minimized. |window_id| should be obtained from
  // PlatformWindow::GetWindowUniqueId(). A typical format might be:
  // "org.chromium.lacros.9A82A161B2A0B9BADF75E9BB958B9FCB"
  DoesWindowExist@0(string window_id) => (bool exist);

  // Causes ash to enter or exit overview mode. The callback is invoked after
  // overview mode is entered (and the animation is finished).
  [MinVersion=1]
  EnterOverviewMode@2() => ();
  [MinVersion=1]
  ExitOverviewMode@3() => ();

  // Causes ash to enter tablet mode. The callback is invoked after animations
  // are finished. Note that tablet mode cannot be activated if mouse devices
  // are connected; the callback will run, but ash will not be in tablet mode.
  [MinVersion=2]
  EnterTabletMode@4() => ();

  // Causes ash to exit tablet mode. The callback is invoked after animations
  // are finished.
  [MinVersion=2]
  ExitTabletMode@5() => ();

  // Gets the context menu for a shelf item. This assumes the item is already in
  // the shelf.
  [MinVersion=7]
  GetContextMenuForShelfItem@13(string item_id) => (array<string> items);

  // Returns the value of the ash::kMinimizeOnBackKey property for the given
  // window.
  // This allows the client (eg lacros) to verify assumptions eg whether
  // the current active tab should react to a system wide back gesture.
  //
  // Note: For simplicity, the return callback is called with `true` in case
  // the property is not set, of the window is not found.
  [MinVersion=4]
  GetMinimizeOnBackKeyWindowProperty@10(string window_id)
      => (OptionalBoolean value);

  // Returns the position of a window's top-left corner in global "screen"
  // coordinates in DIPs. By design, Wayland clients do not know the global
  // position of their windows on the display. However, for window manager
  // integration testing, some tests may need to assert a window is in a certain
  // position (e.g. at the top of the display). Returns null if the window does
  // not exist.
  [MinVersion=3]
  GetWindowPositionInScreen@8(string window_id) => (gfx.mojom.Point? position);

  // Pins or unpins an item to the shelf. This assumes the item is already in
  // the shelf. Returns |false| on any error.
  [MinVersion=6]
  PinOrUnpinItemInShelf@11(string item_id, bool pin) => (bool success);

  // Select the context menu item for the shelf item with |item_id| at |index|.
  // Returns false on any error.
  [MinVersion=11]
  SelectContextMenuForShelfItem@18(string item_id, uint32 index)
      => (bool success);

  // Simulates a user left-clicking an item in the shelf. This assumes the item
  // is already in the shelf. Returns |false| on any error.
  [MinVersion=6]
  SelectItemInShelf@12(string item_id) => (bool success);

  // Creates a touch event and dispatches it to the window with |window_id|.
  // Returns immediately if the window does not exist. The |pointer_id|
  // specifies which touch-point is involved in a multi-touch gesture.
  // |pointer_id| is typically 0, meaning the first touch-point, usually the
  // index finger. |location_in_window| is in DIPs, in coordinates relative to
  // the window origin with 0,0 representing top-left. Note that the location
  // is a float, as some input devices report sub-pixel positions for touch
  // events.
  [MinVersion=3]
  SendTouchEvent@7(string window_id, TouchEventType type, uint8 pointer_id,
                   gfx.mojom.PointF location_in_window) => ();

  // Get the number of open Ash browser windows.
  [MinVersion=8]
  GetOpenAshBrowserWindows@14() => (uint32 number);

  // Close all browser windows.
  // Note: Usually there should be no Ash window open unless the test opened
  // one.
  [MinVersion=8]
  CloseAllBrowserWindows@15() => (bool success);

  // Register a lacros-chrome test controller with ash-chrome to let ash-chrome
  // send commands to lacros-chrome.
  [MinVersion=9] RegisterStandaloneBrowserTestController@16(
      pending_remote<StandaloneBrowserTestController> controller);

  // Provides a mechanism for lacros to tell ash to perform tab scrubbing.
  [MinVersion=10]
  TriggerTabScrubbing@17(float x_offset) => (bool scrubbing);

  // Simulates a user always selecting the specified app from future
  // Sharesheets.
  [MinVersion=12]
  SetSelectedSharesheetApp@21(string app_id) => ();

  // Returns the version of ash-chrome, e.g. "103.0.5029.0". The returned string
  // is intended to be compatible with the base::Version(std::string_view)
  // constructor.
  // Consider using the convenience wrapper
  // lacros_test_helper.h:IsAshVersionAtLeastForTesting instead.
  // Introduced in M-103.
  [MinVersion=13]
  GetAshVersion@22() => (string ash_version);

  // Binds |test_shill_controller| that can be used to simulate packet/message
  // events.
  [MinVersion=14]
  BindTestShillController@23(
      pending_receiver<TestShillController> test_shill_controller) => ();

  // Creates and then cancels a print job.
  [MinVersion=15]
  CreateAndCancelPrintJob@24(string job_title) => ();

  // Binds a |shill_client| that Lacros-Chrome can use to access the Shill
  // test intefaces in Ash-Chrome.
  [MinVersion=16]
  BindShillClientTestInterface@25(
      pending_receiver<ShillClientTestInterface> shill_client) => ();

  // Returns the sanitized (aka "hashed") username of the active user.
  [MinVersion=16]
  GetSanitizedActiveUsername@26() => (string sanitized_active_username);

  // Binds a |test_input_method| that Lacros-Chrome can use to receive commands
  // from a test input method in Ash-Chrome.
  [MinVersion=17]
  BindInputMethodTestInterface@27(
      pending_receiver<InputMethodTestInterface> test_input_method) => ();

  // Connects to network according to |service_path| (e.g.,"/service/eth1" and
  // "/service/wifi1") through shill service client.
  [MinVersion=18]
  ConnectToNetwork@28(string service_path);

  // Disconnects to network according to |service_path| (e.g.,"/service/eth1"
  // and "/service/wifi1") through shill service client.
  [MinVersion=18]
  DisconnectFromNetwork@29(string service_path);

  // Launches an app from the Launcher grid.
  [MinVersion=19]
  LaunchAppFromAppList@30(string app_id);

  // Clear App Service state, including from any previously installed apps.
  [MinVersion=20]
  ReinitializeAppService@31() => ();

  // Reads state of Shelf item. Returns a bitmask of `ShelfItemState` values.
  [MinVersion=21]
  GetShelfItemState@32(string app_id) => (uint32 state);

  // Returns the size of the Tts utterance queue of the TtsController running in
  // Ash.
  [MinVersion=22]
  GetTtsUtteranceQueueSize@33() => (int32 size);

  // Returns true is desk is being created or removed or desk animation is in
  // progress. The result is only accurate on `false` result. Even if it returns
  // `true`, given the async nature of CrosAPI the desk oepration might have
  // been finished already.
  [MinVersion=23]
  AreDesksBeingModified@34()=>(bool are_desks_being_modified);

  // Returns all available voices in ash-chrome.
  [MinVersion=24]
  GetTtsVoices@35() => (array<TtsVoice> voices);

  // Requests Tts(text to speech) to speak an utterance from Ash.
  [MinVersion=24]
  TtsSpeak@36(TtsUtterance utterance,
              pending_remote<TtsUtteranceClient> utterance_client);

  // Checks whether local cache for saved desks is still loading.
  [MinVersion=25]
  IsSavedDeskStorageReady@37() => (bool is_saved_desk_storage_ready);

  // Sets enabled state for the given Accessibility feature.
  [MinVersion=26]
  SetAssistiveTechnologyEnabled@38(AssistiveTechnologyType at_type,
      bool enabled);

  // Gets an app's shelf attributes.
  [MinVersion=27]
  GetAppListItemAttributes@39(string item_id)
      => (AppListItemAttributes attributes);

  // Sets an app's shelf attributes.
  [MinVersion=27]
  SetAppListItemAttributes@40(string item_id,
                              AppListItemAttributes attributes) => ();

  // Closes all Ash browser windows and confirms the result in callback
  // asynchronously.
  // The callback will be run as soon as it observes all ash browser windows are
  // closed, or fails to do so when it times out.
  // Returns true if all windows are closed; false if it fails to close
  // all windows.
  [MinVersion=28]
  CloseAllAshBrowserWindowsAndConfirm@41() => (bool success);

  // Checks if there is at least one ash browser window open asynchronously.
  // The result is passed back in callback.
  // The callback will be run as soon as at least 1 ash browser window is
  // observed, or no ash browser window is open when it times out.
  [MinVersion=28]
  CheckAtLeastOneAshBrowserWindowOpen@42() => (bool has_open_window);

  // Gets the last committed URL for each browser tab currently open in Ash.
  [MinVersion=29]
  GetAllOpenTabURLs@43() => (array<url.mojom.Url> urls);

  // Overrides the Almanac endpoint URL for testing, override is removed if
  // nullopt is given.
  [MinVersion=30]
  SetAlmanacEndpointUrlForTesting@44(string? override) => ();

  // Checks if a toast with a given `toast_id` is shown.
  [MinVersion=31]
  IsToastShown@45(string toast_id) => (bool toast_shown);

  // Snaps the given window to the given position.
  [MinVersion=32]
  SnapWindow@46(string window_id, SnapPosition position) => ();

  // Checks whether the shelf is currently visible.
  [MinVersion=32]
  IsShelfVisible@47() => (bool visible);

  // Sets whether the app install dialog is enabled and should auto accept
  // installation without actual user input.
  [MinVersion=33]
  SetAppInstallDialogAutoAccept@48(bool auto_accept) => ();

  // Sets the number of displays through the `DisplayManagerTestApi`.
  // The values can be in the range [1, 8].
  [MinVersion=34] UpdateDisplay@49(int32 number_of_displays) => ();

  // Enables or disables FakeStatisticsProvider for testing.
  [MinVersion=35] EnableStatisticsProviderForTesting@50(bool enable) => ();

  // Clears all machine statistics data from FakeStatisficsProvider for testing.
  [MinVersion=35] ClearAllMachineStatistics@51() => ();

  // Sets the machine statistics data with FakeStatisficsProvider for testing.
  // Returns true if succeeded.
  [MinVersion=35] SetMachineStatistic@52(MachineStatisticKeyType key,
      string value) => (bool success);

  // Set fling gesture recognition threshold for testing.
  [MinVersion=36] SetMinFlingVelocity@53(float velocity) => ();
};