// Copyright 2017 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.device_sync.mojom;
import "chromeos/ash/components/multidevice/mojom/multidevice_types.mojom";
import "mojo/public/mojom/base/time.mojom";
// Denotes the outcome of an HTTP request, where results like kBadRequest map
// onto HTTP error codes while others like kRequestServiceNotYetInitialized
// reflect issues adjacent to the actual HTTP request.
enum NetworkRequestResult {
// Successful network request.
kSuccess,
// The network request itself was successful, but it did not produce the
// expected result (e.g., called SetSoftwareFeatureState(), but the call did
// not result in the feature state changing).
kRequestSucceededButUnexpectedResult,
// Service was not yet initialized; could not complete request.
kServiceNotYetInitialized,
// Request could not be completed because the device is offline or has issues
// sending the HTTP request.
kOffline,
// Server endpoint could not be found.
kEndpointNotFound,
// Authentication error contacting back-end.
kAuthenticationError,
// Request was invalid.
kBadRequest,
// The server responded, but the response was not formatted correctly.
kResponseMalformed,
// Internal server error.
kInternalServerError,
// Unknown result.
kUnknown
};
// Describes the desired state of a device's software feature.
enum FeatureStatusChange {
// Enables a feature on a device and disables the feature on all other
// devices associated with the account.
kEnableExclusively,
// Enables a feature on a device; other devices on the account are
// unaffected.
kEnableNonExclusively,
// Disables a feature on a device; other devices on the account are
// unaffected.
kDisable
};
// Denotes the relevant CryptAuth service.
enum CryptAuthService {
kEnrollment,
kDeviceSync
};
// Describes a device's network reachability.
enum ConnectivityStatus {
kOnline,
kOffline,
kUnknownConnectivity
};
// Describes the status of the encrypted group private key received in the
// SyncMetadataResponse.
enum GroupPrivateKeyStatus {
// When Device Sync is not initialized, it cannot access the group private key
// status and will return this value.
kStatusUnavailableBecauseDeviceSyncIsNotInitialized,
// When the CryptAuthV2 device manager hasn't initialized a device syncer, it
// cannot access the group private key status and will return this value.
kStatusUnavailableBecauseNoDeviceSyncerSet,
// The CryptAuth SyncMetadata response that includes the encrypted group
// private key hasn't been received yet.
kWaitingForGroupPrivateKey,
// The SyncMetadata response was been received, but doesn't include any
// encrypted group private key. This is expected when no other user device
// uploaded the key or if we already own the key.
kNoEncryptedGroupPrivateKeyReceived,
// The SyncMetadata response was received, but the included encrypted group
// private key is empty.
kEncryptedGroupPrivateKeyEmpty,
// This device's CryptAuthKeyBundle::Name::kDeviceSyncBetterTogether key is
// missing, so the encrypted group private key cannot be decrypted.
kLocalDeviceSyncBetterTogetherKeyMissing,
// An error occurred when decrypting the group private key.
kGroupPrivateKeyDecryptionFailed,
// The group private key was successfully decrypted. This is the expected
// final state of this flow.
kGroupPrivateKeySuccessfullyDecrypted
};
// Describes the status of the better together remote device metadata.
enum BetterTogetherMetadataStatus {
// When Device Sync is not initialized, it cannot access the better together
// metadata status and will return this value.
kStatusUnavailableBecauseDeviceSyncIsNotInitialized,
// When the CryptAuthV2 device manager hasn't initialized a device syncer, it
// cannot access the better together metadata status and will return this
// value.
kStatusUnavailableBecauseNoDeviceSyncerSet,
// The attempt to process the encrypted device metadata hasn't started yet.
// If the device sync attempt finishes and this is still the metadata
// status, clients can inspect GroupPrivateKeyStatus to understand why.
kWaitingToProcessDeviceMetadata,
// The group private key required to decrypt the metadata is missing.
// Clients can inspect GroupPrivateKeyStatus to understand why the group
// private key is missing.
kGroupPrivateKeyMissing,
// CryptAuth didn't send any encrypted metadata.
kEncryptedMetadataEmpty,
// Device metadata was decrypted. This is the expected final state of this
// flow.
kMetadataDecrypted
};
struct FindEligibleDevicesResponse {
array<ash.multidevice.mojom.RemoteDevice> eligible_devices;
array<ash.multidevice.mojom.RemoteDevice> ineligible_devices;
};
struct DeviceActivityStatus {
string device_id;
mojo_base.mojom.Time last_activity_time;
ConnectivityStatus connectivity_status;
mojo_base.mojom.Time last_update_time;
};
struct DebugInfo {
// Enrollment stats:
mojo_base.mojom.Time last_enrollment_time;
mojo_base.mojom.TimeDelta time_to_next_enrollment_attempt;
bool is_recovering_from_enrollment_failure;
bool is_enrollment_in_progress;
// Sync stats:
mojo_base.mojom.Time last_sync_time;
mojo_base.mojom.TimeDelta time_to_next_sync_attempt;
bool is_recovering_from_sync_failure;
bool is_sync_in_progress;
};
interface DeviceSyncObserver {
// Invoked when the current device has successfully completed enrollment. Note
// that enrollment occurs once when the device first starts up, then the
// device re-enrolls periodically (and on-command when ForceEnrollmentNow() is
// called).
OnEnrollmentFinished();
// Invoked when new devices have been synced from the server. Note that this
// function is not invoked if a device sync failed or if a device sync
// succeeded but did not result in a change of devices.
OnNewDevicesSynced();
};
// TODO(khorimoto): Flesh out API.
// Calls to this API run in the browser process.
interface DeviceSync {
// Adds an Observer of this API.
AddObserver(pending_remote<DeviceSyncObserver> observer) => ();
// Triggers an enrollment; result is relayed via the OnEnrollmentFinished()
// observer function. Returns whether the call could be completed
// successfully. If the function returns false, this means that the device has
// not yet completed registration with the back-end; clients should observe
// this service and wait for an OnEnrollmentFinished() callback before
// retrying.
[Sync]
ForceEnrollmentNow() => (bool success);
// Triggers a device sync; result is relayed via the OnDevicesSynced()
// observer function. Returns whether the call could be completed
// successfully. If the function returns false, this means that the device has
// not yet completed registration with the back-end; clients should observe
// this service and wait for an OnEnrollmentFinished() callback before
// retrying.
[Sync]
ForceSyncNow() => (bool success);
// Returns the status of the encrypted group private key received in the
// SyncMetadataResponse.
GetGroupPrivateKeyStatus() => (GroupPrivateKeyStatus status);
// Returns the status of the better together remote device metadata.
GetBetterTogetherMetadataStatus() => (BetterTogetherMetadataStatus status);
// Returns all synced devices associated with the primary account. If this
// device has not yet registered with the back-end, no list is provided.
GetSyncedDevices() =>
(array<ash.multidevice.mojom.RemoteDevice>? devices);
// Returns the RemoteDevice object associated with this device. If this device
// has not yet registered with the back-end, no device is provided.
GetLocalDeviceMetadata() =>
(ash.multidevice.mojom.RemoteDevice? local_device);
// Enables or disables the given software feature for the device with the
// given public key. If |enabled| and |is_exclusive| are both true, this
// function will enable the feature for the given device and disable the
// feature for any other device which currently has that feature enabled.
// |is_exclusive| is ignored if |enabled| is false.
//
// On success, this function returns a null error_code to the callback; on
// error, it returns a valid error_code string indicating the reason for
// failure.
//
// Note: In the special case of passing |software_feature| =
// SoftwareFeature::EASY_UNLOCK_HOST and |enabled| = false, |public_key| is
// ignored, because that combination of arguments disables EASY_UNLOCK_HOST on
// all of the user's devices.
//
// TODO(crbug.com/40105247): Remove this function when v1 DeviceSync
// is disabled.
SetSoftwareFeatureState(
string device_public_key,
ash.multidevice.mojom.SoftwareFeature software_feature,
bool enabled,
bool is_exclusive) => (NetworkRequestResult result_code);
// Enables or disables |feature| for the device with Instance ID
// |device_instance_id|.
//
// This function can only affect devices using CryptAuth v2 DeviceSync since
// it requires an Instance ID. See SetSoftwareFeatureState() for the v1
// DeviceSync analog.
SetFeatureStatus(
string device_instance_id,
ash.multidevice.mojom.SoftwareFeature feature,
FeatureStatusChange status_change) => (NetworkRequestResult result_code);
// Finds devices which are eligible for the given feature. When this function
// is invoked, a network request will be sent to each eligible device which
// instructs that device to enable BLE advertising; thus, this function can be
// used to bootstrap connections to these devices.
//
// On success, this function returns a null error_code with a valid response
// to the callback; on error, it returns a valid error_code string indicating
// the reason for failure along with a null response.
//
// TODO(crbug.com/40105247): Remove this function when v1 DeviceSync
// is disabled.
FindEligibleDevices(
ash.multidevice.mojom.SoftwareFeature software_feature) =>
(NetworkRequestResult result_code,
FindEligibleDevicesResponse? response);
// Sends a GCM message--via CryptAuth--to devices with Instance IDs
// |device_instance_ids|. The message includes the CryptAuth
// service--Enrollment or DeviceSync--and the feature
// type--kBetterTogetherHost, for example--indicating the reason for the
// notification; these are specified by |cryptauth_service| and |feature|,
// respectively.
NotifyDevices(
array<string> device_instance_ids,
CryptAuthService cryptauth_service,
ash.multidevice.mojom.SoftwareFeature feature) =>
(NetworkRequestResult result_code);
// Retrieves the activity status of the user's devices. When this function
// is invoked, a network request will be sent to the CryptAuth server to
// retrieve the last time a device was used.
//
// On success, this function returns a null error_code with the activity
// statuses to the callback; on error, it returns a valid error_code string
// indicating the reason for failure along with a null activity statuses.
//
// This method is expected to be used by multidevice_setup service running
// in the browser process.
GetDevicesActivityStatus() =>
(NetworkRequestResult result_code,
array<DeviceActivityStatus>? device_activity_statuses);
// Functions below are implemented for chrome://proximity-auth page, which is
// intended for debugging purposes only.
// TODO(khorimoto): Determine whether a new, debug-only interface should be
// refactored out of DeviceSync.
GetDebugInfo() => (DebugInfo? debug_info);
};