chromium/chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom

// Copyright 2018 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.multidevice_setup.mojom;

import "chromeos/ash/components/multidevice/mojom/multidevice_types.mojom";
import "chromeos/ash/services/device_sync/public/mojom/device_sync.mojom";

// Enumeration of possible opt-in entry points for Phone Hub Camera Roll
// feature. This enum is tied directly to a UMA enum defined in
// tools/metrics/histograms/enums.xml. These values are persisted to logs.
// Entries should not be renumbered and numeric values should never be reused.
enum CameraRollOptInEntryPoint {
  kSetupFlow = 0,
  kOnboardingDialog = 1,
  kSettings = 2,
};

// Enumeration of event types which can be dispatched. Only used for debugging
// purposes.
enum EventTypeForDebugging {
  kNewUserPotentialHostExists,
  kExistingUserConnectedHostSwitched,
  kExistingUserNewChromebookAdded,
};

// This enum is tied directly to a UMA enum defined in
// //tools/metrics/histograms/enums.xml, and should always reflect it (do not
// change one without changing the other).
enum HostStatus {
  // The user's account has no devices which can serve as a host for
  // multi-device features.
  kNoEligibleHosts = 0,

  // The user's account has one or more devices which can be used as a host for
  // multi-device features, but the user has not yet completed the setup flow
  // for any one of these devices.
  kEligibleHostExistsButNoHostSet = 1,

  // The user has completed the setup flow for multi-device features on this
  // device, but there was an error contacting the back-end (e.g., the device
  // was offline during the setup flow, or the back-end rejected the request for
  // some reason). The local device will continue trying to contact the back-end
  // to confirm that the host is set.
  kHostSetLocallyButWaitingForBackendConfirmation = 2,

  // The host has been set (both locally and on the back-end), but verification
  // has not yet completed. The local device will continue trying to establish
  // a Bluetooth connection to the host until verification succeeds.
  kHostSetButNotYetVerified = 3,

  // The host has been set (both locally and on the back-end), and the
  // verification step over Bluetooth has completed. Features should be
  // available for use.
  kHostVerified = 4
};

// Individual multi-device features types. Enums should remain in sync with
// those in c/b/r/s/chromeos/multidevice_page/multidevice_constants.js,
// and all features should be reflected in the FeatureStateMaps generated in
// chromeos/ash/services/multidevice_setup/public/cpp/multidevice_setup_client.cc
// and chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
enum Feature {
  kBetterTogetherSuite = 0,
  kInstantTethering = 1,
  kMessages = 2,
  kSmartLock = 3,
  kPhoneHub = 4,
  kPhoneHubNotifications = 5,
  kPhoneHubTaskContinuation = 6,
  kWifiSync = 7,
  kEche = 8,
  kPhoneHubCameraRoll = 9,
};

// This enum is tied directly to a UMA enum defined in
// //tools/metrics/histograms/enums.xml, and should always reflect it (do not
// change one without changing the other). Enums should remain in sync with
// those in c/b/r/s/chromeos/multidevice_page/multidevice_constants.js
enum FeatureState {
  // Feature was prohibited by a device policy (e.g., EDU or Enterprise).
  kProhibitedByPolicy = 0,

  // Feature was disabled by the user (i.e., via settings).
  kDisabledByUser = 1,

  // Feature was enabled by the user (i.e., via settings).
  kEnabledByUser = 2,

  // Feature is not supported by this Chromebook.
  kNotSupportedByChromebook = 3,

  // Feature is not supported by the current host phone device.
  kNotSupportedByPhone = 4,

  // This value has been deprecated in favor of more granular
  // kUnavailableNoVerifiedHost_* values.
  // The feature is unavailable because there is no verified multi-device host.
  // kUnavailableNoVerifiedHost = 5,

  // The feature is unavailable because there are insufficient security
  // mechanisms in place (e.g., Smart Lock returns this value when the host
  // phone device does not have a lock screen set).
  kUnavailableInsufficientSecurity = 6,

  // The feature has been enabled by the user, but it is still unavailable
  // because the entire Better Together suite has been disabled by the user.
  kUnavailableSuiteDisabled = 7,

  // kFurtherSetupRequired (8) is deprecated.

  // The feature has been enabled by the user, but it is still unavailable
  // because it is a sub-feature of a top-level feature, and that top-level
  // feature has been disabled (e.g., Phone Hub notifications are a sub-feature
  // of Phone Hub).
  kUnavailableTopLevelFeatureDisabled = 9,

  // The feature is unavailable because there is no verified multi-device host.
  // The device sync client is not ready yet to better understand the flow in
  // the feature states with metrics.
  kUnavailableNoVerifiedHost_ClientNotReady = 10,

  // The feature is unavailable because no eligible multi-device host exists.
  // This should be the starting default value in most cases until proven
  // otherwise.
  kUnavailableNoVerifiedHost_NoEligibleHosts = 11,

  // The feature is unavailable because an eligible multi-device host exists but
  // is not set or is unverified. To set a host, use SetHostDevice(); to verify
  // a host, use RetrySetHostNow().
  kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified = 12,
};

// Metadata describing a device that can used as the host for multidevice
// features.
struct HostDevice {
  ash.multidevice.mojom.RemoteDevice remote_device;
  ash.device_sync.mojom.ConnectivityStatus connectivity_status;
};

// Delegate used to notify Chrome OS UI (//ash) of multidevice account changes
// from the multidevice setup service
// (//chromeos/ash/services/multidevice_setup). Both sides currently live in the
// Chrome process.
interface AccountStatusChangeDelegate {
  // Callback which indicates that one or more MultiDevice host phones are
  // available for setup with the MultiDevice setup flow. This function is only
  // called if the current user has not yet set up MultiDevice features.
  OnPotentialHostExistsForNewUser();

  // Callback which indicates that the account left the state of having a
  // potential host ready for setup. Note that it is called both when a host is
  // set and when there are simply no host devices (i.e. neither potential nor
  // set) on the account anymore. This function is only called if the current
  // user has not yet set up MultiDevice features and received backend
  // confirmation.
  OnNoLongerNewUser();

  // Callback which indicates that the currently-connected MultiDevice host has
  // changed. This likely means that the user has changed MultiDevice settings
  // on another device. This function is only called if the current user has
  // already set up MultiDevice features.
  OnConnectedHostSwitchedForExistingUser(string new_host_device_name);

  // Callback which indicates that a new Chromebook was added to the account of
  // the current user. This function is only called if the current user has
  // already set up MultiDevice features.
  OnNewChromebookAddedForExistingUser(string new_host_device_name);

  // Indicates that the existing host has become eligible for Wi-Fi Sync, but
  // the feature is not yet enabled.  This is called when the announcement
  // notification should be shown.
  OnBecameEligibleForWifiSync();
};

interface HostStatusObserver {
  // Called whenever the host status changes. If the host status is
  // HostStatus::kNoEligibleHosts or
  // HostStatus::kEligibleHostExistsButNoHostSet, |host_device| is null.
  OnHostStatusChanged(HostStatus host_status,
                      ash.multidevice.mojom.RemoteDevice? host_device);
};

interface FeatureStateObserver {
  // Invoked when one or more features have changed state.
  OnFeatureStatesChanged(map<Feature, FeatureState> feature_states_map);
};

// Provides an API to the MultiDevice Setup flow. Designed to be exposed
// primarily to the MultiDevice setup flow at chrome://multidevice-setup and
// chrome://oobe (normal usage) as well as the ProximityAuth debug WebUI page at
// chrome://proximity-auth (debugging only).
interface MultiDeviceSetup {
  // Registers the "account status change" delegate to be used by the service.
  // Only one delegate can be set; this function should not be called more than
  // once.
  SetAccountStatusChangeDelegate(
      pending_remote<AccountStatusChangeDelegate> delegate);

  // Adds an observer of host status changes. To stop observing, disconnect the
  // pending_remote<HostStatusObserver> passed here.
  AddHostStatusObserver(pending_remote<HostStatusObserver> observer);

  // Adds an observer of feature state changes. To stop observing, disconnect
  // the pending_remote<FeatureStateObserver> passed here.
  AddFeatureStateObserver(pending_remote<FeatureStateObserver> observer);

  // Provides a list of all eligible host devices (i.e., those which can be
  // passed to SetHostDevice()).
  GetEligibleHostDevices() =>
      (array<ash.multidevice.mojom.RemoteDevice> eligible_host_devices);

  // Provides a list of all active eligible host devices (i.e., those which
  // can be passed to SetHostDevice()) sorted by last usage as determined by
  // the server.
  GetEligibleActiveHostDevices() =>
      (array<HostDevice> eligible_host_devices);

  // Sets the host associated with the provided ID--Instance ID or legacy
  // device ID, depending on whether the device is using v2 or v1 DeviceSync,
  // respectively--as the host device for this account. The provided auth token
  // must be valid in order to prove that the user is authenticated. If called
  // when there is no current host or when the current host is a different
  // device from the one passed, this function initiates a connection to the
  // back-end and attempts to set the host. When called with the same device
  // that is already the host, this function is a no-op. Returns a success
  // boolean; this function will fail if the provided ID does not correspond to
  // an eligible host device on the account, or the provided auth token is
  // invalid.
  // TODO(crbug.com/40105247): When v1 DeviceSync is turned off, only
  // use Instance ID since all devices are guaranteed to have one.
  SetHostDevice(string instance_id_or_legacy_device_id, string auth_token) =>
      (bool success);

  // Removes the currently-set host as the multi-device host for this account.
  // If there was no host set to begin with, this function is a no-op.
  RemoveHostDevice();

  // Returns the host status and host device. If the host status is
  // HostStatus::kNoEligibleHosts or
  // HostStatus::kEligibleHostExistsButNoHostSet, |host_device| is null.
  GetHostStatus() => (HostStatus host_status,
                      ash.multidevice.mojom.RemoteDevice? host_device);

  // Attempts to enable or disable |feature|. This function succeeds only if
  // |feature|'s current state is FeatureState::kEnabledByUser or
  // FeatureState::kDisabledByUser.
  //
  // A valid |auth_token| only needs to be provided if Smart Lock is being
  // enabled. To be exact, this means a valid |auth_token| must be passed if
  // |feature| == EASY_UNLOCK_CLIENT and |enabled| == true, or
  // |feature| == BETTER_TOGETHER_CLIENT, |enabled| == true, and the pref for
  // Smart Lock is already enabled.
  SetFeatureEnabledState(Feature feature, bool enabled, string? auth_token) =>
      (bool success);

  // Provides the states of all Features.
  GetFeatureStates() => (map<Feature, FeatureState> feature_states_map);

  // Retries the most recent SetHostDevice() call.
  //
  // If the current status is
  // HostStatus::kHostSetLocallyButWaitingForBackendConfirmation, this function
  // retries the network attempt to set the device on the back-end. If the
  // current status is HostStatus::kHostSetButNotYetVerified, this function
  // retries the verification step. Both of these cases return true to the
  // caller.
  //
  // If the current status is any other value, this function is not applicable,
  // and false is returned to the caller.
  RetrySetHostNow() => (bool success);

  // Triggers an event to be dispatched by the service. This API function is
  // intended to be used only for debugging in the chrome://proximity-auth page.
  // During normal usage, events are triggered internally within the service.
  TriggerEventForDebugging(EventTypeForDebugging type) => (bool success);

  // Sets the instance ID of the phone that this Chromebook connected to during
  // OOBE Quick Start. MultideviceSetup OOBE can inspect this instance ID later
  // on to determine whether to show UI enhancements (see
  // GetQuickStartPhoneInstanceID below).
  SetQuickStartPhoneInstanceID(string qs_phone_instance_id);

  // Informs whether the user already connected their phone using OOBE Quick
  // Start. If so, it returns the string of the phone instance ID. If not, it
  // returns std::nullopt. MultideviceSetup in OOBE uses this value to prefer
  // the device and update UI strings if the matching phone is present.
  GetQuickStartPhoneInstanceID() =>
      (string? qs_phone_instance_id);
};

// Provides an API for setting a MultiDevice host without the need to provide an
// auth token. This interface should only be used in circumstances when the user
// has just entered their password.
interface PrivilegedHostDeviceSetter {
  // Same functionality as MultiDeviceSetup's SetHostDevice() function above,
  // except that no auth token is required.
  // TODO(crbug.com/40105247): When v1 DeviceSync is turned off, only
  // use Instance ID since all devices are guaranteed to have one.
  SetHostDevice(string instance_id_or_legacy_device_id) => (bool success);
};